diff --git a/headers/libs/freetype2/freetype/cache/ftccache.h b/headers/libs/freetype2/freetype/cache/ftccache.h index f5e91b40dd..7c7688dba2 100644 --- a/headers/libs/freetype2/freetype/cache/ftccache.h +++ b/headers/libs/freetype2/freetype/cache/ftccache.h @@ -4,7 +4,7 @@ /* */ /* FreeType internal cache interface (specification). */ /* */ -/* Copyright 2000-2001, 2002 by */ +/* Copyright 2000-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,9 +20,7 @@ #define __FTCCACHE_H__ -/* define to allow cache lookup inlining */ -#define FTC_CACHE_USE_INLINE - +#include FT_CACHE_INTERNAL_MRU_H FT_BEGIN_HEADER @@ -30,13 +28,7 @@ FT_BEGIN_HEADER typedef struct FTC_CacheRec_* FTC_Cache; /* handle to cache class */ - typedef const struct FTC_Cache_ClassRec_* FTC_Cache_Class; - - /* handle to cache node family */ - typedef struct FTC_FamilyRec_* FTC_Family; - - /* handle to cache root query */ - typedef struct FTC_QueryRec_* FTC_Query; + typedef const struct FTC_CacheClassRec_* FTC_CacheClass; /*************************************************************************/ @@ -62,12 +54,11 @@ FT_BEGIN_HEADER /* structure size should be 20 bytes on 32-bits machines */ typedef struct FTC_NodeRec_ { - FTC_Node mru_next; /* circular mru list pointer */ - FTC_Node mru_prev; /* circular mru list pointer */ - FTC_Node link; /* used for hashing */ - FT_UInt32 hash; /* used for hashing too */ - FT_UShort fam_index; /* index of family the node belongs to */ - FT_Short ref_count; /* reference count for this node */ + FTC_MruNodeRec mru; /* circular mru list pointer */ + FTC_Node link; /* used for hashing */ + FT_UInt32 hash; /* used for hashing too */ + FT_UShort cache_index; /* index of cache the node belongs to */ + FT_Short ref_count; /* reference count for this node */ } FTC_NodeRec; @@ -75,6 +66,9 @@ FT_BEGIN_HEADER #define FTC_NODE( x ) ( (FTC_Node)(x) ) #define FTC_NODE_P( x ) ( (FTC_Node*)(x) ) +#define FTC_NODE__NEXT(x) FTC_NODE( (x)->mru.next ) +#define FTC_NODE__PREV(x) FTC_NODE( (x)->mru.prev ) + /*************************************************************************/ /* */ @@ -83,83 +77,12 @@ FT_BEGIN_HEADER /* cache sub-system internals. */ /* */ - /* can be used as a FTC_Node_DoneFunc */ - FT_EXPORT( void ) - ftc_node_done( FTC_Node node, - FTC_Cache cache ); - /* reserved for manager's use */ FT_EXPORT( void ) ftc_node_destroy( FTC_Node node, FTC_Manager manager ); - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** CACHE QUERY DEFINITIONS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* A structure modelling a cache node query. The following fields must */ - /* all be set by the @FTC_Family_CompareFunc method of a cache's family */ - /* list. */ - /* */ - typedef struct FTC_QueryRec_ - { - FTC_Family family; - FT_UFast hash; - - } FTC_QueryRec; - - -#define FTC_QUERY( x ) ( (FTC_Query)(x) ) -#define FTC_QUERY_P( x ) ( (FTC_Query*)(x) ) - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** CACHE FAMILY DEFINITIONS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - typedef struct FTC_FamilyRec_ - { - FT_LruNodeRec lru; - FTC_Cache cache; - FT_UInt num_nodes; - FT_UInt fam_index; - - } FTC_FamilyRec; - - -#define FTC_FAMILY( x ) ( (FTC_Family)(x) ) -#define FTC_FAMILY_P( x ) ( (FTC_Family*)(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 any FTC_Node_InitFunc routine */ - FT_EXPORT( FT_Error ) - ftc_family_init( FTC_Family family, - FTC_Query query, - FTC_Cache cache ); - - - /* can be used as a FTC_Family_DoneFunc; otherwise, must be called */ - /* by any family finalizer function */ - FT_EXPORT( void ) - ftc_family_done( FTC_Family family ); - - /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -168,64 +91,12 @@ FT_BEGIN_HEADER /*************************************************************************/ /*************************************************************************/ - /* each cache really implements a dynamic hash table to manage its nodes */ - typedef struct FTC_CacheRec_ - { - FTC_Manager manager; - FT_Memory memory; - FTC_Cache_Class clazz; - - FT_UInt cache_index; /* in manager's table */ - FT_Pointer cache_data; /* used by cache node methods */ - - FT_UFast p; - FT_UFast mask; - FT_Long slack; - FTC_Node* buckets; - - FT_LruList_ClassRec family_class; - FT_LruList families; - - } FTC_CacheRec; - - -#define FTC_CACHE( x ) ( (FTC_Cache)(x) ) -#define FTC_CACHE_P( x ) ( (FTC_Cache*)(x) ) - - - /* initialize a given cache */ - typedef FT_Error - (*FTC_Cache_InitFunc)( FTC_Cache cache ); - - /* clear a cache */ - typedef void - (*FTC_Cache_ClearFunc)( FTC_Cache cache ); - - /* finalize a given cache */ - typedef void - (*FTC_Cache_DoneFunc)( FTC_Cache cache ); - - - typedef FT_Error - (*FTC_Family_InitFunc)( FTC_Family family, - FTC_Query query, - FTC_Cache cache ); - - typedef FT_Int - (*FTC_Family_CompareFunc)( FTC_Family family, - FTC_Query query ); - - typedef void - (*FTC_Family_DoneFunc)( FTC_Family family, - FTC_Cache cache ); - /* initialize a new cache node */ typedef FT_Error - (*FTC_Node_InitFunc)( FTC_Node node, - FT_Pointer type, - FTC_Cache cache ); + (*FTC_Node_NewFunc)( FTC_Node *pnode, + FT_Pointer query, + FTC_Cache cache ); - /* compute the weight of a given cache node */ typedef FT_ULong (*FTC_Node_WeightFunc)( FTC_Node node, FTC_Cache cache ); @@ -236,62 +107,159 @@ FT_BEGIN_HEADER FT_Pointer key, FTC_Cache cache ); - /* finalize a given cache node */ + typedef void - (*FTC_Node_DoneFunc)( FTC_Node node, + (*FTC_Node_FreeFunc)( FTC_Node node, FTC_Cache cache ); + typedef FT_Error + (*FTC_Cache_InitFunc)( FTC_Cache cache ); - typedef struct FTC_Cache_ClassRec_ + typedef void + (*FTC_Cache_DoneFunc)( FTC_Cache cache ); + + + typedef struct FTC_CacheClassRec_ { - FT_UInt cache_size; - FTC_Cache_InitFunc cache_init; - FTC_Cache_ClearFunc cache_clear; - FTC_Cache_DoneFunc cache_done; + FTC_Node_NewFunc node_new; + FTC_Node_WeightFunc node_weight; + FTC_Node_CompareFunc node_compare; + FTC_Node_CompareFunc node_remove_faceid; + FTC_Node_FreeFunc node_free; - FT_UInt family_size; - FTC_Family_InitFunc family_init; - FTC_Family_CompareFunc family_compare; - FTC_Family_DoneFunc family_done; + FT_UInt cache_size; + FTC_Cache_InitFunc cache_init; + FTC_Cache_DoneFunc cache_done; - FT_UInt node_size; - FTC_Node_InitFunc node_init; - FTC_Node_WeightFunc node_weight; - FTC_Node_CompareFunc node_compare; - FTC_Node_DoneFunc node_done; - - } FTC_Cache_ClassRec; + } FTC_CacheClassRec; - /* */ + /* each cache really implements a dynamic hash table to manage its nodes */ + typedef struct FTC_CacheRec_ + { + FT_UFast p; + FT_UFast mask; + FT_Long slack; + FTC_Node* buckets; + + FTC_CacheClassRec clazz; /* local copy, for speed */ + + FTC_Manager manager; + FT_Memory memory; + FT_UInt index; /* in manager's table */ + + FTC_CacheClass org_class; /* original class pointer */ + + } FTC_CacheRec; - /*************************************************************************/ - /* */ - /* 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. */ - /* */ +#define FTC_CACHE( x ) ( (FTC_Cache)(x) ) +#define FTC_CACHE_P( x ) ( (FTC_Cache*)(x) ) - /* can be used directly as FTC_Cache_DoneFunc(), or called by custom */ - /* cache finalizers */ - FT_EXPORT( void ) - ftc_cache_done( FTC_Cache cache ); - /* can be used directly as FTC_Cache_ClearFunc(), or called by custom */ - /* cache clear routines */ - FT_EXPORT( void ) - ftc_cache_clear( FTC_Cache cache ); - - /* initalize the hash table within the cache */ + /* default cache initialize */ FT_EXPORT( FT_Error ) - ftc_cache_init( FTC_Cache cache ); + FTC_Cache_Init( FTC_Cache cache ); - /* can be called when the key's hash value has been computed */ + /* default cache finalizer */ + FT_EXPORT( void ) + FTC_Cache_Done( FTC_Cache cache ); + + /* Call this function to lookup the cache. If no corresponding + * node is found, a new one is automatically created. This function + * is capable of flushing the cache adequately to make room for the + * new cache object. + */ FT_EXPORT( FT_Error ) - ftc_cache_lookup( FTC_Cache cache, - FTC_Query query, - FTC_Node *anode ); + FTC_Cache_Lookup( FTC_Cache cache, + FT_UInt32 hash, + FT_Pointer query, + FTC_Node *anode ); + + FT_EXPORT( FT_Error ) + FTC_Cache_NewNode( FTC_Cache cache, + FT_UInt32 hash, + FT_Pointer query, + FTC_Node *anode ); + + /* Remove all nodes that relate to a given face_id. This is useful + * when un-installing fonts. Note that if a cache node relates to + * the face_id, but is locked (i.e., has 'ref_count > 0'), the node + * will _not_ be destroyed, but its internal face_id reference will + * be modified. + * + * The final result will be that the node will never come back + * in further lookup requests, and will be flushed on demand from + * the cache normally when its reference count reaches 0. + */ + FT_EXPORT( void ) + FTC_Cache_RemoveFaceID( FTC_Cache cache, + FTC_FaceID face_id ); + + +#ifdef FTC_INLINE + +#define FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ) \ + FT_BEGIN_STMNT \ + FTC_Node *_bucket, *_pnode, _node; \ + FTC_Cache _cache = FTC_CACHE(cache); \ + FT_UInt32 _hash = (FT_UInt32)(hash); \ + FTC_Node_CompareFunc _nodcomp = (FTC_Node_CompareFunc)(nodecmp); \ + FT_UInt _idx; \ + \ + \ + error = 0; \ + node = NULL; \ + _idx = _hash & _cache->mask; \ + if ( _idx < _cache->p ) \ + _idx = _hash & ( _cache->mask*2 + 1 ); \ + \ + _bucket = _pnode = _cache->buckets + _idx; \ + for (;;) \ + { \ + _node = *_pnode; \ + if ( _node == NULL ) \ + goto _NewNode; \ + \ + if ( _node->hash == _hash && _nodcomp( _node, query, _cache ) ) \ + break; \ + \ + _pnode = &_node->link; \ + } \ + \ + if ( _node != *_bucket ) \ + { \ + *_pnode = _node->link; \ + _node->link = *_bucket; \ + *_bucket = _node; \ + } \ + \ + { \ + FTC_Manager _manager = _cache->manager; \ + \ + \ + if ( _node != _manager->nodes_list ) \ + FTC_MruNode_Up( (FTC_MruNode*)&_manager->nodes_list, \ + (FTC_MruNode)_node ); \ + } \ + goto _Ok; \ + \ + _NewNode: \ + error = FTC_Cache_NewNode( _cache, _hash, query, &_node ); \ + \ + _Ok: \ + *(FTC_Node*)&(node) = _node; \ + FT_END_STMNT + +#else /* !FTC_INLINE */ + +#define FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ) \ + FT_BEGIN_STMNT \ + error = FTC_Cache_Lookup( FTC_CACHE( cache ), hash, query, \ + (FTC_Node*)&(node) ); \ + FT_END_STMNT + +#endif /* !FTC_INLINE */ /* */ @@ -301,4 +269,4 @@ FT_END_HEADER #endif /* __FTCCACHE_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/cache/ftccmap.h b/headers/libs/freetype2/freetype/cache/ftccmap.h index 4016a4fe77..a41989b282 100644 --- a/headers/libs/freetype2/freetype/cache/ftccmap.h +++ b/headers/libs/freetype2/freetype/cache/ftccmap.h @@ -4,7 +4,7 @@ /* */ /* FreeType charmap cache (specification). */ /* */ -/* Copyright 2000-2001 by */ +/* Copyright 2000-2001, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -36,7 +36,7 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ /* @type: */ - /* FTC_CmapCache */ + /* FTC_CMapCache */ /* */ /* @description: */ /* An opaque handle used to manager a charmap cache. This cache is */ @@ -54,8 +54,8 @@ FT_BEGIN_HEADER /* A handle to an @FTC_CMapDescRec structure used to describe a given */ /* charmap in a charmap cache. */ /* */ - /* Each @FTC_CMapDesc describes which charmap (of which @FTC_Face) we */ - /* want to use in @FTC_CMapCache_Lookup. */ + /* Each @FTC_CMapDesc describes which charmap (of which @FTC_FaceID) */ + /* we want to use in @FTC_CMapCache_Lookup. */ /* */ typedef struct FTC_CMapDescRec_* FTC_CMapDesc; @@ -66,8 +66,8 @@ FT_BEGIN_HEADER /* FTC_CMapType */ /* */ /* @description: */ - /* The list of valid @FTC_CMap types. They indicate how we want to */ - /* address a charmap within an @FTC_FaceID. */ + /* The list of valid @FTC_CMapDesc types. They indicate how we want */ + /* to address a charmap within an @FTC_FaceID. */ /* */ /* @values: */ /* FTC_CMAP_BY_INDEX :: */ @@ -213,4 +213,4 @@ FT_END_HEADER #endif /* __FTCCMAP_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/cache/ftcglyph.h b/headers/libs/freetype2/freetype/cache/ftcglyph.h index afc7290381..be237f934a 100644 --- a/headers/libs/freetype2/freetype/cache/ftcglyph.h +++ b/headers/libs/freetype2/freetype/cache/ftcglyph.h @@ -4,7 +4,7 @@ /* */ /* FreeType abstract glyph cache (specification). */ /* */ -/* Copyright 2000-2001 by */ +/* Copyright 2000-2001, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,13 +16,84 @@ /***************************************************************************/ + /* + * + * 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. */ - /* For example, see `ftcimage.h' and `ftcimage.c' which */ - /* implement a FT_Glyph cache based on this code. */ /* */ /*************************************************************************/ @@ -47,99 +118,53 @@ #include -#include FT_CACHE_H -#include FT_CACHE_MANAGER_H - -#include +#include FT_CACHE_INTERNAL_MANAGER_H FT_BEGIN_HEADER - /* each glyph set is characterized by a "glyph set type" which must be */ - /* defined by sub-classes */ - typedef struct FTC_GlyphFamilyRec_* FTC_GlyphFamily; + /* + * 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. + */ - /* handle to a glyph cache node */ - typedef struct FTC_GlyphNodeRec_* FTC_GlyphNode; - - - /* size should be 24 + chunk size on 32-bit machines; */ - /* note that the node's hash is ((gfam->hash << 16) | glyph_index) -- */ - /* this _must_ be set properly by the glyph node initializer */ - /* */ - typedef struct FTC_GlyphNodeRec_ + typedef struct FTC_FamilyRec_ { - FTC_NodeRec node; - FT_UShort item_count; - FT_UShort item_start; + FTC_MruNodeRec mrunode; + FT_UInt num_nodes; /* current number of nodes in this family */ + FTC_Cache cache; + FTC_MruListClass clazz; - } FTC_GlyphNodeRec; + } FTC_FamilyRec, *FTC_Family; + +#define FTC_FAMILY(x) ( (FTC_Family)(x) ) +#define FTC_FAMILY_P(x) ( (FTC_Family*)(x) ) -#define FTC_GLYPH_NODE( x ) ( (FTC_GlyphNode)(x) ) -#define FTC_GLYPH_NODE_P( x ) ( (FTC_GlyphNode*)(x) ) - - - typedef struct FTC_GlyphQueryRec_ + typedef struct FTC_GNodeRec_ { - FTC_QueryRec query; - FT_UInt gindex; + FTC_NodeRec node; + FTC_Family family; + FT_UInt gindex; - } FTC_GlyphQueryRec, *FTC_GlyphQuery; + } FTC_GNodeRec, *FTC_GNode; + +#define FTC_GNODE( x ) ( (FTC_GNode)(x) ) +#define FTC_GNODE_P( x ) ( (FTC_GNode*)(x) ) -#define FTC_GLYPH_QUERY( x ) ( (FTC_GlyphQuery)(x) ) - - - /* a glyph set is used to categorize glyphs of a given type */ - typedef struct FTC_GlyphFamilyRec_ + typedef struct FTC_GQueryRec_ { - FTC_FamilyRec family; - FT_UInt32 hash; - FT_UInt item_total; /* total number of glyphs in family */ - FT_UInt item_count; /* number of glyph items per node */ + FT_UInt gindex; + FTC_Family family; - } FTC_GlyphFamilyRec; + } FTC_GQueryRec, *FTC_GQuery; - -#define FTC_GLYPH_FAMILY( x ) ( (FTC_GlyphFamily)(x) ) -#define FTC_GLYPH_FAMILY_P( x ) ( (FTC_GlyphFamily*)(x) ) - -#define FTC_GLYPH_FAMILY_MEMORY( x ) FTC_FAMILY(x)->cache->memory - - - /* each glyph node contains a 'chunk' of glyph items; */ - /* translate a glyph index into a chunk index */ -#define FTC_GLYPH_FAMILY_CHUNK( gfam, gindex ) \ - ( ( gindex ) / FTC_GLYPH_FAMILY( gfam )->item_count ) - - /* find a glyph index's chunk, and return its start index */ -#define FTC_GLYPH_FAMILY_START( gfam, gindex ) \ - ( FTC_GLYPH_FAMILY_CHUNK( gfam, gindex ) * \ - FTC_GLYPH_FAMILY( gfam )->item_count ) - - /* compute a glyph request's hash value */ -#define FTC_GLYPH_FAMILY_HASH( gfam, gindex ) \ - ( (FT_UFast)( \ - ( FTC_GLYPH_FAMILY( gfam )->hash << 16 ) | \ - ( FTC_GLYPH_FAMILY_CHUNK( gfam, gindex ) & 0xFFFF ) ) ) - - /* must be called in an FTC_Family_CompareFunc to update the query */ - /* whenever a glyph set is matched in the lookup, or when it */ - /* is created */ -#define FTC_GLYPH_FAMILY_FOUND( gfam, gquery ) \ - do \ - { \ - FTC_QUERY( gquery )->family = FTC_FAMILY( gfam ); \ - FTC_QUERY( gquery )->hash = \ - FTC_GLYPH_FAMILY_HASH( gfam, \ - FTC_GLYPH_QUERY( gquery )->gindex ); \ - } while ( 0 ) - - /* retrieve glyph index of glyph node */ -#define FTC_GLYPH_NODE_GINDEX( x ) \ - ( (FT_UInt)( FTC_GLYPH_NODE( x )->node.hash & 0xFFFF ) ) +#define FTC_GQUERY( x ) ( (FTC_GQuery)(x) ) /*************************************************************************/ @@ -151,43 +176,120 @@ FT_BEGIN_HEADER /* must be called by derived FTC_Node_InitFunc routines */ FT_EXPORT( void ) - ftc_glyph_node_init( FTC_GlyphNode node, - FT_UInt gindex, /* glyph index for node */ - FTC_GlyphFamily gfam ); + FTC_GNode_Init( FTC_GNode node, + FT_UInt gindex, /* glyph index for node */ + FTC_Family family ); /* 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_EXPORT( FT_Bool ) - ftc_glyph_node_compare( FTC_GlyphNode gnode, - FTC_GlyphQuery gquery ); + FTC_GNode_Compare( FTC_GNode gnode, + FTC_GQuery gquery ); + + /* call this function to clear a node's family -- this is necessary */ + /* to implement the `node_remove_faceid' cache method correctly */ + FT_EXPORT( void ) + FTC_GNode_UnselectFamily( FTC_GNode gnode, + FTC_Cache cache ); /* must be called by derived FTC_Node_DoneFunc routines */ FT_EXPORT( void ) - ftc_glyph_node_done( FTC_GlyphNode node, - FTC_Cache cache ); + FTC_GNode_Done( FTC_GNode node, + FTC_Cache cache ); - /* must be called by derived FTC_Family_InitFunc; */ - /* calls "ftc_family_init" */ - FT_EXPORT( FT_Error ) - ftc_glyph_family_init( FTC_GlyphFamily gfam, - FT_UInt32 hash, - FT_UInt item_count, - FT_UInt item_total, - FTC_GlyphQuery gquery, - FTC_Cache cache ); - FT_EXPORT( void ) - ftc_glyph_family_done( FTC_GlyphFamily gfam ); + 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)) + /* can be used as @FTC_Cache_InitFunc */ + FT_EXPORT( FT_Error ) + FTC_GCache_Init( FTC_GCache cache ); + + + /* can be used as @FTC_Cache_DoneFunc */ + FT_EXPORT( void ) + FTC_GCache_Done( FTC_GCache cache ); + + + /* 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_EXPORT( FT_Error ) + FTC_GCache_New( FTC_Manager manager, + FTC_GCacheClass clazz, + FTC_GCache *acache ); + + FT_EXPORT( FT_Error ) + FTC_GCache_Lookup( FTC_GCache cache, + FT_UInt32 hash, + FT_UInt gindex, + FTC_GQuery query, + FTC_Node *anode ); + + +#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); \ + \ + \ + _gquery->gindex = (gindex); \ + \ + FTC_MRULIST_LOOKUP_CMP( &_gcache->families, _gquery, _fcompare, \ + _gquery->family, error ); \ + if ( !error ) \ + FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ); \ + 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 ), (FTC_Node*)&(node) ); \ + FT_END_STMNT + +#endif /* !FTC_INLINE */ + + FT_END_HEADER #endif /* __FTCGLYPH_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/cache/ftcimage.h b/headers/libs/freetype2/freetype/cache/ftcimage.h index 5e65f1a0dd..1bf12db13d 100644 --- a/headers/libs/freetype2/freetype/cache/ftcimage.h +++ b/headers/libs/freetype2/freetype/cache/ftcimage.h @@ -2,9 +2,9 @@ /* */ /* ftcimage.h */ /* */ -/* FreeType Image cache (specification). */ +/* FreeType Generic Image cache (specification) */ /* */ -/* Copyright 2000-2001, 2002 by */ +/* Copyright 2000-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,6 +16,15 @@ /***************************************************************************/ + /* + * FTC_ICache is an _abstract_ cache used to store a single FT_Glyph + * image per cache node. + * + * FTC_ICache extends FTC_GCache. For an implementation example, + * see FTC_ImageCache in `src/cache/ftbasic.c'. + */ + + /*************************************************************************/ /* */ /* Each image cache really manages FT_Glyph objects. */ @@ -29,284 +38,67 @@ #include #include FT_CACHE_H - +#include FT_CACHE_INTERNAL_GLYPH_H FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /*
*/ - /* cache_subsystem */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** IMAGE CACHE OBJECT *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /************************************************************************** - * - * @struct: - * FTC_ImageTypeRec - * - * @description: - * A simple structure used to describe the type of glyph image to be - * loaded into the cache. - * - * @fields: - * font :: An @FTC_FontRec used to describe the glyph's face and size. - * - * flags :: The load flags to be applied when loading the glyph; see - * the @FT_LOAD_XXX constants for details. - * - * @note: - * This type completely replaces the @FTC_Image_Desc structure which is - * now obsolete. - */ - typedef struct FTC_ImageTypeRec_ + /* the FT_Glyph image node type - we store only 1 glyph per node */ + typedef struct FTC_INodeRec_ { - FTC_FontRec font; - FT_Int32 flags; + FTC_GNodeRec gnode; + FT_Glyph glyph; - } FTC_ImageTypeRec; + } FTC_INodeRec, *FTC_INode; - typedef struct FTC_ImageTypeRec_* FTC_ImageType; +#define FTC_INODE( x ) ( (FTC_INode)( x ) ) +#define FTC_INODE_GINDEX( x ) FTC_GNODE(x)->gindex +#define FTC_INODE_FAMILY( x ) FTC_GNODE(x)->family - /* */ + typedef FT_Error + (*FTC_IFamily_LoadGlyphFunc)( FTC_Family family, + FT_UInt gindex, + FTC_Cache cache, + FT_Glyph *aglyph ); -#define FTC_IMAGE_TYPE_COMPARE( d1, d2 ) \ - ( FTC_FONT_COMPARE( &(d1)->font, &(d2)->font ) && \ - (d1)->flags == (d2)->flags ) - -#define FTC_IMAGE_TYPE_HASH( d ) \ - (FT_UFast)( FTC_FONT_HASH( &(d)->font ) ^ \ - ( (d)->flags << 4 ) ) - - - /*************************************************************************/ - /* */ - /* */ - /* FTC_ImageCache */ - /* */ - /* */ - /* A handle to an glyph image cache object. They are designed to */ - /* hold many distinct glyph images while not exceeding a certain */ - /* memory threshold. */ - /* */ - typedef struct FTC_ImageCacheRec_* FTC_ImageCache; - - - /*************************************************************************/ - /* */ - /* */ - /* FTC_ImageCache_New */ - /* */ - /* */ - /* Creates a new glyph image cache. */ - /* */ - /* */ - /* manager :: The parent manager for the image cache. */ - /* */ - /* */ - /* acache :: A handle to the new glyph image cache object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT( FT_Error ) - FTC_ImageCache_New( FTC_Manager manager, - FTC_ImageCache *acache ); - - - /*************************************************************************/ - /* */ - /* */ - /* FTC_ImageCache_Lookup */ - /* */ - /* */ - /* Retrieves a given glyph image from a glyph image cache. */ - /* */ - /* */ - /* cache :: A handle to the source glyph image cache. */ - /* */ - /* type :: A pointer to a glyph image type descriptor. */ - /* */ - /* gindex :: The glyph index to retrieve. */ - /* */ - /* */ - /* aglyph :: The corresponding @FT_Glyph object. 0 in case of */ - /* failure. */ - /* */ - /* anode :: Used to return the address of of the corresponding cache */ - /* node after incrementing its reference count (see note */ - /* below). */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The returned glyph is owned and managed by the glyph image cache. */ - /* Never try to transform or discard it manually! You can however */ - /* create a copy with @FT_Glyph_Copy and modify the new one. */ - /* */ - /* If "anode" is _not_ NULL, it receives the address of the cache */ - /* node containing the glyph image, after increasing its reference */ - /* count. This ensures that the node (as well as the FT_Glyph) will */ - /* always be kept in the cache until you call @FTC_Node_Unref to */ - /* "release" it. */ - /* */ - /* If "anode" is NULL, the cache node is left unchanged, which means */ - /* that the FT_Glyph could be flushed out of the cache on the next */ - /* call to one of the caching sub-system APIs. Don't assume that it */ - /* is persistent! */ - /* */ - FT_EXPORT( FT_Error ) - FTC_ImageCache_Lookup( FTC_ImageCache cache, - FTC_ImageType type, - FT_UInt gindex, - FT_Glyph *aglyph, - FTC_Node *anode ); - - /* */ - -#define ftc_image_format( x ) ( (x) & 7 ) - - -#define ftc_image_format_bitmap 0x0000 -#define ftc_image_format_outline 0x0001 - -#define ftc_image_format_mask 0x000F - -#define ftc_image_flag_monochrome 0x0010 -#define ftc_image_flag_unhinted 0x0020 -#define ftc_image_flag_autohinted 0x0040 -#define ftc_image_flag_unscaled 0x0080 -#define ftc_image_flag_no_sbits 0x0100 - - /* monochrome bitmap */ -#define ftc_image_mono ftc_image_format_bitmap | \ - ftc_image_flag_monochrome - - /* anti-aliased bitmap */ -#define ftc_image_grays ftc_image_format_bitmap - - /* scaled outline */ -#define ftc_image_outline ftc_image_format_outline - - /*************************************************************************/ - /* */ - /* */ - /* FTC_Image_Desc */ - /* */ - /* */ - /* THIS TYPE IS DEPRECATED. Use @FTC_ImageDesc instead. */ - /* */ - /* A simple structure used to describe a given glyph image category. */ - /* */ - /* */ - /* size :: An @FTC_SizeRec used to describe the glyph's face */ - /* and size. */ - /* */ - /* image_type :: The glyph image's type. */ - /* */ - typedef struct FTC_Image_Desc_ + typedef struct FTC_IFamilyClassRec_ { - FTC_FontRec font; - FT_UInt image_type; + FTC_MruListClassRec clazz; + FTC_IFamily_LoadGlyphFunc family_load_glyph; - } FTC_Image_Desc; + } FTC_IFamilyClassRec; + + typedef const FTC_IFamilyClassRec* FTC_IFamilyClass; + +#define FTC_IFAMILY_CLASS( x ) ((FTC_IFamilyClass)(x)) + +#define FTC_CACHE__IFAMILY_CLASS( x ) \ + FTC_IFAMILY_CLASS( FTC_CACHE__GCACHE_CLASS(x)->family_class ) - /*************************************************************************/ - /* */ - /* */ - /* FTC_Image_Cache */ - /* */ - /* */ - /* THIS TYPE IS DEPRECATED. Use @FTC_ImageCache instead. */ - /* */ - typedef FTC_ImageCache FTC_Image_Cache; + /* can be used as a @FTC_Node_FreeFunc */ + FT_EXPORT( void ) + FTC_INode_Free( FTC_INode inode, + FTC_Cache cache ); - - /*************************************************************************/ - /* */ - /* */ - /* FTC_Image_Cache_New */ - /* */ - /* */ - /* THIS FUNCTION IS DEPRECATED. Use @FTC_ImageCache_New instead. */ - /* */ - /* Creates a new glyph image cache. */ - /* */ - /* */ - /* manager :: The parent manager for the image cache. */ - /* */ - /* */ - /* acache :: A handle to the new glyph image cache object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ + /* Can be used as @FTC_Node_NewFunc. `gquery.index' and `gquery.family' + * must be set correctly. This function will call the `family_load_glyph' + * method to load the FT_Glyph into the cache node. + */ FT_EXPORT( FT_Error ) - FTC_Image_Cache_New( FTC_Manager manager, - FTC_Image_Cache *acache ); + FTC_INode_New( FTC_INode *pinode, + FTC_GQuery gquery, + FTC_Cache cache ); - - /*************************************************************************/ - /* */ - /* */ - /* FTC_Image_Cache_Lookup */ - /* */ - /* */ - /* THIS FUNCTION IS DEPRECATED. Use @FTC_ImageCache_Lookup instead. */ - /* */ - /* */ - /* cache :: A handle to the source glyph image cache. */ - /* */ - /* desc :: A pointer to a glyph image descriptor. */ - /* */ - /* gindex :: The glyph index to retrieve. */ - /* */ - /* */ - /* aglyph :: The corresponding @FT_Glyph object. 0 in case of */ - /* failure. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The returned glyph is owned and managed by the glyph image cache. */ - /* Never try to transform or discard it manually! You can however */ - /* create a copy with @FT_Glyph_Copy and modify the new one. */ - /* */ - /* Because the glyph image cache limits the total amount of memory */ - /* taken by the glyphs it holds, the returned glyph might disappear */ - /* on a later invocation of this function! It is a cache after */ - /* all... */ - /* */ - /* Use this function to "lock" the glyph as long as it is needed. */ - /* */ - FT_EXPORT( FT_Error ) - FTC_Image_Cache_Lookup( FTC_Image_Cache cache, - FTC_Image_Desc* desc, - FT_UInt gindex, - FT_Glyph *aglyph ); + /* can be used as @FTC_Node_WeightFunc */ + FT_EXPORT( FT_ULong ) + FTC_INode_Weight( FTC_INode inode ); /* */ FT_END_HEADER - #endif /* __FTCIMAGE_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/cache/ftcmanag.h b/headers/libs/freetype2/freetype/cache/ftcmanag.h index f7f397c89a..5265848228 100644 --- a/headers/libs/freetype2/freetype/cache/ftcmanag.h +++ b/headers/libs/freetype2/freetype/cache/ftcmanag.h @@ -4,7 +4,7 @@ /* */ /* FreeType Cache Manager (specification). */ /* */ -/* Copyright 2000-2001 by */ +/* Copyright 2000-2001, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -65,7 +65,7 @@ #include #include FT_CACHE_H -#include FT_CACHE_INTERNAL_LRU_H +#include FT_CACHE_INTERNAL_MRU_H #include FT_CACHE_INTERNAL_CACHE_H @@ -88,91 +88,25 @@ FT_BEGIN_HEADER #define FTC_MAX_CACHES 16 - typedef struct FTC_FamilyEntryRec_ - { - FTC_Family family; - FTC_Cache cache; - FT_UInt index; - FT_UInt link; - - } FTC_FamilyEntryRec, *FTC_FamilyEntry; - - -#define FTC_FAMILY_ENTRY_NONE ( (FT_UInt)-1 ) - - - typedef struct FTC_FamilyTableRec_ - { - FT_UInt count; - FT_UInt size; - FTC_FamilyEntry entries; - FT_UInt free; - - } FTC_FamilyTableRec, *FTC_FamilyTable; - - - FT_EXPORT( FT_Error ) - ftc_family_table_alloc( FTC_FamilyTable table, - FT_Memory memory, - FTC_FamilyEntry *aentry ); - - FT_EXPORT( void ) - ftc_family_table_free( FTC_FamilyTable table, - FT_UInt idx ); - - - /*************************************************************************/ - /* */ - /* */ - /* FTC_ManagerRec */ - /* */ - /* */ - /* The cache manager structure. */ - /* */ - /* */ - /* library :: A handle to a FreeType library instance. */ - /* */ - /* faces_list :: The lru list of @FT_Face objects in the cache. */ - /* */ - /* sizes_list :: The lru list of @FT_Size objects in the cache. */ - /* */ - /* max_weight :: The maximum cache pool weight. */ - /* */ - /* cur_weight :: The current cache pool weight. */ - /* */ - /* num_nodes :: The current number of nodes in the manager. */ - /* */ - /* nodes_list :: The global lru list of all cache nodes. */ - /* */ - /* caches :: A table of installed/registered cache objects. */ - /* */ - /* request_data :: User-provided data passed to the requester. */ - /* */ - /* request_face :: User-provided function used to implement a mapping */ - /* between abstract @FTC_FaceID values and real */ - /* @FT_Face objects. */ - /* */ - /* families :: Global table of families. */ - /* */ typedef struct FTC_ManagerRec_ { FT_Library library; - FT_LruList faces_list; - FT_LruList sizes_list; + FT_Memory memory; + FTC_Node nodes_list; FT_ULong max_weight; FT_ULong cur_weight; - FT_UInt num_nodes; - FTC_Node nodes_list; - + FTC_Cache caches[FTC_MAX_CACHES]; + FT_UInt num_caches; + + FTC_MruListRec faces; + FTC_MruListRec sizes; FT_Pointer request_data; FTC_Face_Requester request_face; - FTC_FamilyTableRec families; - } FTC_ManagerRec; @@ -201,44 +135,41 @@ FT_BEGIN_HEADER FTC_Manager_Compress( FTC_Manager manager ); + /* try to flush `count' old nodes from the cache; return the number + * of really flushed nodes + */ + FT_EXPORT( FT_UInt ) + FTC_Manager_FlushN( FTC_Manager manager, + FT_UInt count ); + + /* this must be used internally for the moment */ FT_EXPORT( FT_Error ) - FTC_Manager_Register_Cache( FTC_Manager manager, - FTC_Cache_Class clazz, - FTC_Cache *acache ); + FTC_Manager_RegisterCache( FTC_Manager manager, + FTC_CacheClass clazz, + FTC_Cache *acache ); + /* */ - /* can be called to increment a node's reference count */ - FT_EXPORT( void ) - FTC_Node_Ref( FTC_Node node, - FTC_Manager manager ); +#define FTC_SCALER_COMPARE( a, b ) \ + ( (a)->face_id == (b)->face_id && \ + (a)->width == (b)->width && \ + (a)->height == (b)->height && \ + ((a)->pixel != 0) == ((b)->pixel != 0) && \ + ( (a)->pixel || \ + ( (a)->x_res == (b)->x_res && \ + (a)->y_res == (b)->y_res ) ) ) - - /*************************************************************************/ - /* */ - /* */ - /* FTC_Node_Unref */ - /* */ - /* */ - /* Decrement a cache node's internal reference count. When the count */ - /* reaches 0, it is not destroyed but becomes eligible for subsequent */ - /* cache flushes. */ - /* */ - /* */ - /* node :: The cache node handle. */ - /* */ - /* manager :: The cache manager handle. */ - /* */ - FT_EXPORT( void ) - FTC_Node_Unref( FTC_Node node, - FTC_Manager manager ); +#define FTC_SCALER_HASH( q ) \ + ( FTC_FACE_ID_HASH( (q)->face_id ) + \ + (q)->width + (q)->height*7 + \ + ( (q)->pixel ? 0 : ( (q)->x_res*33 ^ (q)->y_res*61 ) ) ) /* */ FT_END_HEADER - #endif /* __FTCMANAG_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/cache/ftcmru.h b/headers/libs/freetype2/freetype/cache/ftcmru.h new file mode 100644 index 0000000000..9556f58e75 --- /dev/null +++ b/headers/libs/freetype2/freetype/cache/ftcmru.h @@ -0,0 +1,246 @@ +/***************************************************************************/ +/* */ +/* ftcmru.h */ +/* */ +/* Simple MRU list-cache (specification). */ +/* */ +/* Copyright 2000-2001, 2003, 2004 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* An MRU is a list that cannot hold more than a certain number of */ + /* elements (`max_elements'). All elements in the list are sorted in */ + /* least-recently-used order, i.e., the `oldest' element is at the tail */ + /* of the list. */ + /* */ + /* When doing a lookup (either through `Lookup()' or `Lookup_Node()'), */ + /* the list is searched for an element with the corresponding key. If */ + /* it is found, the element is moved to the head of the list and is */ + /* returned. */ + /* */ + /* If no corresponding element is found, the lookup routine will try to */ + /* obtain a new element with the relevant key. If the list is already */ + /* full, the oldest element from the list is discarded and replaced by a */ + /* new one; a new element is added to the list otherwise. */ + /* */ + /* Note that it is possible to pre-allocate the element list nodes. */ + /* This is handy if `max_elements' is sufficiently small, as it saves */ + /* allocations/releases during the lookup process. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTCMRU_H__ +#define __FTCMRU_H__ + + +#include +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + +#define xxFT_DEBUG_ERROR +#define FTC_INLINE + +FT_BEGIN_HEADER + + typedef struct FTC_MruNodeRec_* FTC_MruNode; + + typedef struct FTC_MruNodeRec_ + { + FTC_MruNode next; + FTC_MruNode prev; + + } FTC_MruNodeRec; + + + FT_EXPORT( void ) + FTC_MruNode_Prepend( FTC_MruNode *plist, + FTC_MruNode node ); + + FT_EXPORT( void ) + FTC_MruNode_Up( FTC_MruNode *plist, + FTC_MruNode node ); + + FT_EXPORT( void ) + FTC_MruNode_Remove( FTC_MruNode *plist, + FTC_MruNode node ); + + + typedef struct FTC_MruListRec_* FTC_MruList; + + typedef struct FTC_MruListClassRec_ const * FTC_MruListClass; + + + typedef FT_Int + (*FTC_MruNode_CompareFunc)( FTC_MruNode node, + FT_Pointer key ); + + typedef FT_Error + (*FTC_MruNode_InitFunc)( FTC_MruNode node, + FT_Pointer key, + FT_Pointer data ); + + typedef FT_Error + (*FTC_MruNode_ResetFunc)( FTC_MruNode node, + FT_Pointer key, + FT_Pointer data ); + + typedef void + (*FTC_MruNode_DoneFunc)( FTC_MruNode node, + FT_Pointer data ); + + + typedef struct FTC_MruListClassRec_ + { + FT_UInt node_size; + FTC_MruNode_CompareFunc node_compare; + FTC_MruNode_InitFunc node_init; + FTC_MruNode_ResetFunc node_reset; + FTC_MruNode_DoneFunc node_done; + + } FTC_MruListClassRec; + + typedef struct FTC_MruListRec_ + { + FT_UInt num_nodes; + FT_UInt max_nodes; + FTC_MruNode nodes; + FT_Pointer data; + FTC_MruListClassRec clazz; + FT_Memory memory; + + } FTC_MruListRec; + + + FT_EXPORT( void ) + FTC_MruList_Init( FTC_MruList list, + FTC_MruListClass clazz, + FT_UInt max_nodes, + FT_Pointer data, + FT_Memory memory ); + + FT_EXPORT( void ) + FTC_MruList_Reset( FTC_MruList list ); + + + FT_EXPORT( void ) + FTC_MruList_Done( FTC_MruList list ); + + FT_EXPORT( FTC_MruNode ) + FTC_MruList_Find( FTC_MruList list, + FT_Pointer key ); + + FT_EXPORT( FT_Error ) + FTC_MruList_New( FTC_MruList list, + FT_Pointer key, + FTC_MruNode *anode ); + + FT_EXPORT( FT_Error ) + FTC_MruList_Lookup( FTC_MruList list, + FT_Pointer key, + FTC_MruNode *pnode ); + + + FT_EXPORT( void ) + FTC_MruList_Remove( FTC_MruList list, + FTC_MruNode node ); + + FT_EXPORT( void ) + FTC_MruList_RemoveSelection( FTC_MruList list, + FTC_MruNode_CompareFunc selection, + FT_Pointer key ); + + +#ifdef FTC_INLINE + +#define FTC_MRULIST_LOOKUP_CMP( list, key, compare, node, error ) \ + FT_BEGIN_STMNT \ + FTC_MruNode* _pfirst = &(list)->nodes; \ + FTC_MruNode_CompareFunc _compare = (FTC_MruNode_CompareFunc)(compare); \ + FTC_MruNode _first, _node; \ + \ + \ + error = 0; \ + _first = *(_pfirst); \ + _node = NULL; \ + \ + if ( _first ) \ + { \ + _node = _first; \ + do \ + { \ + if ( _compare( _node, (key) ) ) \ + { \ + if ( _node != _first ) \ + FTC_MruNode_Up( _pfirst, _node ); \ + \ + *(FTC_MruNode*)&(node) = _node; \ + goto _MruOk; \ + } \ + _node = _node->next; \ + \ + } while ( _node != _first) ; \ + } \ + \ + error = FTC_MruList_New( (list), (key), (FTC_MruNode*)&(node) ); \ + _MruOk: \ + ; \ + FT_END_STMNT + +#define FTC_MRULIST_LOOKUP( list, key, node, error ) \ + FTC_MRULIST_LOOKUP_CMP( list, key, (list)->clazz.node_compare, node, error ) + +#else /* !FTC_INLINE */ + +#define FTC_MRULIST_LOOKUP( list, key, node, error ) \ + error = FTC_MruList_Lookup( (list), (key), (FTC_MruNode*)&(node) ) + +#endif /* !FTC_INLINE */ + + +#define FTC_MRULIST_LOOP( list, node ) \ + FT_BEGIN_STMNT \ + FTC_MruNode _first = (list)->nodes; \ + \ + \ + if ( _first ) \ + { \ + FTC_MruNode _node = _first; \ + \ + \ + do \ + { \ + *(FTC_MruNode*)&(node) = _node; + + +#define FTC_MRULIST_LOOP_END() \ + _node = _node->next; \ + \ + } while ( _node != _first ); \ + } \ + FT_END_STMNT + + /* */ + +FT_END_HEADER + + +#endif /* __FTCMRU_H__ */ + + +/* END */ diff --git a/headers/libs/freetype2/freetype/cache/ftcsbits.h b/headers/libs/freetype2/freetype/cache/ftcsbits.h index 41b5cceea0..b2ef0f1818 100644 --- a/headers/libs/freetype2/freetype/cache/ftcsbits.h +++ b/headers/libs/freetype2/freetype/cache/ftcsbits.h @@ -4,7 +4,7 @@ /* */ /* A small-bitmap cache (specification). */ /* */ -/* Copyright 2000-2001, 2002 by */ +/* Copyright 2000-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,254 +22,75 @@ #include #include FT_CACHE_H -#include FT_CACHE_IMAGE_H +#include FT_CACHE_INTERNAL_GLYPH_H FT_BEGIN_HEADER +#define FTC_SBIT_ITEMS_PER_NODE 16 - /*************************************************************************/ - /* */ - /*
*/ - /* cache_subsystem */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* FTC_SBit */ - /* */ - /* */ - /* A handle to a small bitmap descriptor. See the @FTC_SBitRec */ - /* structure for details. */ - /* */ - typedef struct FTC_SBitRec_* FTC_SBit; - - - /*************************************************************************/ - /* */ - /* */ - /* FTC_SBitRec */ - /* */ - /* */ - /* A very compact structure used to describe a small glyph bitmap. */ - /* */ - /* */ - /* width :: The bitmap width in pixels. */ - /* */ - /* height :: The bitmap height in pixels. */ - /* */ - /* left :: The horizontal distance from the pen position to the */ - /* left bitmap border (a.k.a. `left side bearing', or */ - /* `lsb'). */ - /* */ - /* top :: The vertical distance from the pen position (on the */ - /* baseline) to the upper bitmap border (a.k.a. `top */ - /* side bearing'). The distance is positive for upwards */ - /* Y coordinates. */ - /* */ - /* format :: The format of the glyph bitmap (monochrome or gray). */ - /* */ - /* max_grays :: Maximum gray level value (in the range 1 to 255). */ - /* */ - /* pitch :: The number of bytes per bitmap line. May be positive */ - /* or negative. */ - /* */ - /* xadvance :: The horizontal advance width in pixels. */ - /* */ - /* yadvance :: The vertical advance height in pixels. */ - /* */ - /* buffer :: A pointer to the bitmap pixels. */ - /* */ - typedef struct FTC_SBitRec_ + typedef struct FTC_SNodeRec_ { - FT_Byte width; - FT_Byte height; - FT_Char left; - FT_Char top; + FTC_GNodeRec gnode; + FT_UInt count; + FTC_SBitRec sbits[FTC_SBIT_ITEMS_PER_NODE]; - FT_Byte format; - FT_Byte max_grays; - FT_Short pitch; - FT_Char xadvance; - FT_Char yadvance; - - FT_Byte* buffer; - - } FTC_SBitRec; + } FTC_SNodeRec, *FTC_SNode; - /*************************************************************************/ - /* */ - /* */ - /* FTC_SBitCache */ - /* */ - /* */ - /* A handle to a small bitmap cache. These are special cache objects */ - /* used to store small glyph bitmaps (and anti-aliased pixmaps) in a */ - /* much more efficient way than the traditional glyph image cache */ - /* implemented by @FTC_ImageCache. */ - /* */ - typedef struct FTC_SBitCacheRec_* FTC_SBitCache; +#define FTC_SNODE( x ) ( (FTC_SNode)( x ) ) +#define FTC_SNODE_GINDEX( x ) FTC_GNODE( x )->gindex +#define FTC_SNODE_FAMILY( x ) FTC_GNODE( x )->family + + typedef FT_UInt + (*FTC_SFamily_GetCountFunc)( FTC_Family family, + FTC_Manager manager ); + + typedef FT_Error + (*FTC_SFamily_LoadGlyphFunc)( FTC_Family family, + FT_UInt gindex, + FTC_Manager manager, + FT_Face *aface ); + + typedef struct FTC_SFamilyClassRec_ + { + FTC_MruListClassRec clazz; + FTC_SFamily_GetCountFunc family_get_count; + FTC_SFamily_LoadGlyphFunc family_load_glyph; + + } FTC_SFamilyClassRec; + + typedef const FTC_SFamilyClassRec* FTC_SFamilyClass; + +#define FTC_SFAMILY_CLASS( x ) ((FTC_SFamilyClass)(x)) + +#define FTC_CACHE__SFAMILY_CLASS( x ) \ + FTC_SFAMILY_CLASS( FTC_CACHE__GCACHE_CLASS( x )->family_class ) - /*************************************************************************/ - /* */ - /* */ - /* FTC_SBit_Cache */ - /* */ - /* */ - /* DEPRECATED. Use @FTC_SBitCache instead. */ - /* */ - typedef FTC_SBitCache FTC_SBit_Cache; + FT_EXPORT( void ) + FTC_SNode_Free( FTC_SNode snode, + FTC_Cache cache ); - - /*************************************************************************/ - /* */ - /* */ - /* FTC_SBitCache_New */ - /* */ - /* */ - /* Creates a new cache to store small glyph bitmaps. */ - /* */ - /* */ - /* manager :: A handle to the source cache manager. */ - /* */ - /* */ - /* acache :: A handle to the new sbit cache. NULL in case of error. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ FT_EXPORT( FT_Error ) - FTC_SBitCache_New( FTC_Manager manager, - FTC_SBitCache *acache ); + FTC_SNode_New( FTC_SNode *psnode, + FTC_GQuery gquery, + FTC_Cache cache ); + + FT_EXPORT( FT_ULong ) + FTC_SNode_Weight( FTC_SNode inode ); - /*************************************************************************/ - /* */ - /* */ - /* FTC_SBitCache_Lookup */ - /* */ - /* */ - /* Looks up a given small glyph bitmap in a given sbit cache and */ - /* "lock" it to prevent its flushing from the cache until needed */ - /* */ - /* */ - /* cache :: A handle to the source sbit cache. */ - /* */ - /* type :: A pointer to the glyph image type descriptor. */ - /* */ - /* gindex :: The glyph index. */ - /* */ - /* */ - /* sbit :: A handle to a small bitmap descriptor. */ - /* */ - /* anode :: Used to return the address of of the corresponding cache */ - /* node after incrementing its reference count (see note */ - /* below). */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The small bitmap descriptor and its bit buffer are owned by the */ - /* cache and should never be freed by the application. They might */ - /* as well disappear from memory on the next cache lookup, so don't */ - /* treat them as persistent data. */ - /* */ - /* The descriptor's `buffer' field is set to 0 to indicate a missing */ - /* glyph bitmap. */ - /* */ - /* If "anode" is _not_ NULL, it receives the address of the cache */ - /* node containing the bitmap, after increasing its reference count. */ - /* This ensures that the node (as well as the image) will always be */ - /* kept in the cache until you call @FTC_Node_Unref to "release" it. */ - /* */ - /* If "anode" is NULL, the cache node is left unchanged, which means */ - /* that the bitmap could be flushed out of the cache on the next */ - /* call to one of the caching sub-system APIs. Don't assume that it */ - /* is persistent! */ - /* */ - FT_EXPORT( FT_Error ) - FTC_SBitCache_Lookup( FTC_SBitCache cache, - FTC_ImageType type, - FT_UInt gindex, - FTC_SBit *sbit, - FTC_Node *anode ); - + FT_EXPORT( FT_Bool ) + FTC_SNode_Compare( FTC_SNode snode, + FTC_GQuery gquery, + FTC_Cache cache ); /* */ - - /*************************************************************************/ - /* */ - /* */ - /* FTC_SBit_Cache_New */ - /* */ - /* */ - /* DEPRECATED. Use @FTC_SBitCache_New instead. */ - /* */ - /* Creates a new cache to store small glyph bitmaps. */ - /* */ - /* */ - /* manager :: A handle to the source cache manager. */ - /* */ - /* */ - /* acache :: A handle to the new sbit cache. NULL in case of error. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT( FT_Error ) - FTC_SBit_Cache_New( FTC_Manager manager, - FTC_SBit_Cache *acache ); - - - /*************************************************************************/ - /* */ - /* */ - /* FTC_SBit_Cache_Lookup */ - /* */ - /* */ - /* DEPRECATED. Use @FTC_SBitCache_Lookup instead. */ - /* */ - /* Looks up a given small glyph bitmap in a given sbit cache. */ - /* */ - /* */ - /* cache :: A handle to the source sbit cache. */ - /* */ - /* desc :: A pointer to the glyph image descriptor. */ - /* */ - /* gindex :: The glyph index. */ - /* */ - /* */ - /* sbit :: A handle to a small bitmap descriptor. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The small bitmap descriptor and its bit buffer are owned by the */ - /* cache and should never be freed by the application. They might */ - /* as well disappear from memory on the next cache lookup, so don't */ - /* treat them as persistent data. */ - /* */ - /* The descriptor's `buffer' field is set to 0 to indicate a missing */ - /* glyph bitmap. */ - /* */ - FT_EXPORT( FT_Error ) - FTC_SBit_Cache_Lookup( FTC_SBit_Cache cache, - FTC_Image_Desc* desc, - FT_UInt gindex, - FTC_SBit *sbit ); - - FT_END_HEADER #endif /* __FTCSBITS_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/cache/ftlru.h b/headers/libs/freetype2/freetype/cache/ftlru.h deleted file mode 100644 index 5b957488e0..0000000000 --- a/headers/libs/freetype2/freetype/cache/ftlru.h +++ /dev/null @@ -1,202 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftlru.h */ -/* */ -/* Simple LRU list-cache (specification). */ -/* */ -/* Copyright 2000-2001 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* An LRU is a list that cannot hold more than a certain number of */ - /* elements (`max_elements'). All elements in the list are sorted in */ - /* least-recently-used order, i.e., the `oldest' element is at the tail */ - /* of the list. */ - /* */ - /* When doing a lookup (either through `Lookup()' or `Lookup_Node()'), */ - /* the list is searched for an element with the corresponding key. If */ - /* it is found, the element is moved to the head of the list and is */ - /* returned. */ - /* */ - /* If no corresponding element is found, the lookup routine will try to */ - /* obtain a new element with the relevant key. If the list is already */ - /* full, the oldest element from the list is discarded and replaced by a */ - /* new one; a new element is added to the list otherwise. */ - /* */ - /* Note that it is possible to pre-allocate the element list nodes. */ - /* This is handy if `max_elements' is sufficiently small, as it saves */ - /* allocations/releases during the lookup process. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********* *********/ - /********* WARNING, THIS IS BETA CODE. *********/ - /********* *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - -#ifndef __FTLRU_H__ -#define __FTLRU_H__ - - -#include -#include FT_FREETYPE_H - - -FT_BEGIN_HEADER - - - /* generic list key type */ - typedef FT_Pointer FT_LruKey; - - /* a list list handle */ - typedef struct FT_LruListRec_* FT_LruList; - - /* a list class handle */ - typedef const struct FT_LruList_ClassRec_* FT_LruList_Class; - - /* a list node handle */ - typedef struct FT_LruNodeRec_* FT_LruNode; - - /* the list node structure */ - typedef struct FT_LruNodeRec_ - { - FT_LruNode next; - FT_LruKey key; - - } FT_LruNodeRec; - - - /* the list structure */ - typedef struct FT_LruListRec_ - { - FT_Memory memory; - FT_LruList_Class clazz; - FT_LruNode nodes; - FT_UInt max_nodes; - FT_UInt num_nodes; - FT_Pointer data; - - } FT_LruListRec; - - - /* initialize a list list */ - typedef FT_Error - (*FT_LruList_InitFunc)( FT_LruList list ); - - /* finalize a list list */ - typedef void - (*FT_LruList_DoneFunc)( FT_LruList list ); - - /* this method is used to initialize a new list element node */ - typedef FT_Error - (*FT_LruNode_InitFunc)( FT_LruNode node, - FT_LruKey key, - FT_Pointer data ); - - /* this method is used to finalize a given list element node */ - typedef void - (*FT_LruNode_DoneFunc)( FT_LruNode node, - FT_Pointer data ); - - /* If defined, this method is called when the list if full */ - /* during the lookup process -- it is used to change the contents */ - /* of a list element node instead of calling `done_element()', */ - /* then `init_element()'. Set it to 0 for default behaviour. */ - typedef FT_Error - (*FT_LruNode_FlushFunc)( FT_LruNode node, - FT_LruKey new_key, - FT_Pointer data ); - - /* If defined, this method is used to compare a list element node */ - /* with a given key during a lookup. If set to 0, the `key' */ - /* fields will be directly compared instead. */ - typedef FT_Bool - (*FT_LruNode_CompareFunc)( FT_LruNode node, - FT_LruKey key, - FT_Pointer data ); - - /* A selector is used to indicate whether a given list element node */ - /* is part of a selection for FT_LruList_Remove_Selection(). The */ - /* functrion must return true (i.e., non-null) to indicate that the */ - /* node is part of it. */ - typedef FT_Bool - (*FT_LruNode_SelectFunc)( FT_LruNode node, - FT_Pointer data, - FT_Pointer list_data ); - - /* LRU class */ - typedef struct FT_LruList_ClassRec_ - { - FT_UInt list_size; - FT_LruList_InitFunc list_init; /* optional */ - FT_LruList_DoneFunc list_done; /* optional */ - - FT_UInt node_size; - FT_LruNode_InitFunc node_init; /* MANDATORY */ - FT_LruNode_DoneFunc node_done; /* optional */ - FT_LruNode_FlushFunc node_flush; /* optional */ - FT_LruNode_CompareFunc node_compare; /* optional */ - - } FT_LruList_ClassRec; - - - /* The following functions must be exported in the case where */ - /* applications would want to write their own cache classes. */ - - FT_EXPORT( FT_Error ) - FT_LruList_New( FT_LruList_Class clazz, - FT_UInt max_elements, - FT_Pointer user_data, - FT_Memory memory, - FT_LruList *alist ); - - FT_EXPORT( void ) - FT_LruList_Reset( FT_LruList list ); - - FT_EXPORT( void ) - FT_LruList_Destroy ( FT_LruList list ); - - FT_EXPORT( FT_Error ) - FT_LruList_Lookup( FT_LruList list, - FT_LruKey key, - FT_LruNode *anode ); - - FT_EXPORT( void ) - FT_LruList_Remove( FT_LruList list, - FT_LruNode node ); - - FT_EXPORT( void ) - FT_LruList_Remove_Selection( FT_LruList list, - FT_LruNode_SelectFunc select_func, - FT_Pointer select_data ); - - /* */ - -FT_END_HEADER - - -#endif /* __FTLRU_H__ */ - - -/* END */ diff --git a/headers/libs/freetype2/freetype/config/ftconfig.h b/headers/libs/freetype2/freetype/config/ftconfig.h index 27f9d7fefb..4bd8cf6174 100644 --- a/headers/libs/freetype2/freetype/config/ftconfig.h +++ b/headers/libs/freetype2/freetype/config/ftconfig.h @@ -4,7 +4,7 @@ /* */ /* ANSI-specific configuration file (specification only). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -58,24 +58,37 @@ FT_BEGIN_HEADER /*************************************************************************/ - /* The number of bytes in an `int' type. */ -#if FT_UINT_MAX == 0xFFFFFFFFUL -#define FT_SIZEOF_INT 4 -#elif FT_UINT_MAX == 0xFFFFU -#define FT_SIZEOF_INT 2 -#elif FT_UINT_MAX > 0xFFFFFFFFU && FT_UINT_MAX == 0xFFFFFFFFFFFFFFFFU -#define FT_SIZEOF_INT 8 -#else -#error "Unsupported number of bytes in `int' type!" + /* There are systems (like the Texas Instruments 'C54x) where a `char' */ + /* has 16 bits. ANSI C says that sizeof(char) is always 1. Since an */ + /* `int' has 16 bits also for this system, sizeof(int) gives 1 which */ + /* is probably unexpected. */ + /* */ + /* `CHAR_BIT' (defined in limits.h) gives the number of bits in a */ + /* `char' type. */ + +#ifndef FT_CHAR_BIT +#define FT_CHAR_BIT CHAR_BIT #endif - /* The number of bytes in a `long' type. */ -#if FT_ULONG_MAX == 0xFFFFFFFFUL -#define FT_SIZEOF_LONG 4 -#elif FT_ULONG_MAX > 0xFFFFFFFFU && FT_ULONG_MAX == 0xFFFFFFFFFFFFFFFFU -#define FT_SIZEOF_LONG 8 + + /* The size of an `int' type. */ +#if FT_UINT_MAX == 0xFFFFFFFFUL +#define FT_SIZEOF_INT (32 / FT_CHAR_BIT) +#elif FT_UINT_MAX == 0xFFFFU +#define FT_SIZEOF_INT (16 / FT_CHAR_BIT) +#elif FT_UINT_MAX > 0xFFFFFFFFU && FT_UINT_MAX == 0xFFFFFFFFFFFFFFFFU +#define FT_SIZEOF_INT (64 / FT_CHAR_BIT) #else -#error "Unsupported number of bytes in `long' type!" +#error "Unsupported size of `int' type!" +#endif + + /* The size of a `long' type. */ +#if FT_ULONG_MAX == 0xFFFFFFFFUL +#define FT_SIZEOF_LONG (32 / FT_CHAR_BIT) +#elif FT_ULONG_MAX > 0xFFFFFFFFU && FT_ULONG_MAX == 0xFFFFFFFFFFFFFFFFU +#define FT_SIZEOF_LONG (64 / FT_CHAR_BIT) +#else +#error "Unsupported size of `long' type!" #endif @@ -108,7 +121,8 @@ FT_BEGIN_HEADER /* This is the only necessary change, so it is defined here instead */ /* providing a new configuration file. */ /* */ -#if defined( __APPLE__ ) || ( defined( __MWERKS__ ) && defined( macintosh ) ) +#if ( defined( __APPLE__ ) && !defined( DARWIN_NO_CARBON ) ) || \ + ( defined( __MWERKS__ ) && defined( macintosh ) ) #define FT_MACINTOSH 1 #endif @@ -122,12 +136,12 @@ FT_BEGIN_HEADER typedef signed short FT_Int16; typedef unsigned short FT_UInt16; -#if FT_SIZEOF_INT == 4 +#if FT_SIZEOF_INT == (32 / FT_CHAR_BIT) typedef signed int FT_Int32; typedef unsigned int FT_UInt32; -#elif FT_SIZEOF_LONG == 4 +#elif FT_SIZEOF_LONG == (32 / FT_CHAR_BIT) typedef signed long FT_Int32; typedef unsigned long FT_UInt32; @@ -136,13 +150,13 @@ FT_BEGIN_HEADER #error "no 32bit type found -- please check your configuration files" #endif - /* now, lookup for an integer type that is at least 32 bits */ -#if FT_SIZEOF_INT >= 4 + /* look up an integer type that is at least 32 bits */ +#if FT_SIZEOF_INT >= (32 / FT_CHAR_BIT) typedef int FT_Fast; typedef unsigned int FT_UFast; -#elif FT_SIZEOF_LONG >= 4 +#elif FT_SIZEOF_LONG >= (32 / FT_CHAR_BIT) typedef long FT_Fast; typedef unsigned long FT_UFast; @@ -152,7 +166,7 @@ FT_BEGIN_HEADER /* determine whether we have a 64-bit int type for platforms without */ /* Autoconf */ -#if FT_SIZEOF_LONG == 8 +#if FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) /* FT_LONG64 must be defined if a 64-bit type is available */ #define FT_LONG64 @@ -177,10 +191,10 @@ FT_BEGIN_HEADER /* Watcom doesn't provide 64-bit data types */ -#elif defined( __MWKS__ ) /* Metrowerks CodeWarrior */ +#elif defined( __MWERKS__ ) /* Metrowerks CodeWarrior */ - /* I don't know if it provides 64-bit data types, any suggestion */ - /* is welcome. */ +#define FT_LONG64 +#define FT_INT64 long long int #elif defined( __GNUC__ ) @@ -188,7 +202,12 @@ FT_BEGIN_HEADER #define FT_LONG64 #define FT_INT64 long long int -#endif /* FT_SIZEOF_LONG == 8 */ +#endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */ + + +#define FT_BEGIN_STMNT do { +#define FT_END_STMNT } while ( 0 ) +#define FT_DUMMY_STMNT FT_BEGIN_STMNT FT_END_STMNT /*************************************************************************/ @@ -331,4 +350,4 @@ FT_END_HEADER #endif /* __FTCONFIG_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/config/ftheader.h b/headers/libs/freetype2/freetype/config/ftheader.h index bb18eb5a89..b996a7a6fb 100644 --- a/headers/libs/freetype2/freetype/config/ftheader.h +++ b/headers/libs/freetype2/freetype/config/ftheader.h @@ -4,7 +4,7 @@ /* */ /* Build macros of the FreeType 2 library. */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -150,6 +150,7 @@ #define FT_CONFIG_MODULES_H #endif + /* public headers */ /*************************************************************************/ @@ -281,7 +282,7 @@ /* A macro used in #include statements to name the file containing */ /* the module management API of FreeType 2. */ /* */ -#define FT_MODULE_H +#define FT_MODULE_H /*************************************************************************/ @@ -373,6 +374,18 @@ #define FT_GZIP_H + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_LZW_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the definitions of an API to support for LZW-compressed files. */ + /* */ +#define FT_LZW_H + + /*************************************************************************/ /* */ /* @macro: */ @@ -384,6 +397,7 @@ /* */ #define FT_WINFONTS_H + /*************************************************************************/ /* */ /* @macro: */ @@ -433,7 +447,10 @@ /* see the API defined in @FT_CACHE_SMALL_BITMAPS_H if you only need */ /* to store small glyph bitmaps, as it will use less memory. */ /* */ -#define FT_CACHE_IMAGE_H + /* This macro is deprecated. Simply include @FT_CACHE_H to have all */ + /* glyph image-related cache declarations. */ + /* */ +#define FT_CACHE_IMAGE_H FT_CACHE_H /*************************************************************************/ @@ -450,7 +467,10 @@ /* in @FT_CACHE_IMAGE_H if you want to cache arbitrary glyph images, */ /* including scalable outlines. */ /* */ -#define FT_CACHE_SMALL_BITMAPS_H + /* This macro is deprecated. Simply include @FT_CACHE_H to have all */ + /* small bitmaps-related cache declarations. */ + /* */ +#define FT_CACHE_SMALL_BITMAPS_H FT_CACHE_H /*************************************************************************/ @@ -462,7 +482,10 @@ /* A macro used in #include statements to name the file containing */ /* the `charmap' API of the FreeType 2 cache sub-system. */ /* */ -#define FT_CACHE_CHARMAP_H + /* This macro is deprecated. Simply include @FT_CACHE_H to have all */ + /* charmap-based cache declarations. */ + /* */ +#define FT_CACHE_CHARMAP_H FT_CACHE_H /*************************************************************************/ @@ -508,28 +531,34 @@ /* */ -#define FT_TRIGONOMETRY_H -#define FT_STROKER_H -#define FT_SYNTHESIS_H -#define FT_ERROR_DEFINITIONS_H +#define FT_TRIGONOMETRY_H +#define FT_STROKER_H +#define FT_SYNTHESIS_H +#define FT_ERROR_DEFINITIONS_H -#define FT_CACHE_MANAGER_H +#define FT_CACHE_MANAGER_H -#define FT_CACHE_INTERNAL_LRU_H -#define FT_CACHE_INTERNAL_GLYPH_H -#define FT_CACHE_INTERNAL_CACHE_H +#define FT_CACHE_INTERNAL_MRU_H +#define FT_CACHE_INTERNAL_MANAGER_H +#define FT_CACHE_INTERNAL_CACHE_H +#define FT_CACHE_INTERNAL_GLYPH_H +#define FT_CACHE_INTERNAL_IMAGE_H +#define FT_CACHE_INTERNAL_SBITS_H -#define FT_XFREE86_H -#define FT_INCREMENTAL_H +#define FT_XFREE86_H + +#define FT_INCREMENTAL_H + +#define FT_TRUETYPE_UNPATENTED_H /* now include internal headers definitions from */ -#define FT_INTERNAL_INTERNAL_H +#define FT_INTERNAL_INTERNAL_H #include FT_INTERNAL_INTERNAL_H #endif /* __FT2_BUILD_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/config/ftmodule.h b/headers/libs/freetype2/freetype/config/ftmodule.h index 3e7d9e6ea5..d0e6f16a3c 100644 --- a/headers/libs/freetype2/freetype/config/ftmodule.h +++ b/headers/libs/freetype2/freetype/config/ftmodule.h @@ -16,4 +16,4 @@ FT_USE_MODULE(t1_driver_class) FT_USE_MODULE(t42_driver_class) FT_USE_MODULE(pfr_driver_class) FT_USE_MODULE(winfnt_driver_class) - + diff --git a/headers/libs/freetype2/freetype/config/ftoption.h b/headers/libs/freetype2/freetype/config/ftoption.h index 9ce528d9b0..a527ec12d1 100644 --- a/headers/libs/freetype2/freetype/config/ftoption.h +++ b/headers/libs/freetype2/freetype/config/ftoption.h @@ -4,7 +4,7 @@ /* */ /* User-selectable configuration macros (specification only). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -81,32 +81,46 @@ FT_BEGIN_HEADER /* by FreeType to speed up some computations. However, this will create */ /* some problems when compiling the library in strict ANSI mode. */ /* */ - /* For this reason, the use of 64-bit ints is normally disabled when */ + /* For this reason, the use of 64-bit integers is normally disabled when */ /* the __STDC__ macro is defined. You can however disable this by */ - /* defining here the macro FT_CONFIG_OPTION_FORCE_INT64. */ + /* defining the macro FT_CONFIG_OPTION_FORCE_INT64 here. */ /* */ - /* For most compilers, this will only create compilation warnings */ - /* when building the library. */ + /* For most compilers, this will only create compilation warnings when */ + /* building the library. */ /* */ /* ObNote: The compiler-specific 64-bit integers are detected in the */ - /* file "ftconfig.h" either statically, or through Autoconf */ - /* on platforms that support it. */ + /* file "ftconfig.h" either statically or through the */ + /* `configure' script on supported platforms. */ /* */ #undef FT_CONFIG_OPTION_FORCE_INT64 + /*************************************************************************/ + /* */ + /* LZW-compressed file support. */ + /* */ + /* FreeType now handles font files that have been compressed with the */ + /* 'compress' program. This is mostly used to parse many of the PCF */ + /* files that come with various X11 distributions. The implementation */ + /* uses NetBSD's `zopen' to partially uncompress the file on the fly */ + /* (see src/lzw/ftgzip.c). */ + /* */ + /* Define this macro if you want to enable this `feature'. */ + /* */ +#define FT_CONFIG_OPTION_USE_LZW + + /*************************************************************************/ /* */ /* Gzip-compressed file support. */ /* */ /* FreeType now handles font files that have been compressed with the */ - /* 'gzip' program. This is mostly used to parse many of the PCF files */ - /* that come with XFree86. The implementation uses 'zlib' to */ - /* partially uncompress the file on the fly (see src/base/ftgzip.c). */ + /* 'gzip' program. This is mostly used to parse many of the PCF files */ + /* that come with XFree86. The implementation uses `zlib' to */ + /* partially uncompress the file on the fly (see src/gzip/ftgzip.c). */ /* */ - /* Define this macro if you want to enable this "feature". Note that */ - /* this will however force you to link the zlib to any program that */ - /* also uses FreeType. */ + /* Define this macro if you want to enable this `feature'. See also */ + /* the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below. */ /* */ #define FT_CONFIG_OPTION_USE_ZLIB @@ -116,18 +130,18 @@ FT_BEGIN_HEADER /* ZLib library selection */ /* */ /* This macro is only used when FT_CONFIG_OPTION_USE_ZLIB is defined. */ - /* It allows FreeType's "ftgzip" component to link to the system's */ - /* installation of the ZLib library. This is useful on systems like */ + /* It allows FreeType's `ftgzip' component to link to the system's */ + /* installation of the ZLib library. This is useful on systems like */ /* Unix or VMS where it generally is already available. */ /* */ /* If you let it undefined, the component will use its own copy */ - /* of the zlib sources instead. These have been modified to be */ + /* of the zlib sources instead. These have been modified to be */ /* included directly within the component and *not* export external */ - /* function names. This allows you to link any program with FreeType */ + /* function names. This allows you to link any program with FreeType */ /* _and_ ZLib without linking conflicts. */ /* */ - /* do not #undef this macro here, since the build system might */ - /* define for certain configurations */ + /* Do not #undef this macro here since the build system might define */ + /* it for certain configurations only. */ /* */ /* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */ @@ -167,6 +181,9 @@ FT_BEGIN_HEADER /* will be later automatically defined as `extern return_type' to */ /* allow normal compilation. */ /* */ + /* Do not #undef these macros here since the build system might define */ + /* them for certain configurations only. */ + /* */ /* #define FT_EXPORT(x) extern x */ /* #define FT_EXPORT_DEF(x) x */ @@ -214,6 +231,42 @@ FT_BEGIN_HEADER #define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST + /*************************************************************************/ + /* */ + /* Support for Mac fonts */ + /* */ + /* Define this macro if you want support for outline fonts in Mac */ + /* format (mac dfont, mac resource, macbinary containing a mac */ + /* resource) on non-Mac platforms. */ + /* */ + /* Note that the `FOND' resource isn't checked. */ + /* */ +#define FT_CONFIG_OPTION_MAC_FONTS + + + /*************************************************************************/ + /* */ + /* Guessing methods to access embedded resource forks */ + /* */ + /* Enable extra Mac fonts support on non-Mac platforms (e.g. */ + /* GNU/Linux). */ + /* */ + /* Resource forks which include fonts data are stored sometimes in */ + /* locations which users or developers don't expected. In some cases, */ + /* resource forks start with some offset from the head of a file. In */ + /* other cases, the actual resource fork is stored in file different */ + /* from what the user specifies. If this option is activated, */ + /* FreeType tries to guess whether such offsets or different file */ + /* names must be used. */ + /* */ + /* Note that normal, direct access of resource forks is controlled via */ + /* the FT_CONFIG_OPTION_MAC_FONTS option. */ + /* */ +#ifdef FT_CONFIG_OPTION_MAC_FONTS +#define FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK +#endif + + /*************************************************************************/ /* */ /* Allow the use of FT_Incremental_Interface to load typefaces that */ @@ -221,7 +274,7 @@ FT_BEGIN_HEADER /* This allows FreeType to be used with the PostScript language, using */ /* the GhostScript interpreter. */ /* */ -/* #define FT_CONFIG_OPTION_INCREMENTAL */ +/* #define FT_CONFIG_OPTION_INCREMENTAL */ /*************************************************************************/ @@ -229,7 +282,7 @@ FT_BEGIN_HEADER /* The size in bytes of the render pool used by the scan-line converter */ /* to do all of its work. */ /* */ - /* This must be greater than 4kByte. */ + /* This must be greater than 4KByte. */ /* */ #define FT_RENDER_POOL_SIZE 16384L @@ -258,8 +311,11 @@ FT_BEGIN_HEADER /* */ /* Don't define any of these macros to compile in `release' mode! */ /* */ -/* #define FT_DEBUG_LEVEL_ERROR */ -/* #define FT_DEBUG_LEVEL_TRACE */ + /* Do not #undef these macros here since the build system might define */ + /* them for certain configurations only. */ + /* */ +/* #define FT_DEBUG_LEVEL_ERROR */ +/* #define FT_DEBUG_LEVEL_TRACE */ /*************************************************************************/ @@ -272,10 +328,12 @@ FT_BEGIN_HEADER /* should define FT_DEBUG_MEMORY here. */ /* */ /* Note that the memory debugger is only activated at runtime when */ - /* when the _environment_ variable "FT_DEBUG_MEMORY" is also defined! */ + /* when the _environment_ variable "FT2_DEBUG_MEMORY" is defined also! */ /* */ -/* #define FT_DEBUG_MEMORY */ - + /* Do not #undef this macro here since the build system might define */ + /* it for certain configurations only. */ + /* */ +/* #define FT_DEBUG_MEMORY */ /*************************************************************************/ @@ -375,12 +433,24 @@ FT_BEGIN_HEADER /* By undefining this, you will only compile the code necessary to load */ /* TrueType glyphs without hinting. */ /* */ - /* do not #undef this macro here, since the build system might */ - /* define for certain configurations */ + /* Do not #undef this macro here, since the build system might */ + /* define it for certain configurations only. */ /* */ /* #define TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_UNPATENTED_HINTING (in addition to */ + /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER) to compile the unpatented */ + /* work-around hinting system. Note that for the moment, the algorithm */ + /* is only used when selected at runtime through the parameter tag */ + /* FT_PARAM_TAG_UNPATENTED_HINTING; or when the debug hook */ + /* FT_DEBUG_HOOK_UNPATENTED_HINTING is globally actived */ + /* */ +#define TT_CONFIG_OPTION_UNPATENTED_HINTING + + /*************************************************************************/ /* */ /* Define TT_CONFIG_OPTION_INTERPRETER_SWITCH to compile the TrueType */ @@ -470,21 +540,21 @@ FT_BEGIN_HEADER /* */ /* - * the FT_CONFIG_OPTION_CHESTER_XXXX macros are used to toggle some recent - * improvements to the auto-hinter contributed by David Chester. They will - * most likely disappear completely in the next release. For now, you should - * always keep them defined + * The FT_CONFIG_OPTION_CHESTER_XXXX macros are used to toggle some recent + * improvements to the auto-hinter contributed by David Chester. They will + * most likely disappear completely in the next release. For now, you + * should always keep them defined. * */ #define FT_CONFIG_OPTION_CHESTER_HINTS #ifdef FT_CONFIG_OPTION_CHESTER_HINTS -# define FT_CONFIG_CHESTER_SMALL_F -# define FT_CONFIG_CHESTER_ASCENDER -# define FT_CONFIG_CHESTER_SERIF -# define FT_CONFIG_CHESTER_STEM -# define FT_CONFIG_CHESTER_BLUE_SCALE +#define FT_CONFIG_CHESTER_SMALL_F +#define FT_CONFIG_CHESTER_ASCENDER +#define FT_CONFIG_CHESTER_SERIF +#define FT_CONFIG_CHESTER_STEM +#define FT_CONFIG_CHESTER_BLUE_SCALE #endif /* FT_CONFIG_OPTION_CHESTER_HINTS */ @@ -494,4 +564,4 @@ FT_END_HEADER #endif /* __FTOPTION_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/config/ftstdlib.h b/headers/libs/freetype2/freetype/config/ftstdlib.h index b2bba62c5a..297d6f0175 100644 --- a/headers/libs/freetype2/freetype/config/ftstdlib.h +++ b/headers/libs/freetype2/freetype/config/ftstdlib.h @@ -5,7 +5,7 @@ /* ANSI-specific library and header configuration file (specification */ /* only). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -73,23 +73,27 @@ #include -#define ft_isalnum isalnum -#define ft_isupper isupper -#define ft_islower islower -#define ft_xdigit isxdigit +#define ft_isalnum isalnum +#define ft_isupper isupper +#define ft_islower islower +#define ft_isdigit isdigit +#define ft_isxdigit isxdigit #include -#define ft_strlen strlen -#define ft_strcmp strcmp -#define ft_strncmp strncmp -#define ft_memcpy memcpy -#define ft_strcpy strcpy -#define ft_strncpy strncpy -#define ft_memset memset -#define ft_memmove memmove #define ft_memcmp memcmp +#define ft_memcpy memcpy +#define ft_memmove memmove +#define ft_memset memset +#define ft_strcat strcat +#define ft_strcmp strcmp +#define ft_strcpy strcpy +#define ft_strlen strlen +#define ft_strncmp strncmp +#define ft_strncpy strncpy +#define ft_strrchr strrchr + #include @@ -108,7 +112,7 @@ #define ft_qsort qsort #define ft_exit exit /* only used to exit from unhandled exceptions */ -#define ft_atoi atoi +#define ft_atol atol /**********************************************************************/ @@ -137,4 +141,4 @@ #endif /* __FTSTDLIB_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/freetype.h b/headers/libs/freetype2/freetype/freetype.h index e56a194c7b..6acf166119 100644 --- a/headers/libs/freetype2/freetype/freetype.h +++ b/headers/libs/freetype2/freetype/freetype.h @@ -4,7 +4,7 @@ /* */ /* FreeType high-level API and common types (specification only). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,6 +16,15 @@ /***************************************************************************/ +#ifndef FT_FREETYPE_H +#error "`ft2build.h' hasn't been included yet!" +#error "Please always use macros to include FreeType header files." +#error "Example:" +#error " #include " +#error " #include FT_FREETYPE_H" +#endif + + #ifndef __FREETYPE_H__ #define __FREETYPE_H__ @@ -35,7 +44,7 @@ /* */ #define FREETYPE_MAJOR 2 #define FREETYPE_MINOR 1 -#define FREETYPE_PATCH 4 +#define FREETYPE_PATCH 8 #include @@ -113,7 +122,6 @@ FT_BEGIN_HEADER /* FT_New_Memory_Face */ /* FT_Open_Face */ /* FT_Open_Args */ - /* FT_Open_Flags */ /* FT_Parameter */ /* FT_Attach_File */ /* FT_Attach_Stream */ @@ -126,6 +134,12 @@ FT_BEGIN_HEADER /* FT_Get_Name_Index */ /* FT_Load_Char */ /* */ + /* FT_OPEN_MEMORY */ + /* FT_OPEN_STREAM */ + /* FT_OPEN_PATHNAME */ + /* FT_OPEN_DRIVER */ + /* FT_OPEN_PARAMS */ + /* */ /* FT_LOAD_DEFAULT */ /* FT_LOAD_RENDER */ /* FT_LOAD_MONOCHROME */ @@ -142,6 +156,12 @@ FT_BEGIN_HEADER /* FT_LOAD_NO_RECURSE */ /* FT_LOAD_PEDANTIC */ /* */ + /* FT_LOAD_TARGET_NORMAL */ + /* FT_LOAD_TARGET_LIGHT */ + /* FT_LOAD_TARGET_MONO */ + /* FT_LOAD_TARGET_LCD */ + /* FT_LOAD_TARGET_LCD_V */ + /* */ /* FT_Render_Glyph */ /* FT_Render_Mode */ /* FT_Get_Kerning */ @@ -162,9 +182,10 @@ FT_BEGIN_HEADER /* FT_Glyph_Metrics */ /* */ /* */ - /* A structure used to model the metrics of a single glyph. Note */ - /* that values are expressed in 26.6 fractional pixel format or in */ - /* font units, depending on context. */ + /* A structure used to model the metrics of a single glyph. The */ + /* values are expressed in 26.6 fractional pixel format; if the flag */ + /* FT_LOAD_NO_SCALE is used, values are returned in font units */ + /* instead. */ /* */ /* */ /* width :: The glyph's width. */ @@ -205,21 +226,62 @@ FT_BEGIN_HEADER /* FT_Bitmap_Size */ /* */ /* */ - /* An extremely simple structure used to model the size of a bitmap */ - /* strike (i.e., a bitmap instance of the font for a given */ - /* resolution) in a fixed-size font face. This is used for the */ - /* `available_sizes' field of the FT_Face_Properties structure. */ + /* This structure models the size of a bitmap strike (i.e., a bitmap */ + /* instance of the font for a given resolution) in a fixed-size font */ + /* face. It is used for the `available_sizes' field of the */ + /* @FT_FaceRec structure. */ /* */ /* */ - /* height :: The character height in pixels. */ + /* height :: The (vertical) baseline-to-baseline distance in pixels. */ + /* It makes most sense to define the height of a bitmap */ + /* font in this way. */ /* */ - /* width :: The character width in pixels. */ + /* width :: The average width of the font (in pixels). Since the */ + /* algorithms to compute this value are different for the */ + /* various bitmap formats, it can only give an additional */ + /* hint if the `height' value isn't sufficient to select */ + /* the proper font. For monospaced fonts the average width */ + /* is the same as the maximum width. */ + /* */ + /* size :: The point size in 26.6 fractional format this font shall */ + /* represent (for a given vertical resolution). */ + /* */ + /* x_ppem :: The horizontal ppem value (in 26.6 fractional format). */ + /* */ + /* y_ppem :: The vertical ppem value (in 26.6 fractional format). */ + /* */ + /* */ + /* The values in this structure are taken from the bitmap font. If */ + /* the font doesn't provide a parameter it is set to zero to indicate */ + /* that the information is not available. */ + /* */ + /* The following formula converts from dpi to ppem: */ + /* */ + /* ppem = size * dpi / 72 */ + /* */ + /* where `size' is in points. */ + /* */ + /* Windows FNT: */ + /* The `size', `x_ppem', and `y_ppem' parameters are not reliable: */ + /* There exist fonts (e.g. app850.fon) which have a wrong size for */ + /* some subfonts; since FNT files don't contain ppem but dpi values */ + /* the computed x_ppem and y_ppem numbers are thus wrong also. */ + /* */ + /* TrueType embedded bitmaps: */ + /* `size', `width', and `height' values are not contained in the */ + /* bitmap strike itself. They are computed from the global font */ + /* parameters. */ /* */ typedef struct FT_Bitmap_Size_ { FT_Short height; FT_Short width; + FT_Pos size; + + FT_Pos x_ppem; + FT_Pos y_ppem; + } FT_Bitmap_Size; @@ -386,6 +448,10 @@ FT_BEGIN_HEADER /* @FT_Open_Face), the library looks for a Unicode charmap within */ /* the list and automatically activates it. */ /* */ + /* */ + /* The @FT_CharMapRec details the publicly accessible fields of a */ + /* given character map. */ + /* */ typedef struct FT_CharMapRec_* FT_CharMap; @@ -403,7 +469,7 @@ FT_BEGIN_HEADER /* should redefine this macro in case of problems to something like */ /* this: */ /* */ - /* #define FT_ENC_TAG( value, a, b, c, d ) (value) */ + /* #define FT_ENC_TAG( value, a, b, c, d ) value */ /* */ /* to get a simple enumeration without assigning special numbers. */ /* */ @@ -452,30 +518,28 @@ FT_BEGIN_HEADER /* mathematical symbols in the 32..255 character code range. For */ /* more information, see `http://www.ceviz.net/symbol.htm'. */ /* */ - /* FT_ENCODING_MS_SJIS :: */ - /* Corresponds to Microsoft's Japanese SJIS encoding. More info */ + /* FT_ENCODING_SJIS :: */ + /* Corresponds to Japanese SJIS encoding. More info at */ /* at `http://langsupport.japanreference.com/encoding.shtml'. */ /* See note on multi-byte encodings below. */ /* */ - /* FT_ENCODING_MS_GB2312 :: */ - /* Corresponds to the encoding system for Simplified Chinese, as */ - /* used in China. Only found in some TrueType fonts. */ + /* FT_ENCODING_GB2312 :: */ + /* Corresponds to an encoding system for Simplified Chinese as used */ + /* used in mainland China. */ /* */ - /* FT_ENCODING_MS_BIG5 :: */ - /* Corresponds to the encoding system for Traditional Chinese, as */ - /* used in Taiwan and Hong Kong. Only found in some TrueType fonts. */ + /* FT_ENCODING_BIG5 :: */ + /* Corresponds to an encoding system for Traditional Chinese as used */ + /* in Taiwan and Hong Kong. */ /* */ - /* FT_ENCODING_MS_WANSUNG :: */ + /* FT_ENCODING_WANSUNG :: */ /* Corresponds to the Korean encoding system known as Wansung. */ - /* This is a Microsoft encoding that is only found in some TrueType */ - /* fonts. For more information, see */ + /* For more information see */ /* `http://www.microsoft.com/typography/unicode/949.txt'. */ /* */ - /* FT_ENCODING_MS_JOHAB :: */ + /* FT_ENCODING_JOHAB :: */ /* The Korean standard character set (KS C-5601-1992), which */ - /* corresponds to Windows code page 1361. This character set */ + /* corresponds to MS Windows code page 1361. This character set */ /* includes all possible Hangeul character combinations. */ - /* Only found on some rare TrueType fonts. */ /* */ /* FT_ENCODING_ADOBE_LATIN_1 :: */ /* Corresponds to a Latin-1 encoding as defined in a Type 1 */ @@ -483,7 +547,7 @@ FT_BEGIN_HEADER /* */ /* FT_ENCODING_ADOBE_STANDARD :: */ /* Corresponds to the Adobe Standard encoding, as found in Type 1, */ - /* CFF, and OpenType/CFF fonts. It is limited to 256character */ + /* CFF, and OpenType/CFF fonts. It is limited to 256 character */ /* codes. */ /* */ /* FT_ENCODING_ADOBE_EXPERT :: */ @@ -504,6 +568,21 @@ FT_BEGIN_HEADER /* This value is deprecated and was never used nor reported by */ /* FreeType. Don't use or test for it. */ /* */ + /* FT_ENCODING_MS_SJIS :: */ + /* Same as FT_ENCODING_SJIS. Deprecated. */ + /* */ + /* FT_ENCODING_MS_GB2312 :: */ + /* Same as FT_ENCODING_GB2312. Deprecated. */ + /* */ + /* FT_ENCODING_MS_BIG5 :: */ + /* Same as FT_ENCODING_BIG5. Deprecated. */ + /* */ + /* FT_ENCODING_MS_WANSUNG :: */ + /* Same as FT_ENCODING_WANSUNG. Deprecated. */ + /* */ + /* FT_ENCODING_MS_JOHAB :: */ + /* Same as FT_ENCODING_JOHAB. Deprecated. */ + /* */ /* */ /* By default, FreeType automatically synthetizes a Unicode charmap */ /* for Postscript fonts, using their glyph names dictionaries. */ @@ -511,6 +590,37 @@ FT_BEGIN_HEADER /* the font file, for the cases when they are needed, with the Adobe */ /* values as well. */ /* */ + /* FT_ENCODING_NONE is set by the BDF and PCF drivers if the charmap */ + /* is neither Unicode nor ISO-8859-1 (otherwise it is set to */ + /* FT_ENCODING_UNICODE). Use `FT_Get_BDF_Charset_ID' to find out */ + /* which encoding is really present. If, for example, the */ + /* `cs_registry' field is `KOI8' and the `cs_encoding' field is `R', */ + /* the font is encoded in KOI8-R. */ + /* */ + /* FT_ENCODING_NONE is always set (with a single exception) by the */ + /* winfonts driver. Use `FT_Get_WinFNT_Header' and examine the */ + /* `charset' field of the `FT_WinFNT_HeaderRec' structure to find out */ + /* which encoding is really present. For example, FT_WinFNT_ID_CP1251 */ + /* (204) means Windows code page 1251 (for Russian). */ + /* */ + /* FT_ENCODING_NONE is set if `platform_id' is `TT_PLATFORM_MACINTOSH' */ + /* and `encoding_id' is not `TT_MAC_ID_ROMAN' (otherwise it is set to */ + /* FT_ENCODING_APPLE_ROMAN). */ + /* */ + /* If `platform_id' is `TT_PLATFORM_MACINTOSH', use the function */ + /* `FT_Get_CMap_Language_ID' to query the Mac language ID which may be */ + /* needed to be able to distinguish Apple encoding variants. See */ + /* */ + /* http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/README.TXT */ + /* */ + /* to get an idea how to do that. Basically, if the language ID is 0, */ + /* dont use it, otherwise subtract 1 from the language ID. Then */ + /* examine `encoding_id'. If, for example, `encoding_id' is */ + /* `TT_MAC_ID_ROMAN' and the language ID (minus 1) is */ + /* `TT_MAC_LANGID_GREEK', it is the Greek encoding, not Roman. */ + /* `TT_MAC_ID_ARABIC' with `TT_MAC_LANGID_FARSI' means the Farsi */ + /* variant the Arabic encoding. */ + /* */ typedef enum FT_Encoding_ { FT_ENC_TAG( FT_ENCODING_NONE, 0, 0, 0, 0 ), @@ -518,11 +628,18 @@ FT_BEGIN_HEADER FT_ENC_TAG( FT_ENCODING_MS_SYMBOL, 's', 'y', 'm', 'b' ), FT_ENC_TAG( FT_ENCODING_UNICODE, 'u', 'n', 'i', 'c' ), - FT_ENC_TAG( FT_ENCODING_MS_SJIS, 's', 'j', 'i', 's' ), - FT_ENC_TAG( FT_ENCODING_MS_GB2312, 'g', 'b', ' ', ' ' ), - FT_ENC_TAG( FT_ENCODING_MS_BIG5, 'b', 'i', 'g', '5' ), - FT_ENC_TAG( FT_ENCODING_MS_WANSUNG, 'w', 'a', 'n', 's' ), - FT_ENC_TAG( FT_ENCODING_MS_JOHAB, 'j', 'o', 'h', 'a' ), + FT_ENC_TAG( FT_ENCODING_SJIS, 's', 'j', 'i', 's' ), + FT_ENC_TAG( FT_ENCODING_GB2312, 'g', 'b', ' ', ' ' ), + FT_ENC_TAG( FT_ENCODING_BIG5, 'b', 'i', 'g', '5' ), + FT_ENC_TAG( FT_ENCODING_WANSUNG, 'w', 'a', 'n', 's' ), + FT_ENC_TAG( FT_ENCODING_JOHAB, 'j', 'o', 'h', 'a' ), + + /* for backwards compatibility */ + FT_ENCODING_MS_SJIS = FT_ENCODING_SJIS, + FT_ENCODING_MS_GB2312 = FT_ENCODING_GB2312, + FT_ENCODING_MS_BIG5 = FT_ENCODING_BIG5, + FT_ENCODING_MS_WANSUNG = FT_ENCODING_WANSUNG, + FT_ENCODING_MS_JOHAB = FT_ENCODING_JOHAB, FT_ENC_TAG( FT_ENCODING_ADOBE_STANDARD, 'A', 'D', 'O', 'B' ), FT_ENC_TAG( FT_ENCODING_ADOBE_EXPERT, 'A', 'D', 'B', 'E' ), @@ -550,11 +667,11 @@ FT_BEGIN_HEADER /* ft_encoding_unicode :: see @FT_ENCODING_UNICODE */ /* ft_encoding_latin_2 :: see @FT_ENCODING_OLD_LATIN_2 */ /* ft_encoding_symbol :: see @FT_ENCODING_MS_SYMBOL */ - /* ft_encoding_sjis :: see @FT_ENCODING_MS_SJIS */ - /* ft_encoding_gb2312 :: see @FT_ENCODING_MS_GB2312 */ - /* ft_encoding_big5 :: see @FT_ENCODING_MS_BIG5 */ - /* ft_encoding_wansung :: see @FT_ENCODING_MS_WANSUNG */ - /* ft_encoding_johab :: see @FT_ENCODING_MS_JOHAB */ + /* ft_encoding_sjis :: see @FT_ENCODING_SJIS */ + /* ft_encoding_gb2312 :: see @FT_ENCODING_GB2312 */ + /* ft_encoding_big5 :: see @FT_ENCODING_BIG5 */ + /* ft_encoding_wansung :: see @FT_ENCODING_WANSUNG */ + /* ft_encoding_johab :: see @FT_ENCODING_JOHAB */ /* */ /* ft_encoding_adobe_standard :: see @FT_ENCODING_ADOBE_STANDARD */ /* ft_encoding_adobe_expert :: see @FT_ENCODING_ADOBE_EXPERT */ @@ -563,21 +680,21 @@ FT_BEGIN_HEADER /* */ /* ft_encoding_apple_roman :: see @FT_ENCODING_APPLE_ROMAN */ /* */ -#define ft_encoding_none FT_ENCODING_NONE -#define ft_encoding_unicode FT_ENCODING_UNICODE -#define ft_encoding_symbol FT_ENCODING_MS_SYMBOL -#define ft_encoding_latin_1 FT_ENCODING_ADOBE_LATIN_1 -#define ft_encoding_latin_2 FT_ENCODING_OLD_LATIN_2 -#define ft_encoding_sjis FT_ENCODING_MS_SJIS -#define ft_encoding_gb2312 FT_ENCODING_MS_GB2312 -#define ft_encoding_big5 FT_ENCODING_MS_BIG5 -#define ft_encoding_wansung FT_ENCODING_MS_WANSUNG -#define ft_encoding_johab FT_ENCODING_MS_JOHAB +#define ft_encoding_none FT_ENCODING_NONE +#define ft_encoding_unicode FT_ENCODING_UNICODE +#define ft_encoding_symbol FT_ENCODING_MS_SYMBOL +#define ft_encoding_latin_1 FT_ENCODING_ADOBE_LATIN_1 +#define ft_encoding_latin_2 FT_ENCODING_OLD_LATIN_2 +#define ft_encoding_sjis FT_ENCODING_SJIS +#define ft_encoding_gb2312 FT_ENCODING_GB2312 +#define ft_encoding_big5 FT_ENCODING_BIG5 +#define ft_encoding_wansung FT_ENCODING_WANSUNG +#define ft_encoding_johab FT_ENCODING_JOHAB -#define ft_encoding_adobe_standard FT_ENCODING_ADOBE_STANDARD -#define ft_encoding_adobe_expert FT_ENCODING_ADOBE_EXPERT -#define ft_encoding_adobe_custom FT_ENCODING_ADOBE_CUSTOM -#define ft_encoding_apple_roman FT_ENCODING_APPLE_ROMAN +#define ft_encoding_adobe_standard FT_ENCODING_ADOBE_STANDARD +#define ft_encoding_adobe_expert FT_ENCODING_ADOBE_EXPERT +#define ft_encoding_adobe_custom FT_ENCODING_ADOBE_CUSTOM +#define ft_encoding_apple_roman FT_ENCODING_APPLE_ROMAN /*************************************************************************/ @@ -651,10 +768,12 @@ FT_BEGIN_HEADER /* collection (i.e., a file which embeds */ /* several faces), this is the total number of */ /* faces found in the resource. 1 by default. */ + /* Accessing non-existent face indices causes */ + /* an error. */ /* */ /* face_index :: The index of the face in its font file. */ /* Usually, this is 0 for all normal font */ - /* formats. It can be more in the case of */ + /* formats. It can be > 0 in the case of */ /* collections (which embed several fonts in a */ /* single resource/file). */ /* */ @@ -692,8 +811,8 @@ FT_BEGIN_HEADER /* */ /* num_fixed_sizes :: The number of fixed sizes available in this */ /* face. This should be set to 0 for scalable */ - /* fonts, unless its face includes a complete */ - /* set of glyphs (called a `strike') for the */ + /* fonts, unless its face includes a set of */ + /* glyphs (called a `strike') for the */ /* specified sizes. */ /* */ /* available_sizes :: An array of sizes specifying the available */ @@ -743,10 +862,11 @@ FT_BEGIN_HEADER /* descender :: The face's descender is the vertical */ /* distance from the baseline to the */ /* bottommost point of any glyph in the face. */ - /* This field's value is *negative*, expressed */ - /* in font units. Some font designs use a */ - /* value different from `bbox.yMin'. Only */ - /* relevant for scalable formats. */ + /* This field's value is *negative* for values */ + /* below the baseline. It is expressed in */ + /* font units. Some font designs use a value */ + /* different from `bbox.yMin'. Only relevant */ + /* for scalable formats. */ /* */ /* height :: The face's height is the vertical distance */ /* from one baseline to the next when writing */ @@ -854,7 +974,7 @@ FT_BEGIN_HEADER /* FT_FACE_FLAG_XXX */ /* */ /* */ - /* A list of bit flags used in the 'face_flags' field of the */ + /* A list of bit flags used in the `face_flags' field of the */ /* @FT_FaceRec structure. They inform client applications of */ /* properties of the corresponding face. */ /* */ @@ -862,7 +982,7 @@ FT_BEGIN_HEADER /* FT_FACE_FLAG_SCALABLE :: */ /* Indicates that the face provides vectorial outlines. This */ /* doesn't prevent embedded bitmaps, i.e., a face can have both */ - /* this bit and @FT_FACE_FLAG_FIXED_SIZES set */ + /* this bit and @FT_FACE_FLAG_FIXED_SIZES set. */ /* */ /* FT_FACE_FLAG_FIXED_SIZES :: */ /* Indicates that the face contains `fixed sizes', i.e., bitmap */ @@ -901,9 +1021,9 @@ FT_BEGIN_HEADER /* */ /* FT_FACE_FLAG_GLYPH_NAMES :: */ /* Indicates that the font contains glyph names that can be */ - /* retrieved through @FT_Get_Glyph_Names. Note that some TrueType */ + /* retrieved through @FT_Get_Glyph_Name. Note that some TrueType */ /* fonts contain broken glyph name tables. Use the function */ - /* @FT_Has_PS_Glyph_Name when needed. */ + /* @FT_Has_PS_Glyph_Names when needed. */ /* */ /* FT_FACE_FLAG_EXTERNAL_STREAM :: */ /* Used internally by FreeType to indicate that a face's stream was */ @@ -1016,12 +1136,12 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ /* @macro: */ - /* FT_IS_FIXED_SIZES( face ) */ + /* FT_HAS_FIXED_SIZES( face ) */ /* */ /* @description: */ /* A macro that returns true whenever a face object contains some */ - /* embedded bitmaps. See the `fixed_sizes' field of the @FT_FaceRec */ - /* structure. */ + /* embedded bitmaps. See the `available_sizes' field of the */ + /* @FT_FaceRec structure. */ /* */ #define FT_HAS_FIXED_SIZES( face ) \ ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES ) @@ -1050,7 +1170,7 @@ FT_BEGIN_HEADER /* */ /* @description: */ /* A macro that returns true whenever a face object contains some */ - /* glyph names that can be accessed through @FT_Get_Glyph_Names. */ + /* glyph names that can be accessed through @FT_Get_Glyph_Name. */ /* */ #define FT_HAS_GLYPH_NAMES( face ) \ ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) @@ -1130,10 +1250,12 @@ FT_BEGIN_HEADER /* units to fractional (26.6) pixel coordinates. */ /* */ /* ascender :: The ascender, expressed in 26.6 fixed point */ - /* pixels. Always positive. */ + /* pixels. Positive for ascenders above the */ + /* baseline. */ /* */ /* descender :: The descender, expressed in 26.6 fixed point */ - /* pixels. Always negative. */ + /* pixels. Negative for descenders below the */ + /* baseline. */ /* */ /* height :: The text height, expressed in 26.6 fixed point */ /* pixels. Always positive. */ @@ -1142,12 +1264,12 @@ FT_BEGIN_HEADER /* fixed point pixels. Always positive. */ /* */ /* */ - /* The values of `ascender', `descender', and `height' are only the */ - /* scaled versions of `face->ascender', `face->descender', and */ - /* `face->height'. */ + /* For scalable fonts, the values of `ascender', `descender', and */ + /* `height' are scaled versions of `face->ascender', */ + /* `face->descender', and `face->height', respectively. */ /* */ /* Unfortunately, due to glyph hinting, these values might not be */ - /* exact for certain fonts, they thus must be treated as unreliable */ + /* exact for certain fonts. They thus must be treated as unreliable */ /* with an error margin of at least one pixel! */ /* */ /* Indeed, the only way to get the exact pixel ascender and descender */ @@ -1161,7 +1283,7 @@ FT_BEGIN_HEADER FT_UShort y_ppem; /* vertical pixels per EM */ FT_Fixed x_scale; /* two scales used to convert font units */ - FT_Fixed y_scale; /* to 26.6 frac. pixel coordinates.. */ + FT_Fixed y_scale; /* to 26.6 frac. pixel coordinates */ FT_Pos ascender; /* ascender in 26.6 frac. pixels */ FT_Pos descender; /* descender in 26.6 frac. pixels */ @@ -1311,16 +1433,18 @@ FT_BEGIN_HEADER /* */ /* outline :: The outline descriptor for the current glyph */ /* image if its format is */ - /* ft_glyph_bitmap_outline. */ + /* FT_GLYPH_FORMAT_OUTLINE. */ /* */ /* num_subglyphs :: The number of subglyphs in a composite glyph. */ - /* This format is only valid for the composite */ - /* glyph format, that should normally only be */ - /* loaded with the FT_LOAD_NO_RECURSE flag. */ + /* This field is only valid for the composite */ + /* glyph format that should normally only be */ + /* loaded with the @FT_LOAD_NO_RECURSE flag. */ + /* For now this is internal to FreeType. */ /* */ /* subglyphs :: An array of subglyph descriptors for */ /* composite glyphs. There are `num_subglyphs' */ - /* elements in there. */ + /* elements in there. Currently internal to */ + /* FreeType. */ /* */ /* control_data :: Certain font drivers can also return the */ /* control data for a given glyph image (e.g. */ @@ -1359,7 +1483,7 @@ FT_BEGIN_HEADER FT_Library library; FT_Face face; FT_GlyphSlot next; - FT_UInt flags; + FT_UInt reserved; /* retained for binary compatibility */ FT_Generic generic; FT_Glyph_Metrics metrics; @@ -1474,13 +1598,13 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ /* */ - /* FT_Open_Flags */ + /* FT_OPEN_XXX */ /* */ /* */ - /* An enumeration used to list the bit flags used within the */ - /* `flags' field of the @FT_Open_Args structure. */ + /* A list of bit-field constants used within the `flags' field of the */ + /* @FT_Open_Args structure. */ /* */ - /* */ + /* */ /* FT_OPEN_MEMORY :: This is a memory-based stream. */ /* */ /* FT_OPEN_STREAM :: Copy the stream from the `stream' field. */ @@ -1492,35 +1616,31 @@ FT_BEGIN_HEADER /* */ /* FT_OPEN_PARAMS :: Use the `num_params' & `params' field. */ /* */ - /* ft_open_memory :: deprecated. use @FT_OPEN_MEMORY instead */ + /* ft_open_memory :: Deprecated; use @FT_OPEN_MEMORY instead. */ /* */ - /* ft_open_stream :: deprecated. use @FT_OPEN_STREAM instead */ + /* ft_open_stream :: Deprecated; use @FT_OPEN_STREAM instead. */ /* */ - /* ft_open_pathname :: deprecated. use @FT_OPEN_PATHNAME instead */ + /* ft_open_pathname :: Deprecated; use @FT_OPEN_PATHNAME instead. */ /* */ - /* ft_open_driver :: deprecated, use @FT_OPEN_DRIVER instead */ + /* ft_open_driver :: Deprecated; use @FT_OPEN_DRIVER instead. */ /* */ - /* ft_open_params :: deprecated, use @FT_OPEN_PARAMS instead */ + /* ft_open_params :: Deprecated; use @FT_OPEN_PARAMS instead. */ /* */ /* */ /* The `FT_OPEN_MEMORY', `FT_OPEN_STREAM', and `FT_OPEN_PATHNAME' */ /* flags are mutually exclusive. */ /* */ - typedef enum - { - FT_OPEN_MEMORY = 1, - FT_OPEN_STREAM = 2, - FT_OPEN_PATHNAME = 4, - FT_OPEN_DRIVER = 8, - FT_OPEN_PARAMS = 16 +#define FT_OPEN_MEMORY 0x1 +#define FT_OPEN_STREAM 0x2 +#define FT_OPEN_PATHNAME 0x4 +#define FT_OPEN_DRIVER 0x8 +#define FT_OPEN_PARAMS 0x10 - } FT_Open_Flags; - -#define ft_open_memory FT_OPEN_MEMORY /* deprecated */ -#define ft_open_stream FT_OPEN_STREAM /* deprecated */ -#define ft_open_pathname FT_OPEN_PATHNAME /* deprecated */ -#define ft_open_driver FT_OPEN_DRIVER /* deprecated */ -#define ft_open_params FT_OPEN_PARAMS /* deprecated */ +#define ft_open_memory FT_OPEN_MEMORY /* deprecated */ +#define ft_open_stream FT_OPEN_STREAM /* deprecated */ +#define ft_open_pathname FT_OPEN_PATHNAME /* deprecated */ +#define ft_open_driver FT_OPEN_DRIVER /* deprecated */ +#define ft_open_params FT_OPEN_PARAMS /* deprecated */ /*************************************************************************/ @@ -1602,14 +1722,14 @@ FT_BEGIN_HEADER /* */ typedef struct FT_Open_Args_ { - FT_Open_Flags flags; - const FT_Byte* memory_base; - FT_Long memory_size; - FT_String* pathname; - FT_Stream stream; - FT_Module driver; - FT_Int num_params; - FT_Parameter* params; + FT_UInt flags; + const FT_Byte* memory_base; + FT_Long memory_size; + FT_String* pathname; + FT_Stream stream; + FT_Module driver; + FT_Int num_params; + FT_Parameter* params; } FT_Open_Args; @@ -1631,6 +1751,7 @@ FT_BEGIN_HEADER /* */ /* face_index :: The index of the face within the resource. The */ /* first face has index 0. */ + /* */ /* */ /* aface :: A handle to a new face object. */ /* */ @@ -1644,9 +1765,9 @@ FT_BEGIN_HEADER /* */ /* @FT_New_Face can be used to determine and/or check the font format */ /* of a given font resource. If the `face_index' field is negative, */ - /* the function will _not_ return any face handle in `aface'. Its */ - /* return value should be 0 if the font format is recognized, or */ - /* non-zero otherwise. */ + /* the function will _not_ return any face handle in `aface'; the */ + /* return value is 0 if the font format is recognized, or non-zero */ + /* otherwise. */ /* */ /* Each new face object created with this function also owns a */ /* default @FT_Size object, accessible as `face->size'. */ @@ -1677,6 +1798,7 @@ FT_BEGIN_HEADER /* */ /* face_index :: The index of the face within the resource. The */ /* first face has index 0. */ + /* */ /* */ /* aface :: A handle to a new face object. */ /* */ @@ -1696,8 +1818,8 @@ FT_BEGIN_HEADER /* @FT_New_Memory_Face can be used to determine and/or check the font */ /* format of a given font resource. If the `face_index' field is */ /* negative, the function will _not_ return any face handle in */ - /* `aface'. Its return value should be 0 if the font format is */ - /* recognized, or non-zero otherwise. */ + /* `aface'; the return value is 0 if the font format is recognized, */ + /* or non-zero otherwise. */ /* */ FT_EXPORT( FT_Error ) FT_New_Memory_Face( FT_Library library, @@ -1726,6 +1848,7 @@ FT_BEGIN_HEADER /* */ /* face_index :: The index of the face within the resource. The */ /* first face has index 0. */ + /* */ /* */ /* aface :: A handle to a new face object. */ /* */ @@ -1737,11 +1860,11 @@ FT_BEGIN_HEADER /* slot for the face object which can be accessed directly through */ /* `face->glyph'. */ /* */ - /* @FT_Open_Face can be used to determine and/or check the font */ + /* @FT_Open_Face can be used to determine and/or check the font */ /* format of a given font resource. If the `face_index' field is */ /* negative, the function will _not_ return any face handle in */ - /* `*face'. Its return value should be 0 if the font format is */ - /* recognized, or non-zero otherwise. */ + /* `*face'; the return value is 0 if the font format is recognized, */ + /* or non-zero otherwise. */ /* */ FT_EXPORT( FT_Error ) FT_Open_Face( FT_Library library, @@ -1853,7 +1976,7 @@ FT_BEGIN_HEADER /* character dimensions is zero, its value is set equal to the other. */ /* */ /* */ - /* size :: A handle to a target size object. */ + /* face :: A handle to a target face object. */ /* */ /* */ /* char_width :: The character width, in 26.6 fractional points. */ @@ -1870,7 +1993,7 @@ FT_BEGIN_HEADER /* */ /* */ /* When dealing with fixed-size faces (i.e., non-scalable formats), */ - /* use the function @FT_Set_Pixel_Sizes. */ + /* @FT_Set_Pixel_Sizes provides a more convenient interface. */ /* */ FT_EXPORT( FT_Error ) FT_Set_Char_Size( FT_Face face, @@ -1903,7 +2026,6 @@ FT_BEGIN_HEADER /* */ /* FreeType error code. 0 means success. */ /* */ - /* */ /* */ /* The values of `pixel_width' and `pixel_height' correspond to the */ /* pixel values of the _typographic_ character size, which are NOT */ @@ -1919,6 +2041,11 @@ FT_BEGIN_HEADER /* guarantee in any way that you will get glyph bitmaps that all fit */ /* within an 8x8 cell (sometimes even far from it). */ /* */ + /* For bitmap fonts, `pixel_height' usually is a reliable value for */ + /* the height of the bitmap cell. Drivers for bitmap font formats */ + /* which contain a single bitmap strike only (BDF, PCF, FNT) ignore */ + /* `pixel_width'. */ + /* */ FT_EXPORT( FT_Error ) FT_Set_Pixel_Sizes( FT_Face face, FT_UInt pixel_width, @@ -1939,7 +2066,9 @@ FT_BEGIN_HEADER /* will be loaded. */ /* */ /* */ - /* glyph_index :: The index of the glyph in the font file. */ + /* glyph_index :: The index of the glyph in the font file. For */ + /* CID-keyed fonts (either in PS or in CFF format) */ + /* this argument specifies the CID value. */ /* */ /* load_flags :: A flag indicating what to load for this glyph. The */ /* @FT_LOAD_XXX constants can be used to control the */ @@ -2010,7 +2139,7 @@ FT_BEGIN_HEADER FT_Int32 load_flags ); - /**************************************************************************** + /*************************************************************************** * * @enum: * FT_LOAD_XXX @@ -2130,7 +2259,23 @@ FT_BEGIN_HEADER * outlines. This doesn't prevent native format-specific hinters from * being used. This can be important for certain fonts where unhinted * output is better than auto-hinted one. + * + * FT_LOAD_TARGET_NORMAL :: + * Use hinting for @FT_RENDER_MODE_NORMAL. + * + * FT_LOAD_TARGET_LIGHT :: + * Use hinting for @FT_RENDER_MODE_LIGHT. + * + * FT_LOAD_TARGET_MONO :: + * Use hinting for @FT_RENDER_MODE_MONO. + * + * FT_LOAD_TARGET_LCD :: + * Use hinting for @FT_RENDER_MODE_LCD. + * + * FT_LOAD_TARGET_LCD_V :: + * Use hinting for @FT_RENDER_MODE_LCD_V. */ +#define FT_LOAD_DEFAULT 0x0 #define FT_LOAD_NO_SCALE 0x1 #define FT_LOAD_NO_HINTING 0x2 #define FT_LOAD_RENDER 0x4 @@ -2160,7 +2305,7 @@ FT_BEGIN_HEADER #define FT_LOAD_TARGET_LCD FT_LOAD_TARGET_( FT_RENDER_MODE_LCD ) #define FT_LOAD_TARGET_LCD_V FT_LOAD_TARGET_( FT_RENDER_MODE_LCD_V ) -#define FT_LOAD_DEFAULT 0x0 + /* */ /*************************************************************************/ @@ -2186,7 +2331,7 @@ FT_BEGIN_HEADER /* The transformation is only applied to scalable image formats after */ /* the glyph has been loaded. It means that hinting is unaltered by */ /* the transformation and is performed on the character size given in */ - /* the last call to @FT_Set_Char_Sizes or @FT_Set_Pixel_Sizes. */ + /* the last call to @FT_Set_Char_Size or @FT_Set_Pixel_Sizes. */ /* */ FT_EXPORT( void ) FT_Set_Transform( FT_Face face, @@ -2205,18 +2350,24 @@ FT_BEGIN_HEADER /* conversion performed on the outline, as well as specific */ /* hinting optimizations. */ /* */ + /* For bitmap fonts the `bitmap->pixel_mode' field in the */ + /* @FT_GlyphSlotRec structure gives the format of the returned */ + /* bitmap. */ + /* */ /* */ /* FT_RENDER_MODE_NORMAL :: */ /* This is the default render mode; it corresponds to 8-bit */ /* anti-aliased bitmaps, using 256 levels of opacity. */ /* */ /* FT_RENDER_MODE_LIGHT :: */ - /* This is similar to @FT_RENDER_MODE_NORMAL, except that this */ - /* changes the hinting to prevent stem width quantization. This */ - /* results in glyph shapes that are more similar to the original, */ - /* while being a bit more fuzzy ("better shapes", instead of */ - /* "better contrast" if you want :-) THIS IS STILL EXPERIMENTAL, */ - /* FOR NOW, THIS WILL PRODUCE RESULTS SIMILAR TO NORMAL MODE !! */ + /* This is similar to @FT_RENDER_MODE_NORMAL -- you have to use */ + /* @FT_LOAD_TARGET_LIGHT in calls to @FT_Load_Glyph to get any */ + /* effect since the rendering process no longer influences the */ + /* positioning of glyph outlines. */ + /* */ + /* The resulting glyph shapes are more similar to the original, */ + /* while being a bit more fuzzy (`better shapes' instead of `better */ + /* contrast', so to say. */ /* */ /* FT_RENDER_MODE_MONO :: */ /* This mode corresponds to 1-bit bitmaps. */ @@ -2225,8 +2376,7 @@ FT_BEGIN_HEADER /* This mode corresponds to horizontal RGB/BGR sub-pixel displays, */ /* like LCD-screens. It produces 8-bit bitmaps that are 3 times */ /* the width of the original glyph outline in pixels, and which use */ - /* the @FT_PIXEL_MODE_LCD mode. THIS IS STILL EXPERIMENTAL, DO NOT */ - /* USE FOR NOW !! */ + /* the @FT_PIXEL_MODE_LCD mode. */ /* */ /* FT_RENDER_MODE_LCD_V :: */ /* This mode corresponds to vertical RGB/BGR sub-pixel displays */ @@ -2237,8 +2387,7 @@ FT_BEGIN_HEADER /* */ /* The LCD-optimized glyph bitmaps produced by FT_Render_Glyph are */ /* _not filtered_ to reduce color-fringes. It is up to the caller to */ - /* perform this pass. THIS IS STILL EXPERIMENTAL, DO NOT USE FOR NOW */ - /* !! */ + /* perform this pass. */ /* */ typedef enum FT_Render_Mode_ { @@ -2770,7 +2919,7 @@ FT_BEGIN_HEADER /* */ /* The optimization for FT_DivFix() is simple: If (a << 16) fits in */ /* 32 bits, then the division is computed directly. Otherwise, we */ - /* use a specialized version of the old @FT_MulDiv64. */ + /* use a specialized version of @FT_MulDiv. */ /* */ FT_EXPORT( FT_Long ) FT_DivFix( FT_Long a, @@ -2862,4 +3011,5 @@ FT_END_HEADER #endif /* __FREETYPE_H__ */ + /* END */ diff --git a/headers/libs/freetype2/freetype/ftbbox.h b/headers/libs/freetype2/freetype/ftbbox.h index 3afa69fae5..f98c89eb2d 100644 --- a/headers/libs/freetype2/freetype/ftbbox.h +++ b/headers/libs/freetype2/freetype/ftbbox.h @@ -4,7 +4,7 @@ /* */ /* FreeType exact bbox computation (specification). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2001, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -34,6 +34,12 @@ #include #include FT_FREETYPE_H +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + FT_BEGIN_HEADER @@ -80,4 +86,4 @@ FT_END_HEADER #endif /* __FTBBOX_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/ftbdf.h b/headers/libs/freetype2/freetype/ftbdf.h index da2930665c..aa411440d9 100644 --- a/headers/libs/freetype2/freetype/ftbdf.h +++ b/headers/libs/freetype2/freetype/ftbdf.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing BDF-specific strings (specification). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,6 +22,12 @@ #include #include FT_FREETYPE_H +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + FT_BEGIN_HEADER @@ -49,22 +55,22 @@ FT_BEGIN_HEADER * FT_PropertyType * * @description: - * list of BDF property types + * A list of BDF property types. * * @values: * BDF_PROPERTY_TYPE_NONE :: - * value 0 is used to indicate a missing property + * Value 0 is used to indicate a missing property. * * BDF_PROPERTY_TYPE_ATOM :: - * property is a string atom + * Property is a string atom. * * BDF_PROPERTY_TYPE_INTEGER :: - * property is a 32-bit signed integer + * Property is a 32-bit signed integer. * * BDF_PROPERTY_TYPE_CARDINAL :: - * property is a 32-bit unsigned integer + * Property is a 32-bit unsigned integer. */ - typedef enum + typedef enum BDF_PropertyType_ { BDF_PROPERTY_TYPE_NONE = 0, BDF_PROPERTY_TYPE_ATOM = 1, @@ -76,34 +82,44 @@ FT_BEGIN_HEADER /********************************************************************** * - * @type: BDF_Property + * @type: + * BDF_Property * * @description: - * handle to a @BDF_PropertyRec structure used to model a given - * BDF/PCF property + * A handle to a @BDF_PropertyRec structure to model a given + * BDF/PCF property. */ - typedef struct BDF_PropertyRec_* BDF_Property; + typedef struct BDF_PropertyRec_* BDF_Property; + /********************************************************************** * - * @struct: BDF_PropertyRec + * @struct: + * BDF_PropertyRec * * @description: - * models a given BDF/PCF property + * This structure models a given BDF/PCF property. * - * @note: - * type :: property type - * u.atom :: atom string, when type is @BDF_PROPERTY_TYPE_ATOM - * u.integer :: signed integer, when type is @BDF_PROPERTY_TYPE_INTEGER - * u.cardinal :: unsigned integer, when type is @BDF_PROPERTY_TYPE_CARDINAL + * @fields: + * type :: + * The property type. + * + * u.atom :: + * The atom string, if type is @BDF_PROPERTY_TYPE_ATOM. + * + * u.integer :: + * A signed integer, if type is @BDF_PROPERTY_TYPE_INTEGER. + * + * u.cardinal :: + * An unsigned integer, if type is @BDF_PROPERTY_TYPE_CARDINAL. */ - typedef struct BDF_PropertyRec_ + typedef struct BDF_PropertyRec_ { - BDF_PropertyType type; + BDF_PropertyType type; union { - const char* atom; - FT_Int32 integer; - FT_UInt32 cardinal; + const char* atom; + FT_Int32 integer; + FT_UInt32 cardinal; } u; @@ -121,7 +137,7 @@ FT_BEGIN_HEADER * * @input: * face :: - * handle to input face + * A handle to the input face. * * @output: * acharset_encoding :: @@ -131,7 +147,7 @@ FT_BEGIN_HEADER * Charset registry, as a C string, owned by the face. * * @return: - * FreeType rror code. 0 means success. + * FreeType error code. 0 means success. * * @note: * This function only works with BDF faces, returning an error otherwise. @@ -141,31 +157,33 @@ FT_BEGIN_HEADER const char* *acharset_encoding, const char* *acharset_registry ); + /********************************************************************** * * @function: * FT_Get_BDF_Property * * @description: - * Retrieves a BDF property from a BDF or PCF font file + * Retrieves a BDF property from a BDF or PCF font file. * * @input: - * face :: handle to input face - * name :: property name + * face :: A handle to the input face. + * + * name :: The property name. * * @output: - * aproperty :: the property + * aproperty :: The property. * * @return: * FreeType error code. 0 means success. * * @note: - * This function works with BDF _and_ PCF fonts. It returns an error - * otherwise. it also returns an error when the property is not in the + * This function works with BDF _and_ PCF fonts. It returns an error + * otherwise. It also returns an error if the property is not in the * font. * - * in case of error, "aproperty->type" is always set to - * @BDF_PROPERTY_TYPE_NONE + * In case of error, "aproperty->type" is always set to + * @BDF_PROPERTY_TYPE_NONE. */ FT_EXPORT( FT_Error ) FT_Get_BDF_Property( FT_Face face, @@ -179,4 +197,4 @@ FT_END_HEADER #endif /* __FTBDF_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/ftcache.h b/headers/libs/freetype2/freetype/ftcache.h index e8c0eac6d8..c6dc14aeca 100644 --- a/headers/libs/freetype2/freetype/ftcache.h +++ b/headers/libs/freetype2/freetype/ftcache.h @@ -4,7 +4,7 @@ /* */ /* FreeType Cache subsystem (specification). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -63,15 +63,14 @@ FT_BEGIN_HEADER /* FTC_Face_Requester */ /* */ /* FTC_Manager_New */ - /* FTC_Manager_Lookup_Face */ - /* FTC_Manager_Lookup_Size */ + /* FTC_Manager_LookupFace */ + /* FTC_Manager_LookupSize */ /* */ /* FTC_Node */ /* FTC_Node_Ref */ /* FTC_Node_Unref */ /* */ /* FTC_Font */ - /* FTC_ImageDesc */ /* FTC_ImageCache */ /* FTC_ImageCache_New */ /* FTC_ImageCache_Lookup */ @@ -109,10 +108,10 @@ FT_BEGIN_HEADER /* FTC_FaceID */ /* */ /* */ - /* A generic pointer type that is used to identity face objects. The */ + /* An opaque pointer type that is used to identity face objects. The */ /* contents of such objects is application-dependent. */ /* */ - typedef FT_Pointer FTC_FaceID; + typedef struct FTC_FaceIDRec_* FTC_FaceID; /*************************************************************************/ @@ -242,9 +241,9 @@ FT_BEGIN_HEADER /* If you lookup nodes, you have the ability to "acquire" them, i.e., */ /* to increment their reference count. This will prevent the node */ /* from being flushed out of the cache until you explicitly "release" */ - /* it (see @FTC_Node_Release). */ + /* it (see @FTC_Node_Unref). */ /* */ - /* See also @FTC_BitsetCache_Lookup and @FTC_ImageCache_Lookup. */ + /* See also @FTC_SBitCache_Lookup and @FTC_ImageCache_Lookup. */ /* */ typedef struct FTC_NodeRec_* FTC_Node; @@ -258,22 +257,16 @@ FT_BEGIN_HEADER /* Creates a new cache manager. */ /* */ /* */ - /* library :: The parent FreeType library handle to use. */ + /* library :: The parent FreeType library handle to use. */ /* */ - /* max_faces :: Maximum number of faces to keep alive in manager. */ - /* Use 0 for defaults. */ + /* max_bytes :: Maximum number of bytes to use for cached data. */ + /* Use 0 for defaults. */ /* */ - /* max_sizes :: Maximum number of sizes to keep alive in manager. */ - /* Use 0 for defaults. */ + /* requester :: An application-provided callback used to translate */ + /* face IDs into real @FT_Face objects. */ /* */ - /* max_bytes :: Maximum number of bytes to use for cached data. */ - /* Use 0 for defaults. */ - /* */ - /* requester :: An application-provided callback used to translate */ - /* face IDs into real @FT_Face objects. */ - /* */ - /* req_data :: A generic pointer that is passed to the requester */ - /* each time it is called (see @FTC_Face_Requester). */ + /* req_data :: A generic pointer that is passed to the requester */ + /* each time it is called (see @FTC_Face_Requester). */ /* */ /* */ /* amanager :: A handle to a new manager object. 0 in case of */ @@ -326,7 +319,7 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ /* */ - /* FTC_Manager_Lookup_Face */ + /* FTC_Manager_LookupFace */ /* */ /* */ /* Retrieves the @FT_Face object that corresponds to a given face ID */ @@ -349,67 +342,483 @@ FT_BEGIN_HEADER /* */ /* The @FT_Face object doesn't necessarily have a current size object */ /* (i.e., face->size can be 0). If you need a specific `font size', */ - /* use @FTC_Manager_Lookup_Size instead. */ + /* use @FTC_Manager_LookupSize instead. */ /* */ /* Never change the face's transformation matrix (i.e., never call */ /* the @FT_Set_Transform function) on a returned face! If you need */ /* to transform glyphs, do it yourself after glyph loading. */ /* */ FT_EXPORT( FT_Error ) - FTC_Manager_Lookup_Face( FTC_Manager manager, - FTC_FaceID face_id, - FT_Face *aface ); + FTC_Manager_LookupFace( FTC_Manager manager, + FTC_FaceID face_id, + FT_Face *aface ); + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_ScalerRec */ + /* */ + /* */ + /* A structure used to describe a given character size in either */ + /* pixels or points to the cache manager. See */ + /* @FTC_Manager_LookupSize. */ + /* */ + /* */ + /* face_id :: The source face ID. */ + /* */ + /* width :: The character width. */ + /* */ + /* height :: The character height. */ + /* */ + /* pixel :: A Boolean. If TRUE, the `width' and `height' fields */ + /* are interpreted as integer pixel character sizes. */ + /* Otherwise, they are expressed as 1/64th of points. */ + /* */ + /* x_res :: Only used when `pixel' is FALSE to indicate the */ + /* horizontal resolution in dpi. */ + /* */ + /* y_res :: Only used when `pixel' is FALSE to indicate the */ + /* vertical resolution in dpi. */ + /* */ + /* */ + /* This type is mainly used to retrieve @FT_Size objects through the */ + /* cache manager. */ + /* */ + typedef struct FTC_ScalerRec_ + { + FTC_FaceID face_id; + FT_UInt width; + FT_UInt height; + FT_Int pixel; + FT_UInt x_res; + FT_UInt y_res; + + } FTC_ScalerRec, *FTC_Scaler; /*************************************************************************/ /* */ /* */ - /* FTC_Manager_Lookup_Size */ + /* FTC_Manager_LookupSize */ /* */ /* */ - /* Retrieves the @FT_Face and @FT_Size objects that correspond to a */ - /* given @FTC_SizeID. */ + /* Retrieve the @FT_Size object that corresponds to a given */ + /* @FTC_Scaler through a cache manager. */ /* */ /* */ /* manager :: A handle to the cache manager. */ /* */ - /* size_id :: The ID of the `font size' to use. */ + /* scaler :: A scaler handle. */ /* */ /* */ - /* aface :: A pointer to the handle of the face object. Set it to */ - /* zero if you don't need it. */ - /* */ - /* asize :: A pointer to the handle of the size object. Set it to */ - /* zero if you don't need it. */ + /* asize :: A handle to the size object. */ /* */ /* */ /* FreeType error code. 0 means success. */ /* */ /* */ - /* The returned @FT_Face object is always owned by the manager. You */ - /* should never try to discard it yourself. */ + /* The returned @FT_Size object is always owned by the manager. You */ + /* should never try to discard it by yourself. */ /* */ - /* Never change the face's transformation matrix (i.e., never call */ - /* the @FT_Set_Transform function) on a returned face! If you need */ - /* to transform glyphs, do it yourself after glyph loading. */ - /* */ - /* Similarly, the returned @FT_Size object is always owned by the */ - /* manager. You should never try to discard it, and never change its */ - /* settings with @FT_Set_Pixel_Sizes or @FT_Set_Char_Size! */ - /* */ - /* The returned size object is the face's current size, which means */ - /* that you can call @FT_Load_Glyph with the face if you need to. */ + /* You can access the parent @FT_Face object simply as `size->face' */ + /* if you need it. Note that this object is also owned by the */ + /* manager. */ /* */ FT_EXPORT( FT_Error ) - FTC_Manager_Lookup_Size( FTC_Manager manager, - FTC_Font font, - FT_Face *aface, - FT_Size *asize ); + FTC_Manager_LookupSize( FTC_Manager manager, + FTC_Scaler scaler, + FT_Size *asize ); + /*************************************************************************/ + /* */ + /* */ + /* FTC_Node_Unref */ + /* */ + /* */ + /* Decrement a cache node's internal reference count. When the count */ + /* reaches 0, it is not destroyed but becomes eligible for subsequent */ + /* cache flushes. */ + /* */ + /* */ + /* node :: The cache node handle. */ + /* */ + /* manager :: The cache manager handle. */ + /* */ + FT_EXPORT( void ) + FTC_Node_Unref( FTC_Node node, + FTC_Manager manager ); + + + /* remove all nodes belonging to a given face_id */ + FT_EXPORT( void ) + FTC_Manager_RemoveFaceID( FTC_Manager manager, + FTC_FaceID face_id ); + + + /*************************************************************************/ + /* */ + /*
*/ + /* cache_subsystem */ + /* */ + /*************************************************************************/ + + /************************************************************************ + * + * @type: + * FTC_CMapCache + * + * @description: + * An opaque handle used to manager a charmap cache. This cache is + * to hold character codes -> glyph indices mappings. + */ + typedef struct FTC_CMapCacheRec_* FTC_CMapCache; + + + /*************************************************************************/ + /* */ + /* @function: */ + /* FTC_CMapCache_New */ + /* */ + /* @description: */ + /* Create a new charmap cache. */ + /* */ + /* @input: */ + /* manager :: A handle to the cache manager. */ + /* */ + /* @output: */ + /* acache :: A new cache handle. NULL in case of error. */ + /* */ + /* @return: */ + /* FreeType error code. 0 means success. */ + /* */ + /* @note: */ + /* Like all other caches, this one will be destroyed with the cache */ + /* manager. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_CMapCache_New( FTC_Manager manager, + FTC_CMapCache *acache ); + + + /* retrieve the index of a given charmap */ + FT_EXPORT( FT_Int ) + FT_Get_CharMap_Index( FT_CharMap charmap ); + + + /*************************************************************************/ + /* */ + /* @function: */ + /* FTC_CMapCache_Lookup */ + /* */ + /* @description: */ + /* Translate a character code into a glyph index, using the charmap */ + /* cache. */ + /* */ + /* @input: */ + /* cache :: A charmap cache handle. */ + /* */ + /* face_id :: source face id */ + /* */ + /* cmap_index :: index of charmap in source face */ + /* */ + /* char_code :: The character code (in the corresponding charmap). */ + /* */ + /* @return: */ + /* Glyph index. 0 means `no glyph'. */ + /* */ + FT_EXPORT( FT_UInt ) + FTC_CMapCache_Lookup( FTC_CMapCache cache, + FTC_FaceID face_id, + FT_Int cmap_index, + FT_UInt32 char_code ); + + + /*************************************************************************/ + /* */ + /*
*/ + /* cache_subsystem */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** IMAGE CACHE OBJECT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct FTC_ImageTypeRec_ + { + FTC_FaceID face_id; + FT_Int width; + FT_Int height; + FT_Int32 flags; + + } FTC_ImageTypeRec; + + typedef struct FTC_ImageTypeRec_* FTC_ImageType; + + /* */ + +#define FTC_IMAGE_TYPE_COMPARE( d1, d2 ) \ + ( FTC_FONT_COMPARE( &(d1)->font, &(d2)->font ) && \ + (d1)->flags == (d2)->flags ) + +#define FTC_IMAGE_TYPE_HASH( d ) \ + (FT_UFast)( FTC_FONT_HASH( &(d)->font ) ^ \ + ( (d)->flags << 4 ) ) + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_ImageCache */ + /* */ + /* */ + /* A handle to an glyph image cache object. They are designed to */ + /* hold many distinct glyph images while not exceeding a certain */ + /* memory threshold. */ + /* */ + typedef struct FTC_ImageCacheRec_* FTC_ImageCache; + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_ImageCache_New */ + /* */ + /* */ + /* Creates a new glyph image cache. */ + /* */ + /* */ + /* manager :: The parent manager for the image cache. */ + /* */ + /* */ + /* acache :: A handle to the new glyph image cache object. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_ImageCache_New( FTC_Manager manager, + FTC_ImageCache *acache ); + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_ImageCache_Lookup */ + /* */ + /* */ + /* Retrieves a given glyph image from a glyph image cache. */ + /* */ + /* */ + /* cache :: A handle to the source glyph image cache. */ + /* */ + /* type :: A pointer to a glyph image type descriptor. */ + /* */ + /* gindex :: The glyph index to retrieve. */ + /* */ + /* */ + /* aglyph :: The corresponding @FT_Glyph object. 0 in case of */ + /* failure. */ + /* */ + /* anode :: Used to return the address of of the corresponding cache */ + /* node after incrementing its reference count (see note */ + /* below). */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + /* */ + /* The returned glyph is owned and managed by the glyph image cache. */ + /* Never try to transform or discard it manually! You can however */ + /* create a copy with @FT_Glyph_Copy and modify the new one. */ + /* */ + /* If `anode' is _not_ NULL, it receives the address of the cache */ + /* node containing the glyph image, after increasing its reference */ + /* count. This ensures that the node (as well as the FT_Glyph) will */ + /* always be kept in the cache until you call @FTC_Node_Unref to */ + /* `release' it. */ + /* */ + /* If `anode' is NULL, the cache node is left unchanged, which means */ + /* that the FT_Glyph could be flushed out of the cache on the next */ + /* call to one of the caching sub-system APIs. Don't assume that it */ + /* is persistent! */ + /* */ + FT_EXPORT( FT_Error ) + FTC_ImageCache_Lookup( FTC_ImageCache cache, + FTC_ImageType type, + FT_UInt gindex, + FT_Glyph *aglyph, + FTC_Node *anode ); + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_SBit */ + /* */ + /* */ + /* A handle to a small bitmap descriptor. See the @FTC_SBitRec */ + /* structure for details. */ + /* */ + typedef struct FTC_SBitRec_* FTC_SBit; + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_SBitRec */ + /* */ + /* */ + /* A very compact structure used to describe a small glyph bitmap. */ + /* */ + /* */ + /* width :: The bitmap width in pixels. */ + /* */ + /* height :: The bitmap height in pixels. */ + /* */ + /* left :: The horizontal distance from the pen position to the */ + /* left bitmap border (a.k.a. `left side bearing', or */ + /* `lsb'). */ + /* */ + /* top :: The vertical distance from the pen position (on the */ + /* baseline) to the upper bitmap border (a.k.a. `top */ + /* side bearing'). The distance is positive for upwards */ + /* Y coordinates. */ + /* */ + /* format :: The format of the glyph bitmap (monochrome or gray). */ + /* */ + /* max_grays :: Maximum gray level value (in the range 1 to 255). */ + /* */ + /* pitch :: The number of bytes per bitmap line. May be positive */ + /* or negative. */ + /* */ + /* xadvance :: The horizontal advance width in pixels. */ + /* */ + /* yadvance :: The vertical advance height in pixels. */ + /* */ + /* buffer :: A pointer to the bitmap pixels. */ + /* */ + typedef struct FTC_SBitRec_ + { + FT_Byte width; + FT_Byte height; + FT_Char left; + FT_Char top; + + FT_Byte format; + FT_Byte max_grays; + FT_Short pitch; + FT_Char xadvance; + FT_Char yadvance; + + FT_Byte* buffer; + + } FTC_SBitRec; + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_SBitCache */ + /* */ + /* */ + /* A handle to a small bitmap cache. These are special cache objects */ + /* used to store small glyph bitmaps (and anti-aliased pixmaps) in a */ + /* much more efficient way than the traditional glyph image cache */ + /* implemented by @FTC_ImageCache. */ + /* */ + typedef struct FTC_SBitCacheRec_* FTC_SBitCache; + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_SBitCache_New */ + /* */ + /* */ + /* Creates a new cache to store small glyph bitmaps. */ + /* */ + /* */ + /* manager :: A handle to the source cache manager. */ + /* */ + /* */ + /* acache :: A handle to the new sbit cache. NULL in case of error. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_SBitCache_New( FTC_Manager manager, + FTC_SBitCache *acache ); + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_SBitCache_Lookup */ + /* */ + /* */ + /* Looks up a given small glyph bitmap in a given sbit cache and */ + /* `lock' it to prevent its flushing from the cache until needed. */ + /* */ + /* */ + /* cache :: A handle to the source sbit cache. */ + /* */ + /* type :: A pointer to the glyph image type descriptor. */ + /* */ + /* gindex :: The glyph index. */ + /* */ + /* */ + /* sbit :: A handle to a small bitmap descriptor. */ + /* */ + /* anode :: Used to return the address of of the corresponding cache */ + /* node after incrementing its reference count (see note */ + /* below). */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + /* */ + /* The small bitmap descriptor and its bit buffer are owned by the */ + /* cache and should never be freed by the application. They might */ + /* as well disappear from memory on the next cache lookup, so don't */ + /* treat them as persistent data. */ + /* */ + /* The descriptor's `buffer' field is set to 0 to indicate a missing */ + /* glyph bitmap. */ + /* */ + /* If `anode' is _not_ NULL, it receives the address of the cache */ + /* node containing the bitmap, after increasing its reference count. */ + /* This ensures that the node (as well as the image) will always be */ + /* kept in the cache until you call @FTC_Node_Unref to `release' it. */ + /* */ + /* If `anode' is NULL, the cache node is left unchanged, which means */ + /* that the bitmap could be flushed out of the cache on the next */ + /* call to one of the caching sub-system APIs. Don't assume that it */ + /* is persistent! */ + /* */ + FT_EXPORT( FT_Error ) + FTC_SBitCache_Lookup( FTC_SBitCache cache, + FTC_ImageType type, + FT_UInt gindex, + FTC_SBit *sbit, + FTC_Node *anode ); + + + /* */ + FT_END_HEADER #endif /* __FTCACHE_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/ftchapters.h b/headers/libs/freetype2/freetype/ftchapters.h index d8f6909c09..c134ec122a 100644 --- a/headers/libs/freetype2/freetype/ftchapters.h +++ b/headers/libs/freetype2/freetype/ftchapters.h @@ -66,4 +66,4 @@ /* module_management */ /* */ /***************************************************************************/ - + diff --git a/headers/libs/freetype2/freetype/fterrdef.h b/headers/libs/freetype2/freetype/fterrdef.h index 8dba978cbf..2f73c08589 100644 --- a/headers/libs/freetype2/freetype/fterrdef.h +++ b/headers/libs/freetype2/freetype/fterrdef.h @@ -4,7 +4,7 @@ /* */ /* FreeType error codes (specification). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -31,118 +31,201 @@ /* generic errors */ - FT_NOERRORDEF_( Ok, 0x00, "no error" ) + FT_NOERRORDEF_( Ok, 0x00, \ + "no error" ) - FT_ERRORDEF_( Cannot_Open_Resource, 0x01, "cannot open resource" ) - FT_ERRORDEF_( Unknown_File_Format, 0x02, "unknown file format" ) - FT_ERRORDEF_( Invalid_File_Format, 0x03, "broken file" ) - FT_ERRORDEF_( Invalid_Version, 0x04, "invalid FreeType version" ) - FT_ERRORDEF_( Lower_Module_Version, 0x05, "module version is too low" ) - FT_ERRORDEF_( Invalid_Argument, 0x06, "invalid argument" ) - FT_ERRORDEF_( Unimplemented_Feature, 0x07, "unimplemented feature" ) - FT_ERRORDEF_( Invalid_Table, 0x08, "broken table" ) - FT_ERRORDEF_( Invalid_Offset, 0x09, "broken offset within table" ) + FT_ERRORDEF_( Cannot_Open_Resource, 0x01, \ + "cannot open resource" ) + FT_ERRORDEF_( Unknown_File_Format, 0x02, \ + "unknown file format" ) + FT_ERRORDEF_( Invalid_File_Format, 0x03, \ + "broken file" ) + FT_ERRORDEF_( Invalid_Version, 0x04, \ + "invalid FreeType version" ) + FT_ERRORDEF_( Lower_Module_Version, 0x05, \ + "module version is too low" ) + FT_ERRORDEF_( Invalid_Argument, 0x06, \ + "invalid argument" ) + FT_ERRORDEF_( Unimplemented_Feature, 0x07, \ + "unimplemented feature" ) + FT_ERRORDEF_( Invalid_Table, 0x08, \ + "broken table" ) + FT_ERRORDEF_( Invalid_Offset, 0x09, \ + "broken offset within table" ) /* glyph/character errors */ - FT_ERRORDEF_( Invalid_Glyph_Index, 0x10, "invalid glyph index" ) - FT_ERRORDEF_( Invalid_Character_Code, 0x11, "invalid character code" ) - FT_ERRORDEF_( Invalid_Glyph_Format, 0x12, "unsupported glyph image format" ) - FT_ERRORDEF_( Cannot_Render_Glyph, 0x13, "cannot render this glyph format" ) - FT_ERRORDEF_( Invalid_Outline, 0x14, "invalid outline" ) - FT_ERRORDEF_( Invalid_Composite, 0x15, "invalid composite glyph" ) - FT_ERRORDEF_( Too_Many_Hints, 0x16, "too many hints" ) - FT_ERRORDEF_( Invalid_Pixel_Size, 0x17, "invalid pixel size" ) + FT_ERRORDEF_( Invalid_Glyph_Index, 0x10, \ + "invalid glyph index" ) + FT_ERRORDEF_( Invalid_Character_Code, 0x11, \ + "invalid character code" ) + FT_ERRORDEF_( Invalid_Glyph_Format, 0x12, \ + "unsupported glyph image format" ) + FT_ERRORDEF_( Cannot_Render_Glyph, 0x13, \ + "cannot render this glyph format" ) + FT_ERRORDEF_( Invalid_Outline, 0x14, \ + "invalid outline" ) + FT_ERRORDEF_( Invalid_Composite, 0x15, \ + "invalid composite glyph" ) + FT_ERRORDEF_( Too_Many_Hints, 0x16, \ + "too many hints" ) + FT_ERRORDEF_( Invalid_Pixel_Size, 0x17, \ + "invalid pixel size" ) /* handle errors */ - FT_ERRORDEF_( Invalid_Handle, 0x20, "invalid object handle" ) - FT_ERRORDEF_( Invalid_Library_Handle, 0x21, "invalid library handle" ) - FT_ERRORDEF_( Invalid_Driver_Handle, 0x22, "invalid module handle" ) - FT_ERRORDEF_( Invalid_Face_Handle, 0x23, "invalid face handle" ) - FT_ERRORDEF_( Invalid_Size_Handle, 0x24, "invalid size handle" ) - FT_ERRORDEF_( Invalid_Slot_Handle, 0x25, "invalid glyph slot handle" ) - FT_ERRORDEF_( Invalid_CharMap_Handle, 0x26, "invalid charmap handle" ) - FT_ERRORDEF_( Invalid_Cache_Handle, 0x27, "invalid cache manager handle" ) - FT_ERRORDEF_( Invalid_Stream_Handle, 0x28, "invalid stream handle" ) + FT_ERRORDEF_( Invalid_Handle, 0x20, \ + "invalid object handle" ) + FT_ERRORDEF_( Invalid_Library_Handle, 0x21, \ + "invalid library handle" ) + FT_ERRORDEF_( Invalid_Driver_Handle, 0x22, \ + "invalid module handle" ) + FT_ERRORDEF_( Invalid_Face_Handle, 0x23, \ + "invalid face handle" ) + FT_ERRORDEF_( Invalid_Size_Handle, 0x24, \ + "invalid size handle" ) + FT_ERRORDEF_( Invalid_Slot_Handle, 0x25, \ + "invalid glyph slot handle" ) + FT_ERRORDEF_( Invalid_CharMap_Handle, 0x26, \ + "invalid charmap handle" ) + FT_ERRORDEF_( Invalid_Cache_Handle, 0x27, \ + "invalid cache manager handle" ) + FT_ERRORDEF_( Invalid_Stream_Handle, 0x28, \ + "invalid stream handle" ) /* driver errors */ - FT_ERRORDEF_( Too_Many_Drivers, 0x30, "too many modules" ) - FT_ERRORDEF_( Too_Many_Extensions, 0x31, "too many extensions" ) + FT_ERRORDEF_( Too_Many_Drivers, 0x30, \ + "too many modules" ) + FT_ERRORDEF_( Too_Many_Extensions, 0x31, \ + "too many extensions" ) /* memory errors */ - FT_ERRORDEF_( Out_Of_Memory, 0x40, "out of memory" ) - FT_ERRORDEF_( Unlisted_Object, 0x41, "unlisted object" ) + FT_ERRORDEF_( Out_Of_Memory, 0x40, \ + "out of memory" ) + FT_ERRORDEF_( Unlisted_Object, 0x41, \ + "unlisted object" ) /* stream errors */ - FT_ERRORDEF_( Cannot_Open_Stream, 0x51, "cannot open stream" ) - FT_ERRORDEF_( Invalid_Stream_Seek, 0x52, "invalid stream seek" ) - FT_ERRORDEF_( Invalid_Stream_Skip, 0x53, "invalid stream skip" ) - FT_ERRORDEF_( Invalid_Stream_Read, 0x54, "invalid stream read" ) - FT_ERRORDEF_( Invalid_Stream_Operation, 0x55, "invalid stream operation" ) - FT_ERRORDEF_( Invalid_Frame_Operation, 0x56, "invalid frame operation" ) - FT_ERRORDEF_( Nested_Frame_Access, 0x57, "nested frame access" ) - FT_ERRORDEF_( Invalid_Frame_Read, 0x58, "invalid frame read" ) + FT_ERRORDEF_( Cannot_Open_Stream, 0x51, \ + "cannot open stream" ) + FT_ERRORDEF_( Invalid_Stream_Seek, 0x52, \ + "invalid stream seek" ) + FT_ERRORDEF_( Invalid_Stream_Skip, 0x53, \ + "invalid stream skip" ) + FT_ERRORDEF_( Invalid_Stream_Read, 0x54, \ + "invalid stream read" ) + FT_ERRORDEF_( Invalid_Stream_Operation, 0x55, \ + "invalid stream operation" ) + FT_ERRORDEF_( Invalid_Frame_Operation, 0x56, \ + "invalid frame operation" ) + FT_ERRORDEF_( Nested_Frame_Access, 0x57, \ + "nested frame access" ) + FT_ERRORDEF_( Invalid_Frame_Read, 0x58, \ + "invalid frame read" ) /* raster errors */ - FT_ERRORDEF_( Raster_Uninitialized, 0x60, "raster uninitialized" ) - FT_ERRORDEF_( Raster_Corrupted, 0x61, "raster corrupted" ) - FT_ERRORDEF_( Raster_Overflow, 0x62, "raster overflow" ) - FT_ERRORDEF_( Raster_Negative_Height, 0x63, "negative height while rastering" ) + FT_ERRORDEF_( Raster_Uninitialized, 0x60, \ + "raster uninitialized" ) + FT_ERRORDEF_( Raster_Corrupted, 0x61, \ + "raster corrupted" ) + FT_ERRORDEF_( Raster_Overflow, 0x62, \ + "raster overflow" ) + FT_ERRORDEF_( Raster_Negative_Height, 0x63, \ + "negative height while rastering" ) /* cache errors */ - FT_ERRORDEF_( Too_Many_Caches, 0x70, "too many registered caches" ) + FT_ERRORDEF_( Too_Many_Caches, 0x70, \ + "too many registered caches" ) /* TrueType and SFNT errors */ - FT_ERRORDEF_( Invalid_Opcode, 0x80, "invalid opcode" ) - FT_ERRORDEF_( Too_Few_Arguments, 0x81, "too few arguments" ) - FT_ERRORDEF_( Stack_Overflow, 0x82, "stack overflow" ) - FT_ERRORDEF_( Code_Overflow, 0x83, "code overflow" ) - FT_ERRORDEF_( Bad_Argument, 0x84, "bad argument" ) - FT_ERRORDEF_( Divide_By_Zero, 0x85, "division by zero" ) - FT_ERRORDEF_( Invalid_Reference, 0x86, "invalid reference" ) - FT_ERRORDEF_( Debug_OpCode, 0x87, "found debug opcode" ) - FT_ERRORDEF_( ENDF_In_Exec_Stream, 0x88, "found ENDF opcode in execution stream" ) - FT_ERRORDEF_( Nested_DEFS, 0x89, "nested DEFS" ) - FT_ERRORDEF_( Invalid_CodeRange, 0x8A, "invalid code range" ) - FT_ERRORDEF_( Execution_Too_Long, 0x8B, "execution context too long" ) - FT_ERRORDEF_( Too_Many_Function_Defs, 0x8C, "too many function definitions" ) - FT_ERRORDEF_( Too_Many_Instruction_Defs, 0x8D, "too many instruction definitions" ) - FT_ERRORDEF_( Table_Missing, 0x8E, "SFNT font table missing" ) - FT_ERRORDEF_( Horiz_Header_Missing, 0x8F, "horizontal header (hhea) table missing" ) - FT_ERRORDEF_( Locations_Missing, 0x90, "locations (loca) table missing" ) - FT_ERRORDEF_( Name_Table_Missing, 0x91, "name table missing" ) - FT_ERRORDEF_( CMap_Table_Missing, 0x92, "character map (cmap) table missing" ) - FT_ERRORDEF_( Hmtx_Table_Missing, 0x93, "horizontal metrics (hmtx) table missing" ) - FT_ERRORDEF_( Post_Table_Missing, 0x94, "PostScript (post) table missing" ) - FT_ERRORDEF_( Invalid_Horiz_Metrics, 0x95, "invalid horizontal metrics" ) - FT_ERRORDEF_( Invalid_CharMap_Format, 0x96, "invalid character map (cmap) format" ) - FT_ERRORDEF_( Invalid_PPem, 0x97, "invalid ppem value" ) - FT_ERRORDEF_( Invalid_Vert_Metrics, 0x98, "invalid vertical metrics" ) - FT_ERRORDEF_( Could_Not_Find_Context, 0x99, "could not find context" ) - FT_ERRORDEF_( Invalid_Post_Table_Format, 0x9A, "invalid PostScript (post) table format" ) - FT_ERRORDEF_( Invalid_Post_Table, 0x9B, "invalid PostScript (post) table" ) + FT_ERRORDEF_( Invalid_Opcode, 0x80, \ + "invalid opcode" ) + FT_ERRORDEF_( Too_Few_Arguments, 0x81, \ + "too few arguments" ) + FT_ERRORDEF_( Stack_Overflow, 0x82, \ + "stack overflow" ) + FT_ERRORDEF_( Code_Overflow, 0x83, \ + "code overflow" ) + FT_ERRORDEF_( Bad_Argument, 0x84, \ + "bad argument" ) + FT_ERRORDEF_( Divide_By_Zero, 0x85, \ + "division by zero" ) + FT_ERRORDEF_( Invalid_Reference, 0x86, \ + "invalid reference" ) + FT_ERRORDEF_( Debug_OpCode, 0x87, \ + "found debug opcode" ) + FT_ERRORDEF_( ENDF_In_Exec_Stream, 0x88, \ + "found ENDF opcode in execution stream" ) + FT_ERRORDEF_( Nested_DEFS, 0x89, \ + "nested DEFS" ) + FT_ERRORDEF_( Invalid_CodeRange, 0x8A, \ + "invalid code range" ) + FT_ERRORDEF_( Execution_Too_Long, 0x8B, \ + "execution context too long" ) + FT_ERRORDEF_( Too_Many_Function_Defs, 0x8C, \ + "too many function definitions" ) + FT_ERRORDEF_( Too_Many_Instruction_Defs, 0x8D, \ + "too many instruction definitions" ) + FT_ERRORDEF_( Table_Missing, 0x8E, \ + "SFNT font table missing" ) + FT_ERRORDEF_( Horiz_Header_Missing, 0x8F, \ + "horizontal header (hhea) table missing" ) + FT_ERRORDEF_( Locations_Missing, 0x90, \ + "locations (loca) table missing" ) + FT_ERRORDEF_( Name_Table_Missing, 0x91, \ + "name table missing" ) + FT_ERRORDEF_( CMap_Table_Missing, 0x92, \ + "character map (cmap) table missing" ) + FT_ERRORDEF_( Hmtx_Table_Missing, 0x93, \ + "horizontal metrics (hmtx) table missing" ) + FT_ERRORDEF_( Post_Table_Missing, 0x94, \ + "PostScript (post) table missing" ) + FT_ERRORDEF_( Invalid_Horiz_Metrics, 0x95, \ + "invalid horizontal metrics" ) + FT_ERRORDEF_( Invalid_CharMap_Format, 0x96, \ + "invalid character map (cmap) format" ) + FT_ERRORDEF_( Invalid_PPem, 0x97, \ + "invalid ppem value" ) + FT_ERRORDEF_( Invalid_Vert_Metrics, 0x98, \ + "invalid vertical metrics" ) + FT_ERRORDEF_( Could_Not_Find_Context, 0x99, \ + "could not find context" ) + FT_ERRORDEF_( Invalid_Post_Table_Format, 0x9A, \ + "invalid PostScript (post) table format" ) + FT_ERRORDEF_( Invalid_Post_Table, 0x9B, \ + "invalid PostScript (post) table" ) /* CFF, CID, and Type 1 errors */ - FT_ERRORDEF_( Syntax_Error, 0xA0, "opcode syntax error" ) - FT_ERRORDEF_( Stack_Underflow, 0xA1, "argument stack underflow" ) + FT_ERRORDEF_( Syntax_Error, 0xA0, \ + "opcode syntax error" ) + FT_ERRORDEF_( Stack_Underflow, 0xA1, \ + "argument stack underflow" ) + FT_ERRORDEF_( Ignore, 0xA2, \ + "ignore" ) /* BDF errors */ - FT_ERRORDEF_( Missing_Startfont_Field, 0xB0, "`STARTFONT' field missing" ) - FT_ERRORDEF_( Missing_Font_Field, 0xB1, "`FONT' field missing" ) - FT_ERRORDEF_( Missing_Size_Field, 0xB2, "`SIZE' field missing" ) - FT_ERRORDEF_( Missing_Chars_Field, 0xB3, "`CHARS' field missing" ) - FT_ERRORDEF_( Missing_Startchar_Field, 0xB4, "`STARTCHAR' field missing" ) - FT_ERRORDEF_( Missing_Encoding_Field, 0xB5, "`ENCODING' field missing" ) - FT_ERRORDEF_( Missing_Bbx_Field, 0xB6, "`BBX' field missing" ) + FT_ERRORDEF_( Missing_Startfont_Field, 0xB0, \ + "`STARTFONT' field missing" ) + FT_ERRORDEF_( Missing_Font_Field, 0xB1, \ + "`FONT' field missing" ) + FT_ERRORDEF_( Missing_Size_Field, 0xB2, \ + "`SIZE' field missing" ) + FT_ERRORDEF_( Missing_Chars_Field, 0xB3, \ + "`CHARS' field missing" ) + FT_ERRORDEF_( Missing_Startchar_Field, 0xB4, \ + "`STARTCHAR' field missing" ) + FT_ERRORDEF_( Missing_Encoding_Field, 0xB5, \ + "`ENCODING' field missing" ) + FT_ERRORDEF_( Missing_Bbx_Field, 0xB6, \ + "`BBX' field missing" ) -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/fterrors.h b/headers/libs/freetype2/freetype/fterrors.h index 179d9964b1..1def4f9ce9 100644 --- a/headers/libs/freetype2/freetype/fterrors.h +++ b/headers/libs/freetype2/freetype/fterrors.h @@ -155,10 +155,12 @@ /* this macro is used to define an error */ -#define FT_ERRORDEF_( e, v, s ) FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v + FT_ERR_BASE, s ) +#define FT_ERRORDEF_( e, v, s ) \ + FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v + FT_ERR_BASE, s ) /* this is only used for FT_Err_Ok, which must be 0! */ -#define FT_NOERRORDEF_( e, v, s ) FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v, s ) +#define FT_NOERRORDEF_( e, v, s ) \ + FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v, s ) #ifdef FT_ERROR_START_LIST @@ -202,4 +204,4 @@ #endif /* __FTERRORS_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/ftglyph.h b/headers/libs/freetype2/freetype/ftglyph.h index cc180fb109..14050a21d9 100644 --- a/headers/libs/freetype2/freetype/ftglyph.h +++ b/headers/libs/freetype2/freetype/ftglyph.h @@ -4,7 +4,7 @@ /* */ /* FreeType convenience functions to handle glyphs (specification). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -36,6 +36,12 @@ #include #include FT_FREETYPE_H +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + FT_BEGIN_HEADER @@ -235,7 +241,8 @@ FT_BEGIN_HEADER /* FT_Glyph_Copy */ /* */ /* */ - /* A function used to copy a glyph image. */ + /* A function used to copy a glyph image. Note that the created */ + /* @FT_Glyph object must be released with @FT_Done_Glyph. */ /* */ /* */ /* source :: A handle to the source glyph object. */ @@ -282,7 +289,64 @@ FT_BEGIN_HEADER FT_Matrix* matrix, FT_Vector* delta ); - /* */ + + /*************************************************************************/ + /* */ + /* */ + /* FT_Glyph_BBox_Mode */ + /* */ + /* */ + /* The mode how the values of @FT_Glyph_Get_CBox are returned. */ + /* */ + /* */ + /* FT_GLYPH_BBOX_UNSCALED :: */ + /* Return unscaled font units. */ + /* */ + /* FT_GLYPH_BBOX_SUBPIXELS :: */ + /* Return unfitted 26.6 coordinates. */ + /* */ + /* FT_GLYPH_BBOX_GRIDFIT :: */ + /* Return grid-fitted 26.6 coordinates. */ + /* */ + /* FT_GLYPH_BBOX_TRUNCATE :: */ + /* Return coordinates in integer pixels. */ + /* */ + /* FT_GLYPH_BBOX_PIXELS :: */ + /* Return grid-fitted pixel coordinates. */ + /* */ + typedef enum FT_Glyph_BBox_Mode_ + { + FT_GLYPH_BBOX_UNSCALED = 0, + FT_GLYPH_BBOX_SUBPIXELS = 0, + FT_GLYPH_BBOX_GRIDFIT = 1, + FT_GLYPH_BBOX_TRUNCATE = 2, + FT_GLYPH_BBOX_PIXELS = 3 + + } FT_Glyph_BBox_Mode; + + + /*************************************************************************/ + /* */ + /* */ + /* ft_glyph_bbox_xxx */ + /* */ + /* */ + /* These constants are deprecated. Use the corresponding */ + /* @FT_Glyph_BBox_Mode values instead. */ + /* */ + /* */ + /* ft_glyph_bbox_unscaled :: see @FT_GLYPH_BBOX_UNSCALED */ + /* ft_glyph_bbox_subpixels :: see @FT_GLYPH_BBOX_SUBPIXELS */ + /* ft_glyph_bbox_gridfit :: see @FT_GLYPH_BBOX_GRIDFIT */ + /* ft_glyph_bbox_truncate :: see @FT_GLYPH_BBOX_TRUNCATE */ + /* ft_glyph_bbox_pixels :: see @FT_GLYPH_BBOX_PIXELS */ + /* */ +#define ft_glyph_bbox_unscaled FT_GLYPH_BBOX_UNSCALED +#define ft_glyph_bbox_subpixels FT_GLYPH_BBOX_SUBPIXELS +#define ft_glyph_bbox_gridfit FT_GLYPH_BBOX_GRIDFIT +#define ft_glyph_bbox_truncate FT_GLYPH_BBOX_TRUNCATE +#define ft_glyph_bbox_pixels FT_GLYPH_BBOX_PIXELS + /*************************************************************************/ /* */ @@ -316,11 +380,9 @@ FT_BEGIN_HEADER /* convention. */ /* */ /* If the glyph has been loaded with FT_LOAD_NO_SCALE, `bbox_mode' */ - /* must be set to `ft_glyph_bbox_unscaled' to get unscaled font */ - /* units. */ - /* */ - /* If `bbox_mode' is set to `ft_glyph_bbox_subpixels' the bbox */ - /* coordinates are returned in 26.6 pixels (i.e. 1/64th of pixels). */ + /* must be set to `FT_GLYPH_BBOX_UNSCALED' to get unscaled font */ + /* units in 26.6 pixel format. The value `FT_GLYPH_BBOX_SUBPIXELS' */ + /* is another name for this constant. */ /* */ /* Note that the maximum coordinates are exclusive, which means that */ /* one can compute the width and height of the glyph image (be it in */ @@ -330,7 +392,7 @@ FT_BEGIN_HEADER /* height = bbox.yMax - bbox.yMin; */ /* */ /* Note also that for 26.6 coordinates, if `bbox_mode' is set to */ - /* `ft_glyph_bbox_gridfit', the coordinates will also be grid-fitted, */ + /* `FT_GLYPH_BBOX_GRIDFIT', the coordinates will also be grid-fitted, */ /* which corresponds to: */ /* */ /* bbox.xMin = FLOOR(bbox.xMin); */ @@ -339,23 +401,11 @@ FT_BEGIN_HEADER /* bbox.yMax = CEILING(bbox.yMax); */ /* */ /* To get the bbox in pixel coordinates, set `bbox_mode' to */ - /* `ft_glyph_bbox_truncate'. */ + /* `FT_GLYPH_BBOX_TRUNCATE'. */ /* */ /* To get the bbox in grid-fitted pixel coordinates, set `bbox_mode' */ - /* to `ft_glyph_bbox_pixels'. */ + /* to `FT_GLYPH_BBOX_PIXELS'. */ /* */ - /* The default value for `bbox_mode' is `ft_glyph_bbox_pixels'. */ - /* */ - enum - { - ft_glyph_bbox_unscaled = 0, /* return unscaled font units */ - ft_glyph_bbox_subpixels = 0, /* return unfitted 26.6 coordinates */ - ft_glyph_bbox_gridfit = 1, /* return grid-fitted 26.6 coordinates */ - ft_glyph_bbox_truncate = 2, /* return coordinates in integer pixels */ - ft_glyph_bbox_pixels = 3 /* return grid-fitted pixel coordinates */ - }; - - FT_EXPORT( void ) FT_Glyph_Get_CBox( FT_Glyph glyph, FT_UInt bbox_mode, @@ -391,8 +441,7 @@ FT_BEGIN_HEADER /* */ /* */ /* The glyph image is translated with the `origin' vector before */ - /* rendering. In case of error, it it translated back to its */ - /* original position and the glyph is left untouched. */ + /* rendering. */ /* */ /* The first parameter is a pointer to a FT_Glyph handle, that will */ /* be replaced by this function. Typically, you would use (omitting */ @@ -413,7 +462,7 @@ FT_BEGIN_HEADER /* // convert to a bitmap (default render mode + destroy old) */ /* if ( glyph->format != FT_GLYPH_FORMAT_BITMAP ) */ /* { */ - /* error = FT_Glyph_To_Bitmap( &glyph, ft_render_mode_default, */ + /* error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_DEFAULT, */ /* 0, 1 ); */ /* if ( error ) // glyph unchanged */ /* ... */ @@ -430,8 +479,7 @@ FT_BEGIN_HEADER /* } */ /* */ /* */ - /* This function will always fail if the glyph's format isn't */ - /* scalable. */ + /* This function does nothing if the glyph format isn't scalable. */ /* */ FT_EXPORT( FT_Error ) FT_Glyph_To_Bitmap( FT_Glyph* the_glyph, @@ -514,4 +562,4 @@ FT_END_HEADER #endif /* __FTGLYPH_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/ftgzip.h b/headers/libs/freetype2/freetype/ftgzip.h index 63bde07741..5d7228bb49 100644 --- a/headers/libs/freetype2/freetype/ftgzip.h +++ b/headers/libs/freetype2/freetype/ftgzip.h @@ -4,7 +4,7 @@ /* */ /* Gzip-compressed stream support. */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,6 +22,13 @@ #include #include FT_FREETYPE_H +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + FT_BEGIN_HEADER /*************************************************************************/ @@ -40,47 +47,54 @@ FT_BEGIN_HEADER /* */ /*************************************************************************/ + /************************************************************************ * - * @type: FT_Stream_OpenGzip + * @function: + * FT_Stream_OpenGzip * * @description: - * open a new stream to parse gzip-compressed font files. This is + * Open a new stream to parse gzip-compressed font files. This is * mainly used to support the compressed *.pcf.gz fonts that come - * with XFree86 + * with XFree86. * * @input: - * stream :: target embedding stream - * source :: source stream, used to + * stream :: The target embedding stream. + * + * source :: The source stream. * * @return: - * error code. 0 means success + * FreeType error code. 0 means success. * * @note: - * the source stream must be opened _before_ calling this function. + * The source stream must be opened _before_ calling this function. * - * calling @FT_Stream_Close on the new stream will *not* call - * @FT_Stream_Close on the source stream. None of the stream objects - * will be released to the heap. + * Calling the internal function FT_Stream_Close on the new stream will + * *not* call FT_Stream_Close on the source stream. None of the stream + * objects will be released to the heap. * - * the stream implementation is very basic, and resets the decompression - * process each time seeking backwards is needed within the stream + * The stream implementation is very basic and resets the decompression + * process each time seeking backwards is needed within the stream. * - * in certain builds of the library, gzip compression recognition is - * automatic when calling @FT_New_Face or @FT_Open_Face. This means that - * if no font driver is capable of handling the raw compressed file, - * the library will try to open a gzip stream from it and re-open - * the face with it. + * In certain builds of the library, gzip compression recognition is + * automatically handled when calling @FT_New_Face or @FT_Open_Face. + * This means that if no font driver is capable of handling the raw + * compressed file, the library will try to open a gzipped stream from + * it and re-open the face with it. * - * this function may return "FT_Err_Unimplemented" if your build of + * This function may return "FT_Err_Unimplemented" if your build of * FreeType was not compiled with zlib support. */ FT_EXPORT( FT_Error ) - FT_Stream_OpenGzip( FT_Stream stream, - FT_Stream source ); + FT_Stream_OpenGzip( FT_Stream stream, + FT_Stream source ); /* */ + FT_END_HEADER -#endif /* __FTGZIP_H__ */ +#endif /* __FTGZIP_H__ */ + + +/* END */ diff --git a/headers/libs/freetype2/freetype/ftimage.h b/headers/libs/freetype2/freetype/ftimage.h index 5c7013352e..4682a4cada 100644 --- a/headers/libs/freetype2/freetype/ftimage.h +++ b/headers/libs/freetype2/freetype/ftimage.h @@ -5,7 +5,7 @@ /* FreeType glyph image formats and default raster interface */ /* (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -53,8 +53,8 @@ FT_BEGIN_HEADER /* */ /* The type FT_Pos is a 32-bit integer used to store vectorial */ /* coordinates. Depending on the context, these can represent */ - /* distances in integer font units, or 26.6 fixed float pixel */ - /* coordinates. */ + /* distances in integer font units, or 16,16, or 26.6 fixed float */ + /* pixel coordinates. */ /* */ typedef signed long FT_Pos; @@ -261,7 +261,8 @@ FT_BEGIN_HEADER /* `FT_PIXEL_MODE_GRAY'; it gives the number of gray */ /* levels used in the bitmap. */ /* */ - /* pixel_mode :: The pixel_mode, i.e., how pixel bits are stored. */ + /* pixel_mode :: The pixel mode, i.e., how pixel bits are stored. */ + /* See @FT_Pixel_Mode for possible values. */ /* */ /* palette_mode :: This field is only used with paletted pixel modes; */ /* it indicates how the palette is stored. */ @@ -357,11 +358,11 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ /* */ - /* FT_Outline_Flags */ + /* FT_OUTLINE_FLAGS */ /* */ /* */ - /* A simple type used to enumerates the flags in an outline's */ - /* `outline_flags' field. */ + /* A list of bit-field constants use for the flags in an outline's */ + /* `flags' field. */ /* */ /* */ /* FT_OUTLINE_NONE :: Value 0 is reserved. */ @@ -414,27 +415,24 @@ FT_BEGIN_HEADER /* completely ignored by a given */ /* scan-converter. */ /* */ - typedef enum FT_Outline_Flags_ - { - FT_OUTLINE_NONE = 0, - FT_OUTLINE_OWNER = 1, - FT_OUTLINE_EVEN_ODD_FILL = 2, - FT_OUTLINE_REVERSE_FILL = 4, - FT_OUTLINE_IGNORE_DROPOUTS = 8, - FT_OUTLINE_HIGH_PRECISION = 256, - FT_OUTLINE_SINGLE_PASS = 512 +#define FT_OUTLINE_NONE 0x0 +#define FT_OUTLINE_OWNER 0x1 +#define FT_OUTLINE_EVEN_ODD_FILL 0x2 +#define FT_OUTLINE_REVERSE_FILL 0x4 +#define FT_OUTLINE_IGNORE_DROPOUTS 0x8 - } FT_Outline_Flags; +#define FT_OUTLINE_HIGH_PRECISION 0x100 +#define FT_OUTLINE_SINGLE_PASS 0x200 /************************************************************************* * * @enum: - * ft_outline_xxx + * ft_outline_flags * * @description: * These constants are deprecated. Please use the corresponding - * @FT_OUTLINE_XXX values. + * @FT_OUTLINE_FLAGS values. * * @values: * ft_outline_none :: See @FT_OUTLINE_NONE. @@ -659,7 +657,7 @@ FT_BEGIN_HEADER /* should redefine this macro in case of problems to something like */ /* this: */ /* */ - /* #define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 ) (value) */ + /* #define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 ) value */ /* */ /* to get a simple enumeration without assigning special numbers. */ /* */ @@ -689,8 +687,8 @@ FT_BEGIN_HEADER /* */ /* FT_GLYPH_FORMAT_COMPOSITE :: */ /* The glyph image is a composite of several other images. This */ - /* format is _only_ used with @FT_LOAD_FLAG_NO_RECURSE, and is */ - /* used to report compound glyphs (like accented characters). */ + /* format is _only_ used with @FT_LOAD_NO_RECURSE, and is used to */ + /* report compound glyphs (like accented characters). */ /* */ /* FT_GLYPH_FORMAT_BITMAP :: */ /* The glyph image is a bitmap, and can be described as an */ @@ -937,11 +935,11 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ /* */ - /* FT_Raster_Flag */ + /* FT_RASTER_FLAG_XXX */ /* */ /* */ - /* An enumeration to list the bit flags as used in the `flags' field */ - /* of a FT_Raster_Params structure. */ + /* A list of bit flag constants as used in the `flags' field of a */ + /* @FT_Raster_Params structure. */ /* */ /* */ /* FT_RASTER_FLAG_DEFAULT :: This value is 0. */ @@ -949,7 +947,7 @@ FT_BEGIN_HEADER /* FT_RASTER_FLAG_AA :: This flag is set to indicate that an */ /* anti-aliased glyph image should be */ /* generated. Otherwise, it will be */ - /* monochrome (1-bit) */ + /* monochrome (1-bit). */ /* */ /* FT_RASTER_FLAG_DIRECT :: This flag is set to indicate direct */ /* rendering. In this mode, client */ @@ -974,15 +972,12 @@ FT_BEGIN_HEADER /* in direct rendering mode where all spans */ /* are generated if no clipping box is set. */ /* */ - typedef enum - { - FT_RASTER_FLAG_DEFAULT = 0, - FT_RASTER_FLAG_AA = 1, - FT_RASTER_FLAG_DIRECT = 2, - FT_RASTER_FLAG_CLIP = 4 - - } FT_Raster_Flag; +#define FT_RASTER_FLAG_DEFAULT 0x0 +#define FT_RASTER_FLAG_AA 0x1 +#define FT_RASTER_FLAG_DIRECT 0x2 +#define FT_RASTER_FLAG_CLIP 0x4 + /* deprecated */ #define ft_raster_flag_default FT_RASTER_FLAG_DEFAULT #define ft_raster_flag_aa FT_RASTER_FLAG_AA #define ft_raster_flag_direct FT_RASTER_FLAG_DIRECT @@ -1238,4 +1233,4 @@ FT_END_HEADER #endif /* __FTIMAGE_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/ftincrem.h b/headers/libs/freetype2/freetype/ftincrem.h index 53f8a82ee8..6a1aa1fc31 100644 --- a/headers/libs/freetype2/freetype/ftincrem.h +++ b/headers/libs/freetype2/freetype/ftincrem.h @@ -4,7 +4,7 @@ /* */ /* FreeType incremental loading (specification). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,6 +22,12 @@ #include #include FT_FREETYPE_H +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + FT_BEGIN_HEADER @@ -186,10 +192,10 @@ FT_BEGIN_HEADER */ typedef FT_Error (*FT_Incremental_GetGlyphMetricsFunc) - ( FT_Incremental incremental, - FT_UInt glyph_index, - FT_Bool vertical, - FT_Incremental_MetricsRec *ametrics ); + ( FT_Incremental incremental, + FT_UInt glyph_index, + FT_Bool vertical, + FT_Incremental_MetricsRec *ametrics ); /************************************************************************** @@ -199,7 +205,7 @@ FT_BEGIN_HEADER * * @description: * A table of functions for accessing fonts that load data - * incrementally. Used in @FT_Incremental_Interface. + * incrementally. Used in @FT_Incremental_InterfaceRec. * * @fields: * get_glyph_data :: @@ -246,8 +252,7 @@ FT_BEGIN_HEADER * parameter.data = &inc_int; * * // set up FT_Open_Args structure - * open_args.flags = (FT_Open_Flags)( FT_OPEN_PATHNAME | - * FT_OPEN_PARAMS ); + * open_args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS; * open_args.pathname = my_font_pathname; * open_args.num_params = 1; * open_args.params = ¶meter; // we use one optional argument @@ -284,4 +289,4 @@ FT_END_HEADER #endif /* __FTINCREM_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/ftlist.h b/headers/libs/freetype2/freetype/ftlist.h index 35b508e3fb..ae9801b9d8 100644 --- a/headers/libs/freetype2/freetype/ftlist.h +++ b/headers/libs/freetype2/freetype/ftlist.h @@ -4,7 +4,7 @@ /* */ /* Generic list support for FreeType (specification). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2001, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -31,6 +31,12 @@ #include #include FT_FREETYPE_H +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + FT_BEGIN_HEADER @@ -265,4 +271,4 @@ FT_END_HEADER #endif /* __FTLIST_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/ftlzw.h b/headers/libs/freetype2/freetype/ftlzw.h new file mode 100644 index 0000000000..a0a042ea07 --- /dev/null +++ b/headers/libs/freetype2/freetype/ftlzw.h @@ -0,0 +1,99 @@ +/***************************************************************************/ +/* */ +/* ftlzw.h */ +/* */ +/* LZW-compressed stream support. */ +/* */ +/* Copyright 2004 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. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTLZW_H__ +#define __FTLZW_H__ + +#include +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + /*************************************************************************/ + /* */ + /*
*/ + /* lzw */ + /* */ + /* */ + /* LZW Streams */ + /* */ + /* <Abstract> */ + /* Using LZW-compressed font files */ + /* */ + /* <Description> */ + /* This section contains the declaration of LZW-specific functions. */ + /* */ + /*************************************************************************/ + + /************************************************************************ + * + * @function: + * FT_Stream_OpenLZW + * + * @description: + * Open a new stream to parse LZW-compressed font files. This is + * mainly used to support the compressed *.pcf.Z fonts that come + * with XFree86. + * + * @input: + * stream :: The target embedding stream. + * + * source :: The source stream. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * The source stream must be opened _before_ calling this function. + * + * Calling the internal function FT_Stream_Close on the new stream will + * *not* call FT_Stream_Close on the source stream. None of the stream + * objects will be released to the heap. + * + * The stream implementation is very basic and resets the decompression + * process each time seeking backwards is needed within the stream + * + * In certain builds of the library, LZW compression recognition is + * automatically handled when calling @FT_New_Face or @FT_Open_Face. + * This means that if no font driver is capable of handling the raw + * compressed file, the library will try to open a LZW stream from it + * and re-open the face with it. + * + * This function may return "FT_Err_Unimplemented" if your build of + * FreeType was not compiled with LZW support. + */ + FT_EXPORT( FT_Error ) + FT_Stream_OpenLZW( FT_Stream stream, + FT_Stream source ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTLZW_H__ */ + + +/* END */ diff --git a/headers/libs/freetype2/freetype/ftmac.h b/headers/libs/freetype2/freetype/ftmac.h index 02b8a8bcf0..78ed779478 100644 --- a/headers/libs/freetype2/freetype/ftmac.h +++ b/headers/libs/freetype2/freetype/ftmac.h @@ -4,7 +4,7 @@ /* */ /* Additional Mac-specific API. */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2001, 2004 by */ /* Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -111,10 +111,44 @@ FT_BEGIN_HEADER /* <Return> */ /* FreeType error code. 0 means success. */ /* */ - FT_EXPORT_DEF( FT_Error ) - FT_GetFile_From_Mac_Name( char* fontName, - FSSpec* pathSpec, - FT_Long* face_index ); + FT_EXPORT( FT_Error ) + FT_GetFile_From_Mac_Name( const char* fontName, + FSSpec* pathSpec, + FT_Long* face_index ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Face_From_FSSpec */ + /* */ + /* <Description> */ + /* Creates a new face object from a given resource and typeface index */ + /* using an FSSpec to the font file. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* spec :: FSSpec to the font file. */ + /* */ + /* face_index :: The index of the face within the resource. The */ + /* first face has index 0. */ + /* <Output> */ + /* aface :: A handle to a new face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* @FT_New_Face_From_FSSpec is identical to @FT_New_Face except */ + /* it accepts an FSSpec instead of a path. */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Face_From_FSSpec( FT_Library library, + const FSSpec *spec, + FT_Long face_index, + FT_Face *aface ); /* */ @@ -125,4 +159,4 @@ FT_END_HEADER #endif /* __FTMAC_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/ftmm.h b/headers/libs/freetype2/freetype/ftmm.h index 6a9cdc63af..7f565bef94 100644 --- a/headers/libs/freetype2/freetype/ftmm.h +++ b/headers/libs/freetype2/freetype/ftmm.h @@ -100,21 +100,6 @@ FT_BEGIN_HEADER /* */ - typedef FT_Error - (*FT_Get_MM_Func)( FT_Face face, - FT_Multi_Master* master ); - - typedef FT_Error - (*FT_Set_MM_Design_Func)( FT_Face face, - FT_UInt num_coords, - FT_Long* coords ); - - typedef FT_Error - (*FT_Set_MM_Blend_Func)( FT_Face face, - FT_UInt num_coords, - FT_Long* coords ); - - /*************************************************************************/ /* */ /* <Function> */ @@ -200,4 +185,4 @@ FT_END_HEADER #endif /* __FTMM_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/ftmodule.h b/headers/libs/freetype2/freetype/ftmodapi.h similarity index 90% rename from headers/libs/freetype2/freetype/ftmodule.h rename to headers/libs/freetype2/freetype/ftmodapi.h index 32be39c74d..1929ca025d 100644 --- a/headers/libs/freetype2/freetype/ftmodule.h +++ b/headers/libs/freetype2/freetype/ftmodapi.h @@ -1,10 +1,10 @@ /***************************************************************************/ /* */ -/* ftmodule.h */ +/* ftmodapi.h */ /* */ /* FreeType modules public interface (specification). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,13 +16,19 @@ /***************************************************************************/ -#ifndef __FTMODULE_H__ -#define __FTMODULE_H__ +#ifndef __FTMODAPI_H__ +#define __FTMODAPI_H__ #include <ft2build.h> #include FT_FREETYPE_H +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + FT_BEGIN_HEADER @@ -46,25 +52,31 @@ FT_BEGIN_HEADER /* module bit flags */ - typedef enum FT_Module_Flags_ - { - ft_module_font_driver = 1, /* this module is a font driver */ - ft_module_renderer = 2, /* this module is a renderer */ - ft_module_hinter = 4, /* this module is a glyph hinter */ - ft_module_styler = 8, /* this module is a styler */ +#define FT_MODULE_FONT_DRIVER 1 /* this module is a font driver */ +#define FT_MODULE_RENDERER 2 /* this module is a renderer */ +#define FT_MODULE_HINTER 4 /* this module is a glyph hinter */ +#define FT_MODULE_STYLER 8 /* this module is a styler */ - ft_module_driver_scalable = 0x100, /* the driver supports scalable */ - /* fonts */ - ft_module_driver_no_outlines = 0x200, /* the driver does not support */ - /* vector outlines */ - ft_module_driver_has_hinter = 0x400 /* the driver provides its own */ - /* hinter */ - - } FT_Module_Flags; +#define FT_MODULE_DRIVER_SCALABLE 0x100 /* the driver supports */ + /* scalable fonts */ +#define FT_MODULE_DRIVER_NO_OUTLINES 0x200 /* the driver does not */ + /* support vector outlines */ +#define FT_MODULE_DRIVER_HAS_HINTER 0x400 /* the driver provides its */ + /* own hinter */ - typedef void - (*FT_Module_Interface)( void ); + /* deprecated values */ +#define ft_module_font_driver FT_MODULE_FONT_DRIVER +#define ft_module_renderer FT_MODULE_RENDERER +#define ft_module_hinter FT_MODULE_HINTER +#define ft_module_styler FT_MODULE_STYLER + +#define ft_module_driver_scalable FT_MODULE_DRIVER_SCALABLE +#define ft_module_driver_no_outlines FT_MODULE_DRIVER_NO_OUTLINES +#define ft_module_driver_has_hinter FT_MODULE_DRIVER_HAS_HINTER + + + typedef FT_Pointer FT_Module_Interface; typedef FT_Error (*FT_Module_Constructor)( FT_Module module ); @@ -72,7 +84,7 @@ FT_BEGIN_HEADER typedef void (*FT_Module_Destructor)( FT_Module module ); - typedef FT_Module_Interface + typedef FT_Module_Interface (*FT_Module_Requester)( FT_Module module, const char* name ); @@ -301,7 +313,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTMODULE_H__ */ +#endif /* __FTMODAPI_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/ftmoderr.h b/headers/libs/freetype2/freetype/ftmoderr.h index ef7fe0c955..d190167fa7 100644 --- a/headers/libs/freetype2/freetype/ftmoderr.h +++ b/headers/libs/freetype2/freetype/ftmoderr.h @@ -4,7 +4,7 @@ /* */ /* FreeType module error offsets (specification). */ /* */ -/* Copyright 2001, 2002 by */ +/* Copyright 2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,8 +23,8 @@ /* The lower byte gives the error code, the higher byte gives the */ /* module. The base module has error offset 0. For example, the error */ /* `FT_Err_Invalid_File_Format' has value 0x003, the error */ - /* `TT_Err_Invalid_File_Format' has value 0xB03, the error */ - /* `T1_Err_Invalid_File_Format' has value 0xC03, etc. */ + /* `TT_Err_Invalid_File_Format' has value 0x1003, the error */ + /* `T1_Err_Invalid_File_Format' has value 0x1103, etc. */ /* */ /* Undefine the macro FT_CONFIG_OPTION_USE_MODULE_ERRORS in ftoption.h */ /* to make the higher byte always zero (disabling the module error */ @@ -102,21 +102,26 @@ #endif - FT_MODERRDEF( Base, 0x000, "base module" ) - FT_MODERRDEF( Autohint, 0x100, "autohinter module" ) - FT_MODERRDEF( Cache, 0x200, "cache module" ) - FT_MODERRDEF( CFF, 0x300, "CFF module" ) - FT_MODERRDEF( CID, 0x400, "CID module" ) - FT_MODERRDEF( PCF, 0x500, "PCF module" ) - FT_MODERRDEF( PSaux, 0x600, "PS auxiliary module" ) - FT_MODERRDEF( PSnames, 0x700, "PS names module" ) - FT_MODERRDEF( Raster, 0x800, "raster module" ) - FT_MODERRDEF( SFNT, 0x900, "SFNT module" ) - FT_MODERRDEF( Smooth, 0xA00, "smooth raster module" ) - FT_MODERRDEF( TrueType, 0xB00, "TrueType module" ) - FT_MODERRDEF( Type1, 0xC00, "Type 1 module" ) - FT_MODERRDEF( Winfonts, 0xD00, "Windows FON/FNT module" ) - FT_MODERRDEF( PFR, 0xE00, "PFR module" ) + FT_MODERRDEF( Base, 0x000, "base module" ) + FT_MODERRDEF( Autohint, 0x100, "autohinter module" ) + FT_MODERRDEF( BDF, 0x200, "BDF module" ) + FT_MODERRDEF( Cache, 0x300, "cache module" ) + FT_MODERRDEF( CFF, 0x400, "CFF module" ) + FT_MODERRDEF( CID, 0x500, "CID module" ) + FT_MODERRDEF( Gzip, 0x600, "Gzip module" ) + FT_MODERRDEF( LZW, 0x700, "LZW module" ) + FT_MODERRDEF( PCF, 0x800, "PCF module" ) + FT_MODERRDEF( PFR, 0x900, "PFR module" ) + FT_MODERRDEF( PSaux, 0xA00, "PS auxiliary module" ) + FT_MODERRDEF( PShinter, 0xB00, "PS hinter module" ) + FT_MODERRDEF( PSnames, 0xC00, "PS names module" ) + FT_MODERRDEF( Raster, 0xD00, "raster module" ) + FT_MODERRDEF( SFNT, 0xE00, "SFNT module" ) + FT_MODERRDEF( Smooth, 0xF00, "smooth raster module" ) + FT_MODERRDEF( TrueType, 0x1000, "TrueType module" ) + FT_MODERRDEF( Type1, 0x1100, "Type 1 module" ) + FT_MODERRDEF( Type42, 0x1200, "Type 42 module" ) + FT_MODERRDEF( Winfonts, 0x1300, "Windows FON/FNT module" ) #ifdef FT_MODERR_END_LIST @@ -146,4 +151,4 @@ #endif /* __FTMODERR_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/ftoutln.h b/headers/libs/freetype2/freetype/ftoutln.h index 555c05891f..79ed35b597 100644 --- a/headers/libs/freetype2/freetype/ftoutln.h +++ b/headers/libs/freetype2/freetype/ftoutln.h @@ -5,7 +5,7 @@ /* Support for the FT_Outline type used to store glyph shapes of */ /* most scalable font formats (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,6 +24,12 @@ #include <ft2build.h> #include FT_FREETYPE_H +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + FT_BEGIN_HEADER @@ -46,7 +52,7 @@ FT_BEGIN_HEADER /* */ /* <Order> */ /* FT_Outline */ - /* FT_Outline_Flags */ + /* FT_OUTLINE_FLAGS */ /* FT_Outline_New */ /* FT_Outline_Done */ /* FT_Outline_Copy */ @@ -389,6 +395,72 @@ FT_BEGIN_HEADER FT_Raster_Params* params ); + /************************************************************************** + * + * @enum: + * FT_Orientation + * + * @description: + * A list of values used to describe an outline's contour orientation. + * + * The TrueType and Postscript specifications use different conventions + * to determine whether outline contours should be filled or unfilled. + * + * @values: + * FT_ORIENTATION_TRUETYPE :: + * According to the TrueType specification, clockwise contours must + * be filled, and counter-clockwise ones must be unfilled. + * + * FT_ORIENTATION_POSTSCRIPT :: + * According to the Postscript specification, counter-clockwise contours + * must be filled, and clockwise ones must be unfilled. + * + * FT_ORIENTATION_FILL_RIGHT :: + * This is identical to @FT_ORIENTATION_TRUETYPE, but is used to + * remember that in TrueType, everything that is to the right of + * the drawing direction of a contour must be filled. + * + * FT_ORIENTATION_FILL_LEFT :: + * This is identical to @FT_ORIENTATION_POSTSCRIPT, but is used to + * remember that in Postscript, everything that is to the left of + * the drawing direction of a contour must be filled. + */ + typedef enum + { + FT_ORIENTATION_TRUETYPE = 0, + FT_ORIENTATION_POSTSCRIPT = 1, + FT_ORIENTATION_FILL_RIGHT = FT_ORIENTATION_TRUETYPE, + FT_ORIENTATION_FILL_LEFT = FT_ORIENTATION_POSTSCRIPT + + } FT_Orientation; + + + /************************************************************************** + * + * @function: + * FT_Outline_Get_Orientation + * + * @description: + * This function analyzes a glyph outline and tries to compute its + * fill orientation (see @FT_Orientation). This is done by computing + * the direction of each global horizontal and/or vertical extrema + * within the outline. + * + * Note that this will return @FT_ORIENTATION_TRUETYPE for empty + * outlines. + * + * @input: + * outline :: + * A handle to the source outline. + * + * @return: + * The orientation. + * + */ + FT_EXPORT( FT_Orientation ) + FT_Outline_Get_Orientation( FT_Outline* outline ); + + /* */ @@ -397,4 +469,4 @@ FT_END_HEADER #endif /* __FTOUTLN_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/ftpfr.h b/headers/libs/freetype2/freetype/ftpfr.h index e3a8f39695..c9a5675445 100644 --- a/headers/libs/freetype2/freetype/ftpfr.h +++ b/headers/libs/freetype2/freetype/ftpfr.h @@ -2,9 +2,9 @@ /* */ /* ftpfr.h */ /* */ -/* FreeType API for accessing PFR-specific data */ +/* FreeType API for accessing PFR-specific data (specification only). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,6 +22,12 @@ #include <ft2build.h> #include FT_FREETYPE_H +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + FT_BEGIN_HEADER @@ -49,42 +55,44 @@ FT_BEGIN_HEADER * FT_Get_PFR_Metrics * * @description: - * returns the outline and metrics resolutions of a given PFR - * face. + * Return the outline and metrics resolutions of a given PFR face. * * @input: - * face :: handle to input face. It can be a non-PFR face. + * face :: Handle to the input face. It can be a non-PFR face. * * @output: * aoutline_resolution :: - * outline resolution. This is equivalent to "face->units_per_EM". - * optional (parameter can be NULL) + * Outline resolution. This is equivalent to `face->units_per_EM'. + * Optional (parameter can be NULL). * * ametrics_resolution :: - * metrics_resolution. This is equivalent to "outline_resolution" - * for non-PFR fonts. can be NULL - * optional (parameter can be NULL) + * Metrics resolution. This is equivalent to `outline_resolution' + * for non-PFR fonts. Optional (parameter can be NULL). * * ametrics_x_scale :: - * a 16.16 fixed-point number used to scale distance expressed - * in metrics units to device sub-pixels. This is equivalent to - * 'face->size->x_scale', but for metrics only. - * optional (parameter can be NULL) + * A 16.16 fixed-point number used to scale distance expressed + * in metrics units to device sub-pixels. This is equivalent to + * `face->size->x_scale', but for metrics only. Optional (parameter + * can be NULL) * * ametrics_y_scale :: - * same as 'ametrics_x_scale', but for the vertical direction. + * Same as `ametrics_x_scale' but for the vertical direction. * optional (parameter can be NULL) * + * @return: + * FreeType error code. 0 means success. + * * @note: - * if the input face is not a PFR, this function will return an error. + * If the input face is not a PFR, this function will return an error. * However, in all cases, it will return valid values. */ FT_EXPORT( FT_Error ) - FT_Get_PFR_Metrics( FT_Face face, - FT_UInt *aoutline_resolution, - FT_UInt *ametrics_resolution, - FT_Fixed *ametrics_x_scale, - FT_Fixed *ametrics_y_scale ); + FT_Get_PFR_Metrics( FT_Face face, + FT_UInt *aoutline_resolution, + FT_UInt *ametrics_resolution, + FT_Fixed *ametrics_x_scale, + FT_Fixed *ametrics_y_scale ); + /********************************************************************** * @@ -92,25 +100,30 @@ FT_BEGIN_HEADER * FT_Get_PFR_Kerning * * @description: - * returns the kerning pair corresponding to two glyphs in - * a PFR face. The distance is expressed in metrics units, unlike - * the result of @FT_Get_Kerning. + * Return the kerning pair corresponding to two glyphs in a PFR face. + * The distance is expressed in metrics units, unlike the result of + * @FT_Get_Kerning. * * @input: - * face :: handle to input face. - * left :: left glyph index - * right :: right glyph index + * face :: A handle to the input face. + * + * left :: Index of the left glyph. + * + * right :: Index of the right glyph. * * @output: - * avector :: kerning vector + * avector :: A kerning vector. + * + * @return: + * FreeType error code. 0 means success. * * @note: - * this function always return distances in original PFR metrics - * units. This is unlike @FT_Get_Kerning with the @FT_KERNING_UNSCALED - * mode, which always return distances converted to outline units. + * This function always return distances in original PFR metrics + * units. This is unlike @FT_Get_Kerning with the @FT_KERNING_UNSCALED + * mode, which always returns distances converted to outline units. * - * you can use the value of the 'x_scale' and 'y_scale' parameters - * returned by @FT_Get_PFR_Metrics to scale these to device sub-pixels + * You can use the value of the `x_scale' and `y_scale' parameters + * returned by @FT_Get_PFR_Metrics to scale these to device sub-pixels. */ FT_EXPORT( FT_Error ) FT_Get_PFR_Kerning( FT_Face face, @@ -118,39 +131,42 @@ FT_BEGIN_HEADER FT_UInt right, FT_Vector *avector ); + /********************************************************************** * * @function: * FT_Get_PFR_Advance * * @description: - * returns a given glyph advance, expressed in original metrics units, + * Return a given glyph advance, expressed in original metrics units, * from a PFR font. * * @input: - * face :: handle to input face. - * gindex :: glyph index + * face :: A handle to the input face. + * + * gindex :: The glyph index. * * @output: - * aadvance :: glyph advance in metrics units + * aadvance :: The glyph advance in metrics units. * * @return: - * error code. 0 means success + * FreeType error code. 0 means success. * * @note: - * you can use the 'x_scale' or 'y_scale' results of @FT_Get_PFR_Metrics - * to convert the advance to device sub-pixels (i.e. 1/64th of pixels) + * You can use the `x_scale' or `y_scale' results of @FT_Get_PFR_Metrics + * to convert the advance to device sub-pixels (i.e. 1/64th of pixels). */ FT_EXPORT( FT_Error ) - FT_Get_PFR_Advance( FT_Face face, - FT_UInt gindex, - FT_Pos *aadvance ); + FT_Get_PFR_Advance( FT_Face face, + FT_UInt gindex, + FT_Pos *aadvance ); /* */ + FT_END_HEADER #endif /* __FTBDF_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/ftrender.h b/headers/libs/freetype2/freetype/ftrender.h index 8e12cb23fa..db3ca94dd7 100644 --- a/headers/libs/freetype2/freetype/ftrender.h +++ b/headers/libs/freetype2/freetype/ftrender.h @@ -226,4 +226,4 @@ FT_END_HEADER #endif /* __FTRENDER_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/ftsizes.h b/headers/libs/freetype2/freetype/ftsizes.h index 350f3e4c83..f0ec915997 100644 --- a/headers/libs/freetype2/freetype/ftsizes.h +++ b/headers/libs/freetype2/freetype/ftsizes.h @@ -4,7 +4,7 @@ /* */ /* FreeType size objects management (specification). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2001, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -32,6 +32,12 @@ #include <ft2build.h> #include FT_FREETYPE_H +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + FT_BEGIN_HEADER @@ -101,7 +107,9 @@ FT_BEGIN_HEADER /* FT_Done_Size */ /* */ /* <Description> */ - /* Discards a given size object. */ + /* Discards a given size object. Note that @FT_Done_Face */ + /* automatically discards all size objects allocated with */ + /* @FT_New_Size. */ /* */ /* <Input> */ /* size :: A handle to a target size object. */ @@ -148,4 +156,4 @@ FT_END_HEADER #endif /* __FTSIZES_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/ftsnames.h b/headers/libs/freetype2/freetype/ftsnames.h index dbc76f0970..0e2d9a4adc 100644 --- a/headers/libs/freetype2/freetype/ftsnames.h +++ b/headers/libs/freetype2/freetype/ftsnames.h @@ -7,7 +7,7 @@ /* */ /* This is _not_ used to retrieve glyph names! */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -26,6 +26,12 @@ #include <ft2build.h> #include FT_FREETYPE_H +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + FT_BEGIN_HEADER @@ -158,4 +164,4 @@ FT_END_HEADER #endif /* __FT_SFNT_NAMES_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/ftstroke.h b/headers/libs/freetype2/freetype/ftstroke.h new file mode 100644 index 0000000000..a3052e858e --- /dev/null +++ b/headers/libs/freetype2/freetype/ftstroke.h @@ -0,0 +1,686 @@ +/***************************************************************************/ +/* */ +/* ftstroke.h */ +/* */ +/* FreeType path stroker (specification). */ +/* */ +/* Copyright 2002, 2003, 2004 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. */ +/* */ +/***************************************************************************/ + + +#ifndef __FT_STROKE_H__ +#define __FT_STROKE_H__ + +#include <ft2build.h> +#include FT_OUTLINE_H +#include FT_GLYPH_H + +FT_BEGIN_HEADER + + /*@************************************************************* + * + * @type: + * FT_Stroker + * + * @description: + * Opaque handler to a path stroker object. + */ + typedef struct FT_StrokerRec_* FT_Stroker; + + + /*@************************************************************* + * + * @enum: + * FT_Stroker_LineJoin + * + * @description: + * These values determine how two joining lines are rendered + * in a stroker. + * + * @values: + * FT_STROKER_LINEJOIN_ROUND :: + * Used to render rounded line joins. Circular arcs are used + * to join two lines smoothly. + * + * FT_STROKER_LINEJOIN_BEVEL :: + * Used to render beveled line joins; i.e., the two joining lines + * are extended until they intersect. + * + * FT_STROKER_LINEJOIN_MITER :: + * Same as beveled rendering, except that an additional line + * break is added if the angle between the two joining lines + * is too closed (this is useful to avoid unpleasant spikes + * in beveled rendering). + */ + typedef enum + { + FT_STROKER_LINEJOIN_ROUND = 0, + FT_STROKER_LINEJOIN_BEVEL, + FT_STROKER_LINEJOIN_MITER + + } FT_Stroker_LineJoin; + + + /*@************************************************************* + * + * @enum: + * FT_Stroker_LineCap + * + * @description: + * These values determine how the end of opened sub-paths are + * rendered in a stroke. + * + * @values: + * FT_STROKER_LINECAP_BUTT :: + * The end of lines is rendered as a full stop on the last + * point itself. + * + * FT_STROKER_LINECAP_ROUND :: + * The end of lines is rendered as a half-circle around the + * last point. + * + * FT_STROKER_LINECAP_SQUARE :: + * The end of lines is rendered as a square around the + * last point. + */ + typedef enum + { + FT_STROKER_LINECAP_BUTT = 0, + FT_STROKER_LINECAP_ROUND, + FT_STROKER_LINECAP_SQUARE + + } FT_Stroker_LineCap; + + + /************************************************************** + * + * @enum: + * FT_StrokerBorder + * + * @description: + * These values are used to select a given stroke border + * in @FT_Stroker_GetBorderCounts and @FT_Stroker_ExportBorder. + * + * @values: + * FT_STROKER_BORDER_LEFT :: + * Select the left border, relative to the drawing direction. + * + * FT_STROKER_BORDER_RIGHT :: + * Select the right border, relative to the drawing direction. + * + * @note: + * Applications are generally interested in the `inside' and `outside' + * borders. However, there is no direct mapping between these and + * the `left' / `right' ones, since this really depends on the glyph's + * drawing orientation, which varies between font formats. + * + * You can however use @FT_Outline_GetInsideBorder and + * @FT_Outline_GetOutsideBorder to get these. + */ + typedef enum + { + FT_STROKER_BORDER_LEFT = 0, + FT_STROKER_BORDER_RIGHT + + } FT_StrokerBorder; + + + /************************************************************** + * + * @function: + * FT_Outline_GetInsideBorder + * + * @description: + * Retrieve the @FT_StrokerBorder value corresponding to the + * `inside' borders of a given outline. + * + * @input: + * outline :: + * The source outline handle. + * + * @return: + * The border index. @FT_STROKER_BORDER_LEFT for empty or invalid + * outlines. + */ + FT_EXPORT( FT_StrokerBorder ) + FT_Outline_GetInsideBorder( FT_Outline* outline ); + + + /************************************************************** + * + * @function: + * FT_Outline_GetOutsideBorder + * + * @description: + * Retrieve the @FT_StrokerBorder value corresponding to the + * `outside' borders of a given outline. + * + * @input: + * outline :: + * The source outline handle. + * + * @return: + * The border index. @FT_STROKER_BORDER_LEFT for empty or invalid + * outlines. + */ + FT_EXPORT( FT_StrokerBorder ) + FT_Outline_GetOutsideBorder( FT_Outline* outline ); + + + /************************************************************** + * + * @function: + * FT_Stroker_New + * + * @description: + * Create a new stroker object. + * + * @input: + * memory :: + * The memory manager handle. + * + * @output: + * A new stroker object handle. NULL in case of error. + * + * @return: + * FreeType error code. 0 means success. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_New( FT_Memory memory, + FT_Stroker *astroker ); + + + /************************************************************** + * + * @function: + * FT_Stroker_Set + * + * @description: + * Reset a stroker object's attributes. + * + * @input: + * stroker :: + * The target stroker handle. + * + * radius :: + * The border radius. + * + * line_cap :: + * The line cap style. + * + * line_join :: + * The line join style. + * + * miter_limit :: + * The miter limit for the FT_STROKER_LINEJOIN_MITER style, + * expressed as 16.16 fixed point value. + * + * @note: + * The radius is expressed in the same units that the outline + * coordinates. + */ + FT_EXPORT( void ) + FT_Stroker_Set( FT_Stroker stroker, + FT_Fixed radius, + FT_Stroker_LineCap line_cap, + FT_Stroker_LineJoin line_join, + FT_Fixed miter_limit ); + + + /************************************************************** + * + * @function: + * FT_Stroker_Rewind + * + * @description: + * Reset a stroker object without changing its attributes. + * You should call this function before beginning a new + * series of calls to @FT_Stroker_BeginSubPath or + * @FT_Stroker_EndSubPath. + * + * @input: + * stroker :: + * The target stroker handle. + */ + FT_EXPORT( void ) + FT_Stroker_Rewind( FT_Stroker stroker ); + + + /************************************************************** + * + * @function: + * FT_Stroker_ParseOutline + * + * @description: + * A convenience function used to parse a whole outline with + * the stroker. The resulting outline(s) can be retrieved + * later by functions like @FT_Stroker_GetCounts and @FT_Stroker_Export. + * + * @input: + * stroker :: + * The target stroker handle. + * + * outline :: + * The source outline. + * + * opened :: + * A boolean. If TRUE, the outline is treated as an open path + * instead of a closed one. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * If `opened' is 0 (the default), the outline is treated as a closed + * path, and the stroker will generate two distinct `border' outlines. + * + * If `opened' is 1, the outline is processed as an open path, and the + * stroker will generate a single `stroke' outline. + * + * This function calls @FT_Stroker_Rewind automatically. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_ParseOutline( FT_Stroker stroker, + FT_Outline* outline, + FT_Bool opened ); + + + /************************************************************** + * + * @function: + * FT_Stroker_BeginSubPath + * + * @description: + * Start a new sub-path in the stroker. + * + * @input: + * stroker :: + * The target stroker handle. + * + * to :: + * A pointer to the start vector. + * + * open :: + * A boolean. If TRUE, the sub-path is treated as an open one. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * This function is useful when you need to stroke a path that is + * not stored as a @FT_Outline object. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_BeginSubPath( FT_Stroker stroker, + FT_Vector* to, + FT_Bool open ); + + + /************************************************************** + * + * @function: + * FT_Stroker_EndSubPath + * + * @description: + * Close the current sub-path in the stroker. + * + * @input: + * stroker :: + * The target stroker handle. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * You should call this function after @FT_Stroker_BeginSubPath. + * If the subpath was not `opened', this function will `draw' a + * single line segment to the start position when needed. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_EndSubPath( FT_Stroker stroker ); + + + /************************************************************** + * + * @function: + * FT_Stroker_LineTo + * + * @description: + * `Draw' a single line segment in the stroker's current sub-path, + * from the last position. + * + * @input: + * stroker :: + * The target stroker handle. + * + * to :: + * A pointer to the destination point. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * You should call this function between @FT_Stroker_BeginSubPath and + * @FT_Stroker_EndSubPath. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_LineTo( FT_Stroker stroker, + FT_Vector* to ); + + + /************************************************************** + * + * @function: + * FT_Stroker_ConicTo + * + * @description: + * `Draw; a single quadratic bezier in the stroker's current sub-path, + * from the last position. + * + * @input: + * stroker :: + * The target stroker handle. + * + * control :: + * A pointer to a Bézier control point. + * + * to :: + * A pointer to the destination point. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * You should call this function between @FT_Stroker_BeginSubPath and + * @FT_Stroker_EndSubPath. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_ConicTo( FT_Stroker stroker, + FT_Vector* control, + FT_Vector* to ); + + + /************************************************************** + * + * @function: + * FT_Stroker_CubicTo + * + * @description: + * `Draw' a single cubic Bézier in the stroker's current sub-path, + * from the last position. + * + * @input: + * stroker :: + * The target stroker handle. + * + * control1 :: + * A pointer to the first Bézier control point. + * + * control2 :: + * A pointer to second Bézier control point. + * + * to :: + * A pointer to the destination point. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * You should call this function between @FT_Stroker_BeginSubPath and + * @FT_Stroker_EndSubPath. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_CubicTo( FT_Stroker stroker, + FT_Vector* control1, + FT_Vector* control2, + FT_Vector* to ); + + + /************************************************************** + * + * @function: + * FT_Stroker_GetBorderCounts + * + * @description: + * Vall this function once you have finished parsing your paths + * with the stroker. It will return the number of points and + * contours necessary to export one of the `border' or `stroke' + * outlines generated by the stroker. + * + * @input: + * stroker :: + * The target stroker handle. + * + * border :: + * The border index. + * + * @output: + * anum_points :: + * The number of points. + * + * anum_contours :: + * The number of contours. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * When an outline, or a sub-path, is `closed', the stroker generates + * two independent `border' outlines, named `left' and `right'. + * + * When the outline, or a sub-path, is `opened', the stroker merges + * the `border' outlines with caps. The `left' border receives all + * points, while the `right' border becomes empty. + * + * Use the function @FT_Stroker_GetCounts instead if you want to + * retrieve the counts associated to both borders. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_GetBorderCounts( FT_Stroker stroker, + FT_StrokerBorder border, + FT_UInt *anum_points, + FT_UInt *anum_contours ); + + + /************************************************************** + * + * @function: + * FT_Stroker_ExportBorder + * + * @description: + * Call this function after @FT_Stroker_GetBorderCounts to + * export the corresponding border to your own @FT_Outline + * structure. + * + * Note that this function will append the border points and + * contours to your outline, but will not try to resize its + * arrays. + * + * @input: + * stroker :: + * The target stroker handle. + * + * border :: + * The border index. + * + * outline :: + * The target outline handle. + * + * @note: + * Always call this function after @FT_Stroker_GetBorderCounts to + * get sure that there is enough room in your @FT_Outline object to + * receive all new data. + * + * When an outline, or a sub-path, is `closed', the stroker generates + * two independent `border' outlines, named `left' and `right' + * + * When the outline, or a sub-path, is `opened', the stroker merges + * the `border' outlines with caps. The `left' border receives all + * points, while the `right' border becomes empty. + * + * Use the function @FT_Stroker_Export instead if you want to + * retrieve all borders at once. + */ + FT_EXPORT( void ) + FT_Stroker_ExportBorder( FT_Stroker stroker, + FT_StrokerBorder border, + FT_Outline* outline ); + + + /************************************************************** + * + * @function: + * FT_Stroker_GetCounts + * + * @description: + * Call this function once you have finished parsing your paths + * with the stroker. It returns the number of points and + * contours necessary to export all points/borders from the stroked + * outline/path. + * + * @input: + * stroker :: + * The target stroker handle. + * + * @output: + * anum_points :: + * The number of points. + * + * anum_contours :: + * The number of contours. + * + * @return: + * FreeType error code. 0 means success. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_GetCounts( FT_Stroker stroker, + FT_UInt *anum_points, + FT_UInt *anum_contours ); + + + /************************************************************** + * + * @function: + * FT_Stroker_Export + * + * @description: + * Call this function after @FT_Stroker_GetBorderCounts to + * export the all borders to your own @FT_Outline structure. + * + * Note that this function will append the border points and + * contours to your outline, but will not try to resize its + * arrays. + * + * @input: + * stroker :: + * The target stroker handle. + * + * outline :: + * The target outline handle. + */ + FT_EXPORT( void ) + FT_Stroker_Export( FT_Stroker stroker, + FT_Outline* outline ); + + + /************************************************************** + * + * @function: + * FT_Stroker_Done + * + * @description: + * Destroy a stroker object. + * + * @input: + * stroker :: + * A stroker handle. Can be NULL. + */ + FT_EXPORT( void ) + FT_Stroker_Done( FT_Stroker stroker ); + + + /************************************************************** + * + * @function: + * FT_Glyph_Stroke + * + * @description: + * Stroke a given outline glyph object with a given stroker. + * + * @inout: + * pglyph :: Source glyph handle on input, new glyph handle + * on output. + * + * @input: + * stroker :: + * A stroker handle. + * + * destroy :: + * A Boolean. If TRUE, the source glyph object is destroyed + * on success. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * The source glyph is untouched in case of error. + */ + FT_EXPORT( FT_Error ) + FT_Glyph_Stroke( FT_Glyph *pglyph, + FT_Stroker stroker, + FT_Bool destroy ); + + + /************************************************************** + * + * @function: + * FT_Glyph_StrokeBorder + * + * @description: + * Stroke a given outline glyph object with a given stroker, but + * only return either its inside or outside border. + * + * @inout: + * pglyph :: + * Source glyph handle on input, new glyph handle on output. + * + * @input: + * stroker :: + * A stroker handle. + * + * inside :: + * A Boolean. If TRUE, return the inside border, otherwise + * the outside border. + * + * destroy :: + * A Boolean. If TRUE, the source glyph object is destroyed + * on success. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * The source glyph is untouched in case of error. + */ + FT_EXPORT( FT_Error ) + FT_Glyph_StrokeBorder( FT_Glyph *pglyph, + FT_Stroker stroker, + FT_Bool inside, + FT_Bool destroy ); + + /* */ + +FT_END_HEADER + +#endif /* __FT_STROKE_H__ */ + + +/* END */ diff --git a/headers/libs/freetype2/freetype/ftstroker.h b/headers/libs/freetype2/freetype/ftstroker.h deleted file mode 100644 index 9ef3c60e0c..0000000000 --- a/headers/libs/freetype2/freetype/ftstroker.h +++ /dev/null @@ -1,139 +0,0 @@ -#ifndef __FT_STROKER_H__ -#define __FT_STROKER_H__ - -#include <ft2build.h> -#include FT_OUTLINE_H - -FT_BEGIN_HEADER - -/*@************************************************************* - * - * @type: FT_Stroker - * - * @description: - * opaque handler to a path stroker object - */ - typedef struct FT_StrokerRec_* FT_Stroker; - - -/*@************************************************************* - * - * @enum: FT_Stroker_LineJoin - * - * @description: - * these values determine how two joining lines are rendered - * in a stroker. - * - * @values: - * FT_STROKER_LINEJOIN_ROUND :: - * used to render rounded line joins. circular arcs are used - * to join two lines smoothly - * - * FT_STROKER_LINEJOIN_BEVEL :: - * used to render beveled line joins; i.e. the two joining lines - * are extended until they intersect - * - * FT_STROKER_LINEJOIN_MITER :: - * same as beveled rendering, except that an additional line - * break is added if the angle between the two joining lines - * is too closed (this is useful to avoid unpleasant spikes - * in beveled rendering). - */ - typedef enum - { - FT_STROKER_LINEJOIN_ROUND = 0, - FT_STROKER_LINEJOIN_BEVEL, - FT_STROKER_LINEJOIN_MITER - - } FT_Stroker_LineJoin; - - -/*@************************************************************* - * - * @enum: FT_Stroker_LineCap - * - * @description: - * these values determine how the end of opened sub-paths are - * rendered in a stroke - * - * @values: - * FT_STROKER_LINECAP_BUTT :: - * the end of lines is rendered as a full stop on the last - * point itself - * - * FT_STROKER_LINECAP_ROUND :: - * the end of lines is rendered as a half-circle around the - * last point - * - * FT_STROKER_LINECAP_SQUARE :: - * the end of lines is rendered as a square around the - * last point - */ - typedef enum - { - FT_STROKER_LINECAP_BUTT = 0, - FT_STROKER_LINECAP_ROUND, - FT_STROKER_LINECAP_SQUARE - - } FT_Stroker_LineCap; - - /* */ - - FT_EXPORT( FT_Error ) - FT_Stroker_New( FT_Memory memory, - FT_Stroker *astroker ); - - FT_EXPORT( void ) - FT_Stroker_Set( FT_Stroker stroker, - FT_Fixed radius, - FT_Stroker_LineCap line_cap, - FT_Stroker_LineJoin line_join, - FT_Fixed miter_limit ); - - - FT_EXPORT( FT_Error ) - FT_Stroker_ParseOutline( FT_Stroker stroker, - FT_Outline* outline, - FT_Bool opened ); - - FT_EXPORT( FT_Error ) - FT_Stroker_BeginSubPath( FT_Stroker stroker, - FT_Vector* to, - FT_Bool open ); - - FT_EXPORT( FT_Error ) - FT_Stroker_EndSubPath( FT_Stroker stroker ); - - - FT_EXPORT( FT_Error ) - FT_Stroker_LineTo( FT_Stroker stroker, - FT_Vector* to ); - - FT_EXPORT( FT_Error ) - FT_Stroker_ConicTo( FT_Stroker stroker, - FT_Vector* control, - FT_Vector* to ); - - FT_EXPORT( FT_Error ) - FT_Stroker_CubicTo( FT_Stroker stroker, - FT_Vector* control1, - FT_Vector* control2, - FT_Vector* to ); - - - FT_EXPORT( FT_Error ) - FT_Stroker_GetCounts( FT_Stroker stroker, - FT_UInt *anum_points, - FT_UInt *anum_contours ); - - FT_EXPORT( void ) - FT_Stroker_Export( FT_Stroker stroker, - FT_Outline* outline ); - - FT_EXPORT( void ) - FT_Stroker_Done( FT_Stroker stroker ); - - -FT_END_HEADER - -#endif /* __FT_STROKER_H__ */ diff --git a/headers/libs/freetype2/freetype/ftsynth.h b/headers/libs/freetype2/freetype/ftsynth.h index 049574b9f1..f0c738532f 100644 --- a/headers/libs/freetype2/freetype/ftsynth.h +++ b/headers/libs/freetype2/freetype/ftsynth.h @@ -5,7 +5,7 @@ /* FreeType synthesizing code for emboldening and slanting */ /* (specification). */ /* */ -/* Copyright 2000-2001 by */ +/* Copyright 2000-2001, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -41,6 +41,12 @@ #include <ft2build.h> #include FT_FREETYPE_H +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + FT_BEGIN_HEADER @@ -62,4 +68,4 @@ FT_END_HEADER #endif /* __FTSYNTH_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/ftsysio.h b/headers/libs/freetype2/freetype/ftsysio.h index 887afa51fa..f8e49543f3 100644 --- a/headers/libs/freetype2/freetype/ftsysio.h +++ b/headers/libs/freetype2/freetype/ftsysio.h @@ -192,4 +192,4 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FT_SYSTEM_STREAM_H__ */ +#endif /* __FT_SYSTEM_STREAM_H__ */ diff --git a/headers/libs/freetype2/freetype/ftsysmem.h b/headers/libs/freetype2/freetype/ftsysmem.h index 60c891a4f1..8de0c4db03 100644 --- a/headers/libs/freetype2/freetype/ftsysmem.h +++ b/headers/libs/freetype2/freetype/ftsysmem.h @@ -199,4 +199,4 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FT_SYSTEM_MEMORY_H__ */ +#endif /* __FT_SYSTEM_MEMORY_H__ */ diff --git a/headers/libs/freetype2/freetype/ftsystem.h b/headers/libs/freetype2/freetype/ftsystem.h index b056a57270..d1c55f7aea 100644 --- a/headers/libs/freetype2/freetype/ftsystem.h +++ b/headers/libs/freetype2/freetype/ftsystem.h @@ -306,4 +306,4 @@ FT_END_HEADER #endif /* __FTSYSTEM_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/fttrigon.h b/headers/libs/freetype2/freetype/fttrigon.h index 9af1a273b7..0462265e3c 100644 --- a/headers/libs/freetype2/freetype/fttrigon.h +++ b/headers/libs/freetype2/freetype/fttrigon.h @@ -4,7 +4,7 @@ /* */ /* FreeType trigonometric functions (specification). */ /* */ -/* Copyright 2001 by */ +/* Copyright 2001, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,6 +21,12 @@ #include FT_FREETYPE_H +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + FT_BEGIN_HEADER @@ -257,22 +263,6 @@ FT_BEGIN_HEADER FT_Vector_Length( FT_Vector* vec ); - /*************************************************************************/ - /* */ - /* @function: */ - /* FT_Vector_Normalize */ - /* */ - /* @description: */ - /* Normalize a given vector (i.e. compute the equivalent unit */ - /* vector). */ - /* */ - /* @inout: */ - /* vec :: The address of target vector. */ - /* */ - FT_EXPORT( void ) - FT_Vector_Normalize( FT_Vector* vec ); - - /*************************************************************************/ /* */ /* @function: */ @@ -322,4 +312,4 @@ FT_END_HEADER #endif /* __FTTRIGON_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/fttypes.h b/headers/libs/freetype2/freetype/fttypes.h index 1ea8dd6647..2782f74d58 100644 --- a/headers/libs/freetype2/freetype/fttypes.h +++ b/headers/libs/freetype2/freetype/fttypes.h @@ -555,4 +555,4 @@ FT_END_HEADER #endif /* __FTTYPES_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/ftwinfnt.h b/headers/libs/freetype2/freetype/ftwinfnt.h index ca5ef2f5b7..a19a12d972 100644 --- a/headers/libs/freetype2/freetype/ftwinfnt.h +++ b/headers/libs/freetype2/freetype/ftwinfnt.h @@ -1,129 +1,257 @@ -/***************************************************************************/ -/* */ -/* ftwinfnt.h */ -/* */ -/* FreeType API for accessing Windows fnt-specific data. */ -/* */ -/* Copyright 2002 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. */ -/* */ -/***************************************************************************/ - - -#ifndef __FTWINFNT_H__ -#define __FTWINFNT_H__ - -#include <ft2build.h> -#include FT_FREETYPE_H - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <Section> */ - /* winfnt_fonts */ - /* */ - /* <Title> */ - /* Window FNT Fonts */ - /* */ - /* <Abstract> */ - /* Windows FNT specific APIs */ - /* */ - /* <Description> */ - /* This section contains the declaration of Windows FNT specific */ - /* functions. */ - /* */ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* FT_WinFNT_HeaderRec_ */ - /* */ - /* <Description> */ - /* Windows FNT Header info. */ - /* */ - typedef struct FT_WinFNT_HeaderRec_ - { - FT_UShort version; - FT_ULong file_size; - FT_Byte copyright[60]; - FT_UShort file_type; - FT_UShort nominal_point_size; - FT_UShort vertical_resolution; - FT_UShort horizontal_resolution; - FT_UShort ascent; - FT_UShort internal_leading; - FT_UShort external_leading; - FT_Byte italic; - FT_Byte underline; - FT_Byte strike_out; - FT_UShort weight; - FT_Byte charset; - FT_UShort pixel_width; - FT_UShort pixel_height; - FT_Byte pitch_and_family; - FT_UShort avg_width; - FT_UShort max_width; - FT_Byte first_char; - FT_Byte last_char; - FT_Byte default_char; - FT_Byte break_char; - FT_UShort bytes_per_row; - FT_ULong device_offset; - FT_ULong face_name_offset; - FT_ULong bits_pointer; - FT_ULong bits_offset; - FT_Byte reserved; - FT_ULong flags; - FT_UShort A_space; - FT_UShort B_space; - FT_UShort C_space; - FT_UShort color_table_offset; - FT_ULong reserved1[4]; - - } FT_WinFNT_HeaderRec, *FT_WinFNT_Header; - - - - /********************************************************************** - * - * @function: - * FT_Get_WinFNT_Header - * - * @description: - * Retrieves a Windows FNT font info header. - * - * @input: - * face :: handle to input face - * - * @output: - * header :: WinFNT header. - * - * @return: - * FreeType error code. 0 means success. - * - * @note: - * This function only works with Windows FNT faces, returning an erro - * otherwise. - */ - FT_EXPORT( FT_Error ) - FT_Get_WinFNT_Header( FT_Face face, - FT_WinFNT_HeaderRec *header ); - - /* */ - -FT_END_HEADER - -#endif /* __FTWINFNT_H__ */ - - -/* END */ +/***************************************************************************/ +/* */ +/* ftwinfnt.h */ +/* */ +/* FreeType API for accessing Windows fnt-specific data. */ +/* */ +/* Copyright 2003 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. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTWINFNT_H__ +#define __FTWINFNT_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* winfnt_fonts */ + /* */ + /* <Title> */ + /* Window FNT Fonts */ + /* */ + /* <Abstract> */ + /* Windows FNT specific APIs */ + /* */ + /* <Description> */ + /* This section contains the declaration of Windows FNT specific */ + /* functions. */ + /* */ + /*************************************************************************/ + + + /************************************************************************* + * + * @enum: + * FT_WinFNT_ID_XXX + * + * @description: + * A list of valid values for the `charset' byte in + * @FT_WinFNT_HeaderRec. Exact mapping tables for the various cpXXXX + * encodings (except for cp1361) can be found at ftp://ftp.unicode.org + * in the MAPPINGS/VENDORS/MICSFT/WINDOWS subdirectory. cp1361 is + * roughly a superset of MAPPINGS/OBSOLETE/EASTASIA/KSC/JOHAB.TXT. + * + * @values: + * FT_WinFNT_ID_DEFAULT :: + * This is used for font enumeration and font creation as a + * `don't care' value. Valid font files don't contain this value. + * When querying for information about the character set of the font + * that is currently selected into a specified device context, this + * return value (of the related Windows API) simply denotes failure. + * + * FT_WinFNT_ID_SYMBOL :: + * There is no known mapping table available. + * + * FT_WinFNT_ID_MAC :: + * Mac Roman encoding. + * + * FT_WinFNT_ID_OEM :: + * From Michael Pöttgen <michael@poettgen.de>: + * The `Windows Font Mapping' article says that FT_WinFNT_ID_OEM + * is used for the charset of vector fonts, like `modern.fon', + * `roman.fon', and `script.fon' on Windows. + * + * The `CreateFont' documentation says: The FT_WinFNT_ID_OEM value + * specifies a character set that is operating-system dependent. + * + * The `IFIMETRICS' documentation from the `Windows Driver + * Development Kit' says: This font supports an OEM-specific + * character set. The OEM character set is system dependent. + * + * In general OEM, as opposed to ANSI (i.e., cp1252), denotes the + * second default codepage that most international versions of + * Windows have. It is one of the OEM codepages from + * + * http://www.microsoft.com/globaldev/reference/cphome.mspx, + * + * and is used for the `DOS boxes', to support legacy applications. + * A German Windows version for example usually uses ANSI codepage + * 1252 and OEM codepage 850. + * + * FT_WinFNT_ID_CP874 :: + * A superset of Thai TIS 620 and ISO 8859-11. + * + * FT_WinFNT_ID_CP932 :: + * A superset of Japanese Shift-JIS (with minor deviations). + * + * FT_WinFNT_ID_CP936 :: + * A superset of simplified Chinese GB 2312-1980 (with different + * ordering and minor deviations). + * + * FT_WinFNT_ID_CP949 :: + * A superset of Korean Hangul KS C 5601-1987 (with different + * ordering and minor deviations). + * + * FT_WinFNT_ID_CP950 :: + * A superset of traditional Chinese Big 5 ETen (with different + * ordering and minor deviations). + * + * FT_WinFNT_ID_CP1250 :: + * A superset of East European ISO 8859-2 (with slightly different + * ordering). + * + * FT_WinFNT_ID_CP1251 :: + * A superset of Russian ISO 8859-5 (with different ordering). + * + * FT_WinFNT_ID_CP1252 :: + * ANSI encoding. A superset of ISO 8859-1. + * + * FT_WinFNT_ID_CP1253 :: + * A superset of Greek ISO 8859-7 (with minor modifications). + * + * FT_WinFNT_ID_CP1254 :: + * A superset of Turkish ISO 8859-9. + * + * FT_WinFNT_ID_CP1255 :: + * A superset of Hebrew ISO 8859-8 (with some modifications). + * + * FT_WinFNT_ID_CP1256 :: + * A superset of Arabic ISO 8859-6 (with different ordering). + * + * FT_WinFNT_ID_CP1257 :: + * A superset of Baltic ISO 8859-13 (with some deviations). + * + * FT_WinFNT_ID_CP1258 :: + * For Vietnamese. This encoding doesn't cover all necessary + * characters. + * + * FT_WinFNT_ID_CP1361 :: + * Korean (Johab). + */ + +#define FT_WinFNT_ID_CP1252 0 +#define FT_WinFNT_ID_DEFAULT 1 +#define FT_WinFNT_ID_SYMBOL 2 +#define FT_WinFNT_ID_MAC 77 +#define FT_WinFNT_ID_CP932 128 +#define FT_WinFNT_ID_CP949 129 +#define FT_WinFNT_ID_CP1361 130 +#define FT_WinFNT_ID_CP936 134 +#define FT_WinFNT_ID_CP950 136 +#define FT_WinFNT_ID_CP1253 161 +#define FT_WinFNT_ID_CP1254 162 +#define FT_WinFNT_ID_CP1258 163 +#define FT_WinFNT_ID_CP1255 177 +#define FT_WinFNT_ID_CP1256 178 +#define FT_WinFNT_ID_CP1257 186 +#define FT_WinFNT_ID_CP1251 204 +#define FT_WinFNT_ID_CP874 222 +#define FT_WinFNT_ID_CP1250 238 +#define FT_WinFNT_ID_OEM 255 + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_WinFNT_HeaderRec */ + /* */ + /* <Description> */ + /* Windows FNT Header info. */ + /* */ + typedef struct FT_WinFNT_HeaderRec_ + { + FT_UShort version; + FT_ULong file_size; + FT_Byte copyright[60]; + FT_UShort file_type; + FT_UShort nominal_point_size; + FT_UShort vertical_resolution; + FT_UShort horizontal_resolution; + FT_UShort ascent; + FT_UShort internal_leading; + FT_UShort external_leading; + FT_Byte italic; + FT_Byte underline; + FT_Byte strike_out; + FT_UShort weight; + FT_Byte charset; + FT_UShort pixel_width; + FT_UShort pixel_height; + FT_Byte pitch_and_family; + FT_UShort avg_width; + FT_UShort max_width; + FT_Byte first_char; + FT_Byte last_char; + FT_Byte default_char; + FT_Byte break_char; + FT_UShort bytes_per_row; + FT_ULong device_offset; + FT_ULong face_name_offset; + FT_ULong bits_pointer; + FT_ULong bits_offset; + FT_Byte reserved; + FT_ULong flags; + FT_UShort A_space; + FT_UShort B_space; + FT_UShort C_space; + FT_UShort color_table_offset; + FT_ULong reserved1[4]; + + } FT_WinFNT_HeaderRec, *FT_WinFNT_Header; + + + /********************************************************************** + * + * @function: + * FT_Get_WinFNT_Header + * + * @description: + * Retrieve a Windows FNT font info header. + * + * @input: + * face :: A handle to the input face. + * + * @output: + * aheader :: The WinFNT header. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * This function only works with Windows FNT faces, returning an error + * otherwise. + */ + FT_EXPORT( FT_Error ) + FT_Get_WinFNT_Header( FT_Face face, + FT_WinFNT_HeaderRec *aheader ); + + + /* */ + +FT_END_HEADER + +#endif /* __FTWINFNT_H__ */ + + +/* END */ diff --git a/headers/libs/freetype2/freetype/ftxf86.h b/headers/libs/freetype2/freetype/ftxf86.h index 030ab98e3c..3362883cbc 100644 --- a/headers/libs/freetype2/freetype/ftxf86.h +++ b/headers/libs/freetype2/freetype/ftxf86.h @@ -4,7 +4,7 @@ /* */ /* Support functions for X11. */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,6 +22,13 @@ #include <ft2build.h> #include FT_FREETYPE_H +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + FT_BEGIN_HEADER /* this comment is intentionally disabled for now, to prevent this */ @@ -43,11 +50,11 @@ FT_BEGIN_HEADER /* <Return> */ /* Font format string. NULL in case of error. */ /* */ - FT_EXPORT_DEF( const char* ) + FT_EXPORT( const char* ) FT_Get_X11_Font_Format( FT_Face face ); /* */ FT_END_HEADER -#endif /* __FTXF86_H__ */ +#endif /* __FTXF86_H__ */ diff --git a/headers/libs/freetype2/freetype/internal/autohint.h b/headers/libs/freetype2/freetype/internal/autohint.h index cda3d19cfc..22340afc3f 100644 --- a/headers/libs/freetype2/freetype/internal/autohint.h +++ b/headers/libs/freetype2/freetype/internal/autohint.h @@ -202,4 +202,4 @@ FT_END_HEADER #endif /* __AUTOHINT_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/internal/bdftypes.h b/headers/libs/freetype2/freetype/internal/bdftypes.h deleted file mode 100644 index 8f2250e528..0000000000 --- a/headers/libs/freetype2/freetype/internal/bdftypes.h +++ /dev/null @@ -1,58 +0,0 @@ -/* bdftypes.h - - FreeType font driver for bdf fonts - - Copyright (C) 2001, 2002 by - Francesco Zappa Nardelli - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -#ifndef __BDFTYPES_H__ -#define __BDFTYPES_H__ - -#include <ft2build.h> -#include FT_FREETYPE_H -#include FT_BDF_H - - -FT_BEGIN_HEADER - - - typedef struct BDF_Public_FaceRec_ - { - FT_FaceRec root; - - char* charset_encoding; - char* charset_registry; - - } BDF_Public_FaceRec, *BDF_Public_Face; - - - typedef FT_Error (*BDF_GetPropertyFunc)( FT_Face face, - const char* prop_name, - BDF_PropertyRec *aproperty ); - -FT_END_HEADER - - -#endif /* __BDFTYPES_H__ */ - - -/* END */ diff --git a/headers/libs/freetype2/freetype/internal/fnttypes.h b/headers/libs/freetype2/freetype/internal/fnttypes.h deleted file mode 100644 index 032b1d5336..0000000000 --- a/headers/libs/freetype2/freetype/internal/fnttypes.h +++ /dev/null @@ -1,114 +0,0 @@ -/***************************************************************************/ -/* */ -/* fnttypes.h */ -/* */ -/* Basic Windows FNT/FON type definitions and interface (specification */ -/* only). */ -/* */ -/* Copyright 1996-2001, 2002 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. */ -/* */ -/***************************************************************************/ - - -#ifndef __FNTTYPES_H__ -#define __FNTTYPES_H__ - - -#include <ft2build.h> -#include FT_FREETYPE_H -#include FT_WINFONTS_H - - -FT_BEGIN_HEADER - - - typedef struct WinMZ_HeaderRec_ - { - FT_UShort magic; - /* skipped content */ - FT_UShort lfanew; - - } WinMZ_HeaderRec; - - - typedef struct WinNE_HeaderRec_ - { - FT_UShort magic; - /* skipped content */ - FT_UShort resource_tab_offset; - FT_UShort rname_tab_offset; - - } WinNE_HeaderRec; - - - typedef struct WinNameInfoRec_ - { - FT_UShort offset; - FT_UShort length; - FT_UShort flags; - FT_UShort id; - FT_UShort handle; - FT_UShort usage; - - } WinNameInfoRec; - - - typedef struct WinResourceInfoRec_ - { - FT_UShort type_id; - FT_UShort count; - - } WinResourceInfoRec; - - -#define WINFNT_MZ_MAGIC 0x5A4D -#define WINFNT_NE_MAGIC 0x454E - - - typedef struct FNT_FontRec_ - { - FT_ULong offset; - FT_Int size_shift; - - FT_WinFNT_HeaderRec header; - - FT_Byte* fnt_frame; - FT_ULong fnt_size; - - } FNT_FontRec, *FNT_Font; - - - typedef struct FNT_SizeRec_ - { - FT_SizeRec root; - FNT_Font font; - - } FNT_SizeRec, *FNT_Size; - - - typedef struct FNT_FaceRec_ - { - FT_FaceRec root; - - FT_UInt num_fonts; - FNT_Font fonts; - - FT_CharMap charmap_handle; - FT_CharMapRec charmap; /* a single charmap per face */ - - } FNT_FaceRec, *FNT_Face; - - -FT_END_HEADER - -#endif /* __FNTTYPES_H__ */ - - -/* END */ diff --git a/headers/libs/freetype2/freetype/internal/ftcalc.h b/headers/libs/freetype2/freetype/internal/ftcalc.h index 08d4e15232..7866c46273 100644 --- a/headers/libs/freetype2/freetype/internal/ftcalc.h +++ b/headers/libs/freetype2/freetype/internal/ftcalc.h @@ -4,7 +4,7 @@ /* */ /* Arithmetic computations (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -27,7 +27,8 @@ FT_BEGIN_HEADER - FT_EXPORT( FT_Int32 ) FT_SqrtFixed( FT_Int32 x ); + FT_EXPORT( FT_Int32 ) + FT_SqrtFixed( FT_Int32 x ); #define SQRT_32( x ) FT_Sqrt32( x ) @@ -59,6 +60,39 @@ FT_BEGIN_HEADER /*************************************************************************/ +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_MulDiv_No_Round */ + /* */ + /* <Description> */ + /* A very simple function used to perform the computation `(a*b)/c' */ + /* (without rounding) with maximal accuracy (it uses a 64-bit */ + /* intermediate integer whenever necessary). */ + /* */ + /* This function isn't necessarily as fast as some processor specific */ + /* operations, but is at least completely portable. */ + /* */ + /* <Input> */ + /* a :: The first multiplier. */ + /* b :: The second multiplier. */ + /* c :: The divisor. */ + /* */ + /* <Return> */ + /* The result of `(a*b)/c'. This function never traps when trying to */ + /* divide by zero; it simply returns `MaxInt' or `MinInt' depending */ + /* on the signs of `a' and `b'. */ + /* */ + FT_BASE( FT_Long ) + FT_MulDiv_No_Round( FT_Long a, + FT_Long b, + FT_Long c ); + +#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ + + #define INT_TO_F26DOT6( x ) ( (FT_Long)(x) << 6 ) #define INT_TO_F2DOT14( x ) ( (FT_Long)(x) << 14 ) #define INT_TO_FIXED( x ) ( (FT_Long)(x) << 16 ) @@ -74,4 +108,4 @@ FT_END_HEADER #endif /* __FTCALC_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/internal/ftcore.h b/headers/libs/freetype2/freetype/internal/ftcore.h deleted file mode 100644 index e5763ebd65..0000000000 --- a/headers/libs/freetype2/freetype/internal/ftcore.h +++ /dev/null @@ -1,185 +0,0 @@ -#ifndef __FT_CORE_H__ -#define __FT_CORE_H__ - -#include <ft2build.h> -#include FT_TYPES_H -#include FT_SYSTEM_MEMORY_H - -FT_BEGIN_HEADER - - /**************************************************************************/ - /**************************************************************************/ - /***** *****/ - /***** C L E A N U P S T A C K *****/ - /***** *****/ - /**************************************************************************/ - /**************************************************************************/ - - - /************************************************************************ - * - * @functype: FT_CleanupFunc - * - * @description: - * a function used to cleanup a given item on the cleanup stack - * - * @input: - * item :: target item pointer - * item_data :: optional argument to cleanup routine - */ - typedef void (*FT_CleanupFunc)( FT_Pointer item, - FT_Pointer item_data ); - - - - /************************************************************************ - * - * @type: FT_XHandler - * - * @description: - * handle to an exception-handler structure for the FreeType - * exception sub-system - * - * @note: - * exception handlers are allocated on the stack within a - * @FT_XTRY macro. Do not try to access them directly. - */ - typedef struct FT_XHandlerRec_* FT_XHandler; - - -/* the size of a cleanup chunk in bytes is FT_CLEANUP_CHUNK_SIZE*12 + 4 */ -/* this must be a small power of 2 whenever possible.. */ -/* */ -/* with a value of 5, we have a byte size of 64 bytes per chunk.. */ -/* */ -#define FT_CLEANUP_CHUNK_SIZE 5 - - - - typedef struct FT_CleanupItemRec_ - { - FT_Pointer item; - FT_CleanupFunc item_func; - FT_Pointer item_data; - - } FT_CleanupItemRec; - - - typedef struct FT_CleanupChunkRec_* FT_CleanupChunk; - - typedef struct FT_CleanupChunkRec_ - { - FT_CleanupChunk link; - FT_CleanupItemRec items[ FT_CLEANUP_CHUNK_SIZE ]; - - } FT_CleanupChunkRec; - - - typedef struct FT_CleanupStackRec_ - { - FT_CleanupItem top; - FT_CleanupItem limit; - FT_CleanupChunk chunk; - FT_CleanupChunkRec chunk_0; /* avoids stupid dynamic allocation */ - FT_Memory memory; - - } FT_CleanupStackRec, *FT_CleanupStack; - - - FT_BASE( void ) - ft_cleanup_stack_push( FT_CleanupStack stack, - FT_Pointer item, - FT_CleanupFunc item_func, - FT_Pointer item_data ); - - FT_BASE( void ) - ft_cleanup_stack_pop( FT_CleanupStack stack, - FT_Int destroy ); - - FT_BASE( FT_CleanupItem ) - ft_cleanup_stack_peek( FT_CleanupStack stack ); - - FT_BASE( void ) - ft_cleanup_throw( FT_CleanupStack stack, - FT_Error error ); - - - - /**************************************************************************/ - /**************************************************************************/ - /***** *****/ - /***** M E M O R Y M A N A G E R *****/ - /***** *****/ - /**************************************************************************/ - /**************************************************************************/ - - typedef struct FT_MemoryRec_ - { - FT_Memory_AllocFunc mem_alloc; /* shortcut to funcs->mem_alloc */ - FT_Memory_FreeFunc mem_free; /* shortcut to funcs->mem_free */ - FT_Pointer mem_data; - const FT_Memory_Funcs mem_funcs; - - FT_CleanupStackRec cleanup_stack; - FT_Pointer meta_class; - - } FT_MemoryRec; - - -#define FT_MEMORY(x) ((FT_Memory)(x)) -#define FT_MEMORY__ALLOC(x) FT_MEMORY(x)->mem_alloc -#define FT_MEMORY__FREE(x) FT_MEMORY(x)->mem_free -#define FT_MEMORY__REALLOC(x) FT_MEMORY(x)->mem_funcs->mem_realloc -#define FT_MEMORY__CLEANUP(x) (&FT_MEMORY(x)->cleanup_stack) -#define FT_MEMORY__META_CLASS(x) ((FT_MetaClass)(FT_MEMORY(x)->meta_class)) - - - /**************************************************************************/ - /**************************************************************************/ - /***** *****/ - /***** E X C E P T I O N H A N D L I N G *****/ - /***** *****/ - /**************************************************************************/ - /**************************************************************************/ - - - /************************************************************************ - * - * @struct: FT_XHandlerRec - * - * @description: - * exception handler structure - * - * @fields: - * previous :: previous handler in chain. - * jum_buffer :: processor state used by setjmp/longjmp to implement - * exception control transfer - * error :: exception error code - * mark :: top of cleanup stack when @FT_XTRY is used - */ - typedef struct FT_XHandlerRec_ - { - FT_XHandler previous; - ft_jmp_buf jump_buffer; - volatile FT_Error error; - FT_Pointer mark; - - } FT_XHandlerRec; - - FT_BASE( void ) - ft_xhandler_enter( FT_XHandler xhandler, - FT_Memory memory ); - - FT_BASE( void ) - ft_xhandler_exit( FT_XHandler xhandler ); - - - - - - - - -FT_END_HEADER - -#endif /* __FT_CORE_H__ */ diff --git a/headers/libs/freetype2/freetype/internal/ftdebug.h b/headers/libs/freetype2/freetype/internal/ftdebug.h index bce1e7b8a9..ce142c54c9 100644 --- a/headers/libs/freetype2/freetype/internal/ftdebug.h +++ b/headers/libs/freetype2/freetype/internal/ftdebug.h @@ -4,7 +4,7 @@ /* */ /* Debugging and logging component (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -27,6 +27,7 @@ #include <ft2build.h> #include FT_CONFIG_CONFIG_H +#include FT_FREETYPE_H FT_BEGIN_HEADER @@ -96,6 +97,53 @@ FT_BEGIN_HEADER #endif /* !FT_DEBUG_LEVEL_TRACE */ + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Trace_Get_Count */ + /* */ + /* <Description> */ + /* Return the number of available trace components. */ + /* */ + /* <Return> */ + /* The number of trace components. 0 if FreeType 2 is not built with */ + /* FT_DEBUG_LEVEL_TRACE definition. */ + /* */ + /* <Note> */ + /* This function may be useful if you want to access elements of */ + /* the internal `ft_trace_levels' array by an index. */ + /* */ + FT_EXPORT( FT_Int ) + FT_Trace_Get_Count( void ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Trace_Get_Name */ + /* */ + /* <Description> */ + /* Return the name of a trace component. */ + /* */ + /* <Input> */ + /* The index of the trace component. */ + /* */ + /* <Return> */ + /* The name of the trace component. This is a statically allocated */ + /* C string, so do not free it after use. NULL if FreeType 2 is not */ + /* built with FT_DEBUG_LEVEL_TRACE definition. */ + /* */ + /* <Note> */ + /* Use @FT_Trace_Get_Count to get the number of available trace */ + /* components. */ + /* */ + /* This function may be useful if you want to control FreeType 2's */ + /* debug level in your appliaciton. */ + /* */ + FT_EXPORT( const char * ) + FT_Trace_Get_Name( FT_Int idx ); + + /*************************************************************************/ /* */ /* You need two opening resp. closing parentheses! */ @@ -193,4 +241,4 @@ FT_END_HEADER #endif /* __FTDEBUG_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/internal/ftdriver.h b/headers/libs/freetype2/freetype/internal/ftdriver.h index ffa7215e4f..02f585d6b0 100644 --- a/headers/libs/freetype2/freetype/internal/ftdriver.h +++ b/headers/libs/freetype2/freetype/internal/ftdriver.h @@ -4,7 +4,7 @@ /* */ /* FreeType font driver interface (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -155,11 +155,15 @@ FT_BEGIN_HEADER /* add data from AFM or PFM files on a Type 1 */ /* face, or a CIDMap on a CID-keyed face. */ /* */ - /* get_advances :: A function handle used to return the advances */ - /* of 'count' glyphs, starting at `index'. the */ - /* `vertical' flags must be set when vertical */ - /* advances are queried. The advances buffer is */ - /* caller-allocated. */ + /* get_advances :: A function handle used to return advance */ + /* widths of 'count' glyphs (in font units), */ + /* starting at `first'. The `vertical' flag must */ + /* be set to get vertical advance heights. The */ + /* `advances' buffer is caller-allocated. */ + /* Currently not implemented. The idea of this */ + /* function is to be able to perform */ + /* device-independent text layout without loading */ + /* a single glyph image. */ /* */ /* <Note> */ /* Most function pointers, with the exception of `load_glyph' and */ @@ -169,9 +173,9 @@ FT_BEGIN_HEADER { FT_Module_Class root; - FT_Int face_object_size; - FT_Int size_object_size; - FT_Int slot_object_size; + FT_Long face_object_size; + FT_Long size_object_size; + FT_Long slot_object_size; FT_Face_InitFunc init_face; FT_Face_DoneFunc done_face; @@ -199,4 +203,4 @@ FT_END_HEADER #endif /* __FTDRIVER_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/internal/ftexcept.h b/headers/libs/freetype2/freetype/internal/ftexcept.h deleted file mode 100644 index c53af9d716..0000000000 --- a/headers/libs/freetype2/freetype/internal/ftexcept.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef __FT_EXCEPT_H__ -#define __FT_EXCEPT_H__ - -#include <ft2build.h> -#include FT_INTERNAL_OBJECTS_H - -FT_BEGIN_HEADER - - - - /* I can't find a better place for this for now */ - -<<<<<<< ftexcept.h -======= - -/* the size of a cleanup chunk in bytes is FT_CLEANUP_CHUNK_SIZE*12 + 4 */ -/* this must be a small power of 2 whenever possible.. */ -/* */ -/* with a value of 5, we have a byte size of 64 bytes per chunk.. */ -/* */ -#define FT_CLEANUP_CHUNK_SIZE 5 - - - - typedef struct FT_CleanupItemRec_ - { - FT_Pointer item; - FT_CleanupFunc item_func; - FT_Pointer item_data; - - } FT_CleanupItemRec; - - typedef struct FT_CleanupChunkRec_* FT_CleanupChunk; - - typedef struct FT_CleanupChunkRec_ - { - FT_CleanupChunk link; - FT_CleanupItemRec items[ FT_CLEANUP_CHUNK_SIZE ]; - - } FT_CleanupChunkRec; - - - typedef struct FT_CleanupStackRec_ - { - FT_CleanupItem top; - FT_CleanupItem limit; - FT_CleanupChunk chunk; - FT_CleanupChunkRec chunk_0; /* avoids stupid dynamic allocation */ - FT_Memory memory; - - } FT_CleanupStackRec, *FT_CleanupStack; - - - FT_BASE( void ) - ft_cleanup_stack_push( FT_CleanupStack stack, - FT_Pointer item, - FT_CleanupFunc item_func, - FT_Pointer item_data ); - - FT_BASE( void ) - ft_cleanup_stack_pop( FT_CleanupStack stack, - FT_Int destroy ); - - FT_BASE( FT_CleanupItem ) - ft_cleanup_stack_peek( FT_CleanupStack stack ); - - FT_BASE( void ) - ft_xhandler_enter( FT_XHandler xhandler, - FT_Memory memory ); - - FT_BASE( void ) - ft_xhandler_exit( FT_XHandler xhandler ); - - - FT_BASE( void ) - ft_cleanup_throw( FT_CleanupStack stack, - FT_Error error ); - ->>>>>>> 1.2 -FT_END_HEADER - -#endif /* __FT_EXCEPT_H__ */ diff --git a/headers/libs/freetype2/freetype/internal/ftgloadr.h b/headers/libs/freetype2/freetype/internal/ftgloadr.h index 7ac2901de7..abc56e2566 100644 --- a/headers/libs/freetype2/freetype/internal/ftgloadr.h +++ b/headers/libs/freetype2/freetype/internal/ftgloadr.h @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph loader (specification). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -52,12 +52,6 @@ FT_BEGIN_HEADER #define FT_SUBGLYPH_FLAG_USE_MY_METRICS 0x200 - enum - { - FT_GLYPH_OWN_BITMAP = 1 - }; - - typedef struct FT_SubGlyphRec_ { FT_Int index; @@ -116,15 +110,15 @@ FT_BEGIN_HEADER FT_BASE( void ) FT_GlyphLoader_Rewind( FT_GlyphLoader loader ); - /* check that there is enough room to add 'n_points' and 'n_contours' */ - /* to the glyph loader */ + /* check that there is enough space to add `n_points' and `n_contours' */ + /* to the glyph loader */ FT_BASE( FT_Error ) FT_GlyphLoader_CheckPoints( FT_GlyphLoader loader, FT_UInt n_points, FT_UInt n_contours ); - /* check that there is enough room to add 'n_subs' sub-glyphs to */ - /* a glyph loader */ + /* check that there is enough space to add `n_subs' sub-glyphs to */ + /* a glyph loader */ FT_BASE( FT_Error ) FT_GlyphLoader_CheckSubGlyphs( FT_GlyphLoader loader, FT_UInt n_subs ); @@ -150,4 +144,4 @@ FT_END_HEADER #endif /* __FTGLOADR_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/internal/fthash.h b/headers/libs/freetype2/freetype/internal/fthash.h deleted file mode 100644 index f676c1e601..0000000000 --- a/headers/libs/freetype2/freetype/internal/fthash.h +++ /dev/null @@ -1,502 +0,0 @@ -/****************************************************************** - * - * fthash.h - fast dynamic hash tables - * - * Copyright 2002 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. - * - * - * This header is used to define dynamic hash tables as described - * by the article "Main-Memory Linear Hashing - Some Enhancements - * of Larson's Algorithm" by Mikael Petterson. - * - * Basically, linear hashing prevents big "stalls" during - * resizes of the buckets array by only splitting one bucket - * at a time. This ensures excellent response time even when - * the table is frequently resized.. - * - * - * Note that the use of the FT_Hash type is rather unusual in order - * to be as generic and efficient as possible. See the comments in the - * following definitions for more details. - */ - -#ifndef __FT_HASH_H__ -#define __FT_HASH_H__ - -#include <ft2build.h> -#include FT_TYPES_H - -FT_BEGIN_HEADER - - /*********************************************************** - * - * @type: FT_Hash - * - * @description: - * handle to a @FT_HashRec structure used to model a - * dynamic hash table - */ - typedef struct FT_HashRec_* FT_Hash; - - - /*********************************************************** - * - * @type: FT_HashNode - * - * @description: - * handle to a @FT_HashNodeRec structure used to model a - * single node of a hash table - */ - typedef struct FT_HashNodeRec_* FT_HashNode; - - - /*********************************************************** - * - * @type: FT_HashLookup - * - * @description: - * handle to a @FT_HashNode pointer. This is returned by - * the @ft_hash_lookup function and can later be used by - * @ft_hash_add or @ft_hash_remove - */ - typedef FT_HashNode* FT_HashLookup; - - - /*********************************************************** - * - * @type: FT_Hash_EqualFunc - * - * @description: - * a function used to compare two nodes of the hash table - * - * @input: - * node1 :: handle to first node - * node2 :: handle to second node - * - * @return: - * 1 iff the 'keys' in 'node1' and 'node2' are identical. - * 0 otherwise. - */ - typedef FT_Int (*FT_Hash_EqualFunc)( FT_HashNode node1, - FT_HashNode node2 ); - - - /*********************************************************** - * - * @struct: FT_HashRec - * - * @description: - * a structure used to model a dynamic hash table. - * - * @fields: - * memory :: memory manager used to allocate - * the buckets array and the hash nodes - * - * buckets :: array of hash buckets - * - * node_size :: size of node in bytes - * node_compare :: a function used to compare two nodes - * node_hash :: a function used to compute the hash - * value of a given node - * p :: - * mask :: - * slack :: - * - * @note: - * 'p', 'mask' and 'slack' are control values managed by - * the hash table. Do not try to interpret them directly. - * - * You can grab the hash table size by calling - * '@ft_hash_get_size'. - */ - typedef struct FT_HashRec_ - { - FT_HashNode* buckets; - FT_UInt p; - FT_UInt mask; /* really maxp-1 */ - FT_Long slack; - FT_Hash_EqualFunc node_equal; - FT_Memory memory; - - } FT_HashRec; - - - /*********************************************************** - * - * @struct: FT_HashNodeRec - * - * @description: - * a structure used to model the root fields of a dynamic - * hash table node. - * - * it's up to client applications to "sub-class" this - * structure to add relevant (key,value) definitions - * - * @fields: - * link :: pointer to next node in bucket's collision list - * hash :: 32-bit hash value for this node - * - * @note: - * it's up to client applications to "sub-class" this structure - * to add relevant (key,value) type definitions. For example, - * if we want to build a "string -> int" mapping, we could use - * something like: - * - * { - * typedef struct MyNodeRec_ - * { - * FT_HashNodeRec hnode; - * const char* key; - * int value; - * - * } MyNodeRec, *MyNode; - * } - * - */ - typedef struct FT_HashNodeRec_ - { - FT_HashNode link; - FT_UInt32 hash; - - } FT_HashNodeRec; - - - /**************************************************************** - * - * @function: ft_hash_init - * - * @description: - * initialize a dynamic hash table - * - * @input: - * table :: handle to target hash table structure - * node_equal :: node comparison function - * memory :: memory manager handle used to allocate the - * buckets array within the hash table - * - * @return: - * error code. 0 means success - * - * @note: - * the node comparison function should only compare node _keys_ - * and ignore values !! with good hashing computation (which the - * user must perform itself), the comparison function should be - * pretty seldom called. - * - * here is a simple example: - * - * { - * static int my_equal( MyNode node1, - * MyNode node2 ) - * { - * // compare keys of 'node1' and 'node2' - * return (strcmp( node1->key, node2->key ) == 0); - * } - * - * .... - * - * ft_hash_init( &hash, (FT_Hash_EqualFunc) my_compare, memory ); - * .... - * } - */ - FT_BASE( FT_Error ) - ft_hash_init( FT_Hash table, - FT_Hash_EqualFunc compare, - FT_Memory memory ); - - - /**************************************************************** - * - * @function: ft_hash_lookup - * - * @description: - * search a hash table to find a node corresponding to a given - * key. - * - * @input: - * table :: handle to target hash table structure - * keynode :: handle to a reference hash node that will be - * only used for key comparisons with the table's - * elements - * - * @return: - * a pointer-to-hash-node value, which must be used as followed: - * - * - if '*result' is NULL, the key wasn't found in the hash - * table. The value of 'result' can be used to add new elements - * through @ft_hash_add however.. - * - * - if '*result' is not NULL, it's a handle to the first table - * node that corresponds to the search key. The value of 'result' - * can be used to remove this element through @ft_hash_remove - * - * @note: - * here is an example: - * - * { - * // maps a string to an integer with a hash table - * // returns -1 in case of failure - * // - * int my_lookup( FT_Hash table, - * const char* key ) - * { - * MyNode* pnode; - * MyNodeRec noderec; - * - * // set-up key node. It's 'hash' and 'key' fields must - * // be set correctly.. we ignore 'link' and 'value' - * // - * noderec.hnode.hash = strhash( key ); - * noderec.key = key; - * - * // perform search - return value - * // - * pnode = (MyNode) ft_hash_lookup( table, &noderec ); - * if ( *pnode ) - * { - * // we found it - * return (*pnode)->value; - * } - * return -1; - * } - * } - */ - FT_BASE_DEF( FT_HashLookup ) - ft_hash_lookup( FT_Hash table, - FT_HashNode keynode ); - - - /**************************************************************** - * - * @function: ft_hash_add - * - * @description: - * add a new node to a dynamic hash table. the user must - * call @ft_hash_lookup and allocate a new node before calling - * this function. - * - * @input: - * table :: hash table handle - * lookup :: pointer-to-hash-node value returned by @ft_hash_lookup - * new_node :: handle to new hash node. All its fields must be correctly - * set, including 'hash'. - * - * @return: - * error code. 0 means success - * - * @note: - * this function should always be used _after_ a call to @ft_hash_lookup - * that returns a pointer to a NULL handle. Here's an example: - * - * { - * // sets the value corresponding to a given string key - * // - * void my_set( FT_Hash table, - * const char* key, - * int value ) - * { - * MyNode* pnode; - * MyNodeRec noderec; - * MyNode node; - * - * // set-up key node. It's 'hash' and 'key' fields must - * // be set correctly.. - * noderec.hnode.hash = strhash( key ); - * noderec.key = key; - * - * // perform search - return value - * pnode = (MyNode) ft_hash_lookup( table, &noderec ); - * if ( *pnode ) - * { - * // we found it, simply replace the value in the node - * (*pnode)->value = value; - * return; - * } - * - * // allocate a new node - and set it up - * node = (MyNode) malloc( sizeof(*node) ); - * if ( node == NULL ) ..... - * - * node->hnode.hash = noderec.hnode.hash; - * node->key = key; - * node->value = value; - * - * // add it to the hash table - * error = ft_hash_add( table, pnode, node ); - * if (error) .... - * } - */ - FT_BASE( FT_Error ) - ft_hash_add( FT_Hash table, - FT_HashLookup lookup, - FT_HashNode new_node ); - - - /**************************************************************** - * - * @function: ft_hash_remove - * - * @description: - * try to remove the node corresponding to a given key from - * a hash table. This must be called after @ft_hash_lookup - * - * @input: - * table :: hash table handle - * lookup :: pointer-to-hash-node value returned by @ft_hash_lookup - * - * @note: - * this function doesn't free the node itself !! Here's an example: - * - * { - * // sets the value corresponding to a given string key - * // - * void my_remove( FT_Hash table, - * const char* key ) - * { - * MyNodeRec noderec; - * MyNode node; - * - * noderec.hnode.hash = strhash(key); - * noderec.key = key; - * node = &noderec; - * - * pnode = ft_hash_lookup( table, &noderec ); - * node = *pnode; - * if ( node != NULL ) - * { - * error = ft_hash_remove( table, pnode ); - * if ( !error ) - * free( node ); - * } - * } - * } - */ - FT_BASE( FT_Error ) - ft_hash_remove( FT_Hash table, - FT_HashLookup lookup ); - - - - /**************************************************************** - * - * @function: ft_hash_get_size - * - * @description: - * return the number of elements in a given hash table - * - * @input: - * table :: handle to target hash table structure - * - * @return: - * number of elements. 0 if empty - */ - FT_BASE( FT_UInt ) - ft_hash_get_size( FT_Hash table ); - - - - /**************************************************************** - * - * @functype: FT_Hash_ForeachFunc - * - * @description: - * a function used to iterate over all elements of a given - * hash table - * - * @input: - * node :: handle to target @FT_HashNodeRec node structure - * data :: optional argument to iteration routine - * - * @also: @ft_hash_foreach - */ - typedef void (*FT_Hash_ForeachFunc)( const FT_HashNode node, - const FT_Pointer data ); - - - /**************************************************************** - * - * @function: ft_hash_foreach - * - * @description: - * parse over all elements in a hash table - * - * @input: - * table :: handle to target hash table structure - * foreach_func :: iteration routine called for each element - * foreach_data :: optional argument to the iteration routine - * - * @note: - * this function is often used to release all elements from a - * hash table. See the example given for @ft_hash_done - */ - FT_BASE( void ) - ft_hash_foreach( FT_Hash table, - FT_Hash_ForeachFunc foreach_func, - const FT_Pointer foreach_data ); - - - - /**************************************************************** - * - * @function: ft_hash_done - * - * @description: - * finalize a given hash table - * - * @input: - * table :: handle to target hash table structure - * node_func :: optional iteration function pointer. this - * can be used to destroy all nodes explicitely - * node_data :: optional argument to the node iterator - * - * @note: - * this function simply frees the hash table's buckets. - * you probably will need to call @ft_hash_foreach to - * destroy all its elements before @ft_hash_done, as in - * the following example: - * - * { - * static void my_node_clear( const MyNode node ) - * { - * free( node ); - * } - * - * static void my_done( FT_Hash table ) - * { - * ft_hash_done( table, (FT_Hash_ForeachFunc) my_node_clear, NULL ); - * } - * } - */ - FT_BASE( void ) - ft_hash_done( FT_Hash table, - FT_Hash_ForeachFunc item_func, - const FT_Pointer item_data ); - - /* */ - - /* compute bucket index from hash value in a dynamic hash table */ - /* this is only used to break encapsulation to speed lookups in */ - /* the FreeType cache manager !! */ - /* */ - -#define FT_HASH_COMPUTE_INDEX(_table,_hash,_index) \ - { \ - FT_UInt _mask = (_table)->mask; \ - FT_UInt _hash0 = (_hash); \ - \ - (_index) = (FT_UInt)( (_hash0) & _mask ) ); \ - if ( (_index) < (_table)->p ) \ - (_index) = (FT_uInt)( (_hash0) & ( 2*_mask+1 ) ); \ - } - - -FT_END_HEADER - -#endif /* __FT_HASH_H__ */ diff --git a/headers/libs/freetype2/freetype/internal/ftmemory.h b/headers/libs/freetype2/freetype/internal/ftmemory.h index 9f0128dc7c..63f37aff7c 100644 --- a/headers/libs/freetype2/freetype/internal/ftmemory.h +++ b/headers/libs/freetype2/freetype/internal/ftmemory.h @@ -4,7 +4,7 @@ /* */ /* The FreeType memory management macros (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -141,7 +141,7 @@ FT_BEGIN_HEADER FT_Realloc( FT_Memory memory, FT_Long current, FT_Long size, - void** P ); + void* *P ); /*************************************************************************/ @@ -159,17 +159,14 @@ FT_BEGIN_HEADER /* P :: This is the _address_ of a _pointer_ which points to the */ /* allocated block. It is always set to NULL on exit. */ /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ /* <Note> */ - /* If P or *P are NULL, this function should return successfully. */ + /* If P or *P is NULL, this function should return successfully. */ /* This is a strong convention within all of FreeType and its */ /* drivers. */ /* */ FT_BASE( void ) FT_Free( FT_Memory memory, - void** P ); + void* *P ); #define FT_MEM_SET( dest, byte, count ) ft_memset( dest, byte, count ) @@ -183,6 +180,12 @@ FT_BEGIN_HEADER #define FT_ZERO( p ) FT_MEM_ZERO( p, sizeof ( *(p) ) ) +#define FT_ARRAY_COPY( dest, source, count ) \ + FT_MEM_COPY( dest, source, (count) * sizeof( *(dest) ) ) + +#define FT_ARRAY_MOVE( dest, source, count ) \ + FT_MEM_MOVE( dest, source, (count) * sizeof( *(dest) ) ) + /*************************************************************************/ /* */ @@ -293,4 +296,4 @@ FT_END_HEADER #endif /* __FTMEMORY_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/internal/ftobject.h b/headers/libs/freetype2/freetype/internal/ftobject.h deleted file mode 100644 index 15b2c8b225..0000000000 --- a/headers/libs/freetype2/freetype/internal/ftobject.h +++ /dev/null @@ -1,533 +0,0 @@ -#ifndef __FT_OBJECT_H__ -#define __FT_OBJECT_H__ - -#include <ft2build.h> -#include FT_FREETYPE_H - -FT_BEGIN_HEADER - - /************************************************************** - * - * @type: FT_Object - * - * @description: - * handle to a FreeType Object. See @FT_ObjectRec - */ - typedef struct FT_ObjectRec_* FT_Object; - - - /************************************************************** - * - * @type: FT_Class - * - * @description: - * handle to a constant class handle to a FreeType Object. - * - * Note that a class is itself a @FT_Object and are dynamically - * allocated on the heap. - * - * @also: - * @FT_ClassRec, @FT_Object, @FT_ObjectRec, @FT_Type, @FT_TypeRec - */ - typedef const struct FT_ClassRec_* FT_Class; - - - /************************************************************** - * - * @type: FT_Type - * - * @description: - * handle to a constant structure (of type @FT_TypeRec) used - * to describe a given @FT_Class type to the FreeType object - * sub-system. - */ - typedef const struct FT_TypeRec_* FT_Type; - - - - /************************************************************** - * - * @struct: FT_ObjectRec - * - * @description: - * a structure describing the root fields of all @FT_Object - * class instances in FreeType - * - * @fields: - * clazz :: handle to the object's class - * ref_count :: object's reference count. Starts at 1 - */ - typedef struct FT_ObjectRec_ - { - FT_Class clazz; - FT_Int ref_count; - - } FT_ObjectRec; - - - /************************************************************** - * - * @macro: FT_OBJECT (x) - * - * @description: - * a useful macro to type-cast anything to a @FT_Object - * handle. No check performed.. - */ -#define FT_OBJECT(x) ((FT_Object)(x)) - - - /************************************************************** - * - * @macro: FT_OBJECT_P (x) - * - * @description: - * a useful macro to type-cast anything to a pointer to - * @FT_Object handle. - */ -#define FT_OBJECT_P(x) ((FT_Object*)(x)) - - - /************************************************************** - * - * @macro: FT_OBJECT__CLASS (obj) - * - * @description: - * a useful macro to return the class of any object - */ -#define FT_OBJECT__CLASS(x) FT_OBJECT(x)->clazz - - - /************************************************************** - * - * @macro: FT_OBJECT__REF_COUNT (obj) - * - * @description: - * a useful macro to return the reference count of any object - */ -#define FT_OBJECT__REF_COUNT(x) FT_OBJECT(x)->ref_count - - - /************************************************************** - * - * @macro: FT_OBJECT__MEMORY (obj) - * - * @description: - * a useful macro to return a handle to the memory manager - * used to allocate a given object - */ -#define FT_OBJECT__MEMORY(x) FT_CLASS__MEMORY(FT_OBJECT(x)->clazz) - - - /************************************************************** - * - * @macro: FT_OBJECT__LIBRARY (obj) - * - * @description: - * a useful macro to return a handle to the library handle - * that owns the object - */ -#define FT_OBJECT__LIBRARY(x) FT_CLASS__LIBRARY(FT_OBJECT(x)->clazz) - - - /************************************************************** - * - * @functype: FT_Object_InitFunc - * - * @description: - * a function used to initialize a new object - * - * @input: - * object :: target object handle - * init_data :: optional pointer to initialization data - * - * @return: - * error code. 0 means success - */ - typedef FT_Error (*FT_Object_InitFunc)( FT_Object object, - FT_Pointer init_data ); - - /************************************************************** - * - * @functype: FT_Object_DoneFunc - * - * @description: - * a function used to finalize a given object - * - * @input: - * object :: handle to target object - */ - typedef void (*FT_Object_DoneFunc)( FT_Object object ); - - - /************************************************************** - * - * @struct: FT_ClassRec - * - * @description: - * a structure used to describe a given object class within - * FreeType - * - * @fields: - * object :: root @FT_ObjectRec fields, since each class is - * itself an object. (it's an instance of the - * "metaclass", a special object of the FreeType - * object sub-system.) - * - * magic :: a 32-bit magic number used for decoding - * super :: pointer to super class - * type :: the @FT_Type descriptor of this class - * memory :: the current memory manager handle - * library :: the current library handle - * info :: an opaque pointer to class-specific information - * managed by the FreeType object sub-system - * - * class_done :: the class destructor function - * - * obj_size :: size of class instances in bytes - * obj_init :: class instance constructor - * obj_done :: class instance destructor - */ - typedef struct FT_ClassRec_ - { - FT_ObjectRec object; - FT_UInt32 magic; - FT_Class super; - FT_Type type; - FT_Memory memory; - FT_Library library; - FT_Pointer info; - - FT_Object_DoneFunc class_done; - - FT_UInt obj_size; - FT_Object_InitFunc obj_init; - FT_Object_DoneFunc obj_done; - - } FT_ClassRec; - - - /************************************************************** - * - * @macro: FT_CLASS (x) - * - * @description: - * a useful macro to convert anything to a class handle - * without checks - */ -#define FT_CLASS(x) ((FT_Class)(x)) - - - /************************************************************** - * - * @macro: FT_CLASS_P (x) - * - * @description: - * a useful macro to convert anything to a pointer to a class - * handle without checks - */ -#define FT_CLASS_P(x) ((FT_Class*)(x)) - - - /************************************************************** - * - * @macro: FT_CLASS__MEMORY (clazz) - * - * @description: - * a useful macro to return the memory manager handle of a - * given class - */ -#define FT_CLASS__MEMORY(x) FT_CLASS(x)->memory - - - /************************************************************** - * - * @macro: FT_CLASS__LIBRARY (clazz) - * - * @description: - * a useful macro to return the library handle of a - * given class - */ -#define FT_CLASS__LIBRARY(x) FT_CLASS(x)->library - - - - /************************************************************** - * - * @macro: FT_CLASS__TYPE (clazz) - * - * @description: - * a useful macro to return the type of a given class - * given class - */ -#define FT_CLASS__TYPE(x) FT_CLASS(x)->type - - /* */ -#define FT_CLASS__INFO(x) FT_CLASS(x)->info -#define FT_CLASS__MAGIC(x) FT_CLASS(x)->magic - - - /************************************************************** - * - * @struct: FT_TypeRec - * - * @description: - * a structure used to describe a given class to the FreeType - * object sub-system. - * - * @fields: - * name :: class name. only used for debugging - * super :: type of super-class. NULL if none - * - * class_size :: size of class structure in bytes - * class_init :: class constructor - * class_done :: class finalizer - * - * obj_size :: instance size in bytes - * obj_init :: instance constructor. can be NULL - * obj_done :: instance destructor. can be NULL - * - * @note: - * if 'obj_init' is NULL, the class will use it's parent - * constructor, if any - * - * if 'obj_done' is NULL, the class will use it's parent - * finalizer, if any - * - * the object sub-system allocates a new class, copies - * the content of its super-class into the new structure, - * _then_ calls 'clazz_init'. - * - * 'class_init' and 'class_done' can be NULL, in which case - * the parent's class constructor and destructor wil be used - */ - typedef struct FT_TypeRec_ - { - const char* name; - FT_Type super; - - FT_UInt class_size; - FT_Object_InitFunc class_init; - FT_Object_DoneFunc class_done; - - FT_UInt obj_size; - FT_Object_InitFunc obj_init; - FT_Object_DoneFunc obj_done; - - } FT_TypeRec; - - - /************************************************************** - * - * @macro: FT_TYPE (x) - * - * @description: - * a useful macro to convert anything to a class type handle - * without checks - */ -#define FT_TYPE(x) ((FT_Type)(x)) - - - /************************************************************** - * - * @function: ft_object_check - * - * @description: - * checks that a handle points to a valid @FT_Object - * - * @input: - * obj :: handle/pointer - * - * @return: - * 1 iff the handle points to a valid object. 0 otherwise - */ - FT_BASE( FT_Int ) - ft_object_check( FT_Pointer obj ); - - - /************************************************************** - * - * @function: ft_object_is_a - * - * @description: - * checks that a handle points to a valid @FT_Object that - * is an instance of a given class (or of any of its sub-classes) - * - * @input: - * obj :: handle/pointer - * clazz :: class handle to check - * - * @return: - * 1 iff the handle points to a valid 'clazz' instance. 0 - * otherwise. - */ - FT_BASE( FT_Int ) - ft_object_is_a( FT_Pointer obj, - FT_Class clazz ); - - - /************************************************************** - * - * @function: ft_object_create - * - * @description: - * create a new object (class instance) - * - * @output: - * aobject :: new object handle. NULL in case of error - * - * @input: - * clazz :: object's class pointer - * init_data :: optional pointer to initialization data - * - * @return: - * error code. 0 means success - */ - FT_BASE( FT_Error ) - ft_object_create( FT_Object *aobject, - FT_Class clazz, - FT_Pointer init_data ); - - - /************************************************************** - * - * @function: ft_object_create_from_type - * - * @description: - * create a new object (class instance) from a @FT_Type - * - * @output: - * aobject :: new object handle. NULL in case of error - * - * @input: - * type :: object's type descriptor - * init_data :: optional pointer to initialization data - * - * @return: - * error code. 0 means success - * - * @note: - * this function is slower than @ft_object_create - * - * this is equivalent to calling @ft_class_from_type followed by - * @ft_object_create - */ - FT_BASE( FT_Error ) - ft_object_create_from_type( FT_Object *aobject, - FT_Type type, - FT_Pointer init_data, - FT_Library library ); - - - - /************************************************************** - * - * @macro FT_OBJ_CREATE (object,class,init) - * - * @description: - * a convenient macro used to create new objects. see - * @ft_object_create for details - */ -#define FT_OBJ_CREATE( _obj, _clazz, _init ) \ - ft_object_create( FT_OBJECT_P(&(_obj)), _clazz, _init ) - - - /************************************************************** - * - * @macro FT_CREATE (object,class,init) - * - * @description: - * a convenient macro used to create new objects. It also - * sets an _implicit_ local variable named "error" to the error - * code returned by the object constructor. - */ -#define FT_CREATE( _obj, _clazz, _init ) \ - FT_SET_ERROR( FT_OBJ_CREATE( _obj, _clazz, _init ) ) - - /************************************************************** - * - * @macro FT_OBJ_CREATE_FROM_TYPE (object,type,init) - * - * @description: - * a convenient macro used to create new objects. see - * @ft_object_create_from_type for details - */ -#define FT_OBJ_CREATE_FROM_TYPE( _obj, _type, _init, _lib ) \ - ft_object_create_from_type( FT_OBJECT_P(&(_obj)), _type, _init, _lib ) - - - /************************************************************** - * - * @macro FT_CREATE_FROM_TYPE (object,type,init) - * - * @description: - * a convenient macro used to create new objects. It also - * sets an _implicit_ local variable named "error" to the error - * code returned by the object constructor. - */ -#define FT_CREATE_FROM_TYPE( _obj, _type, _init, _lib ) \ - FT_SET_ERROR( FT_OBJ_CREATE_FROM_TYPE( _obj, _type, _init, _lib ) ) - - - /* */ - - /************************************************************** - * - * @function: ft_class_from_type - * - * @description: - * retrieves the class object corresponding to a given type - * descriptor. The class is created when needed - * - * @output: - * aclass :: handle to corresponding class object. NULL in - * case of error - * - * @input: - * type :: type descriptor handle - * library :: library handle - * - * @return: - * error code. 0 means success - */ - FT_BASE( FT_Error ) - ft_class_from_type( FT_Class *aclass, - FT_Type type, - FT_Library library ); - - - /* */ - -#include FT_INTERNAL_HASH_H - - typedef struct FT_ClassHNodeRec_* FT_ClassHNode; - - typedef struct FT_ClassHNodeRec_ - { - FT_HashNodeRec hnode; - FT_Type type; - FT_Class clazz; - - } FT_ClassHNodeRec; - - typedef struct FT_MetaClassRec_ - { - FT_ClassRec clazz; /* the meta-class is a class itself */ - FT_HashRec type_to_class; /* the type => class hash table */ - - } FT_MetaClassRec, *FT_MetaClass; - - - /* initialize meta class */ - FT_BASE( FT_Error ) - ft_metaclass_init( FT_MetaClass meta, - FT_Library library ); - - /* finalize meta class - destroy all registered class objects */ - FT_BASE( void ) - ft_metaclass_done( FT_MetaClass meta ); - - /* */ - -FT_END_HEADER - -#endif /* __FT_OBJECT_H__ */ diff --git a/headers/libs/freetype2/freetype/internal/ftobjs.h b/headers/libs/freetype2/freetype/internal/ftobjs.h index 3f60b1554c..3a28119af1 100644 --- a/headers/libs/freetype2/freetype/internal/ftobjs.h +++ b/headers/libs/freetype2/freetype/internal/ftobjs.h @@ -4,7 +4,7 @@ /* */ /* The FreeType private base classes (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -34,7 +34,7 @@ #include FT_INTERNAL_GLYPH_LOADER_H #include FT_INTERNAL_DRIVER_H #include FT_INTERNAL_AUTOHINT_H -#include FT_INTERNAL_OBJECT_H +#include FT_INTERNAL_SERVICE_H #ifdef FT_CONFIG_OPTION_INCREMENTAL #include FT_INCREMENTAL_H @@ -64,19 +64,21 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ /* The min and max functions missing in C. As usual, be careful not to */ - /* write things like MIN( a++, b++ ) to avoid side effects. */ + /* write things like FT_MIN( a++, b++ ) to avoid side effects. */ /* */ -#ifndef MIN -#define MIN( a, b ) ( (a) < (b) ? (a) : (b) ) -#endif +#define FT_MIN( a, b ) ( (a) < (b) ? (a) : (b) ) +#define FT_MAX( a, b ) ( (a) > (b) ? (a) : (b) ) -#ifndef MAX -#define MAX( a, b ) ( (a) > (b) ? (a) : (b) ) -#endif +#define FT_ABS( a ) ( (a) < 0 ? -(a) : (a) ) -#ifndef ABS -#define ABS( a ) ( (a) < 0 ? -(a) : (a) ) -#endif + +#define FT_PAD_FLOOR( x, n ) ( (x) & ~((n)-1) ) +#define FT_PAD_ROUND( x, n ) FT_PAD_FLOOR( (x) + ((n)/2), n ) +#define FT_PAD_CEIL( x, n ) FT_PAD_FLOOR( (x) + ((n)-1), n ) + +#define FT_PIX_FLOOR( x ) ( (x) & ~63 ) +#define FT_PIX_ROUND( x ) FT_PIX_FLOOR( (x) + 32 ) +#define FT_PIX_CEIL( x ) FT_PIX_FLOOR( (x) + 63 ) /*************************************************************************/ @@ -112,7 +114,7 @@ FT_BEGIN_HEADER /* return an error later when trying to load the glyph). */ /* */ /* It also check that fields that must be a multiple of 2, 4, or 8 */ - /* dont' have incorrect values, etc. */ + /* don't have incorrect values, etc. */ /* */ /* FT_VALIDATE_PARANOID :: */ /* Only for font debugging. Checks that a table follows the */ @@ -239,7 +241,7 @@ FT_BEGIN_HEADER typedef struct FT_CMap_ClassRec_ { - FT_UInt size; + FT_ULong size; FT_CMap_InitFunc init; FT_CMap_DoneFunc done; FT_CMap_CharIndexFunc char_index; @@ -271,56 +273,52 @@ FT_BEGIN_HEADER /* FreeType. */ /* */ /* <Fields> */ - /* max_points :: The maximal number of points used to store the */ - /* vectorial outline of any glyph in this face. */ - /* If this value cannot be known in advance, or */ - /* if the face isn't scalable, this should be set */ - /* to 0. Only relevant for scalable formats. */ + /* max_points :: */ + /* The maximal number of points used to store the vectorial outline */ + /* of any glyph in this face. If this value cannot be known in */ + /* advance, or if the face isn't scalable, this should be set to 0. */ + /* Only relevant for scalable formats. */ /* */ - /* max_contours :: The maximal number of contours used to store */ - /* the vectorial outline of any glyph in this */ - /* face. If this value cannot be known in */ - /* advance, or if the face isn't scalable, this */ - /* should be set to 0. Only relevant for */ - /* scalable formats. */ + /* max_contours :: */ + /* The maximal number of contours used to store the vectorial */ + /* outline of any glyph in this face. If this value cannot be */ + /* known in advance, or if the face isn't scalable, this should be */ + /* set to 0. Only relevant for scalable formats. */ /* */ - /* transform_matrix :: A 2x2 matrix of 16.16 coefficients used to */ - /* transform glyph outlines after they are loaded */ - /* from the font. Only used by the convenience */ - /* functions. */ + /* transform_matrix :: */ + /* A 2x2 matrix of 16.16 coefficients used to transform glyph */ + /* outlines after they are loaded from the font. Only used by the */ + /* convenience functions. */ /* */ - /* transform_delta :: A translation vector used to transform glyph */ - /* outlines after they are loaded from the font. */ - /* Only used by the convenience functions. */ + /* transform_delta :: */ + /* A translation vector used to transform glyph outlines after they */ + /* are loaded from the font. Only used by the convenience */ + /* functions. */ /* */ - /* transform_flags :: Some flags used to classify the transform. */ - /* Only used by the convenience functions. */ + /* transform_flags :: */ + /* Some flags used to classify the transform. Only used by the */ + /* convenience functions. */ /* */ - /* hint_flags :: Some flags used to change the hinters' */ - /* behaviour. Only used for debugging for now. */ - /* */ - /* postscript_name :: Postscript font name for this face. */ + /* services :: */ + /* A cache for frequently used services. It should be only */ + /* accessed with the macro `FT_FACE_LOOKUP_SERVICE'. */ /* */ /* incremental_interface :: */ - /* If non-null, the interface through */ - /* which glyph data and metrics are loaded */ - /* incrementally for faces that do not provide */ - /* all of this data when first opened. */ - /* This field exists only if */ - /* @FT_CONFIG_OPTION_INCREMENTAL is defined. */ + /* If non-null, the interface through which glyph data and metrics */ + /* are loaded incrementally for faces that do not provide all of */ + /* this data when first opened. This field exists only if */ + /* @FT_CONFIG_OPTION_INCREMENTAL is defined. */ /* */ typedef struct FT_Face_InternalRec_ { - FT_UShort max_points; - FT_Short max_contours; + FT_UShort max_points; + FT_Short max_contours; - FT_Matrix transform_matrix; - FT_Vector transform_delta; - FT_Int transform_flags; + FT_Matrix transform_matrix; + FT_Vector transform_delta; + FT_Int transform_flags; - FT_UInt32 hint_flags; - - const char* postscript_name; + FT_ServiceCacheRec services; #ifdef FT_CONFIG_OPTION_INCREMENTAL FT_Incremental_InterfaceRec* incremental_interface; @@ -343,6 +341,11 @@ FT_BEGIN_HEADER /* loader :: The glyph loader object used to load outlines */ /* into the glyph slot. */ /* */ + /* flags :: Possible values are zero or */ + /* FT_GLYPH_OWN_BITMAP. The latter indicates */ + /* that the FT_GlyphSlot structure owns the */ + /* bitmap buffer. */ + /* */ /* glyph_transformed :: Boolean. Set to TRUE when the loaded glyph */ /* must be transformed through a specific */ /* font transformation. This is _not_ the same */ @@ -357,9 +360,13 @@ FT_BEGIN_HEADER /* */ /* glyph_hints :: Format-specific glyph hints management. */ /* */ + +#define FT_GLYPH_OWN_BITMAP 0x1 + typedef struct FT_Slot_InternalRec_ { FT_GlyphLoader loader; + FT_UInt flags; FT_Bool glyph_transformed; FT_Matrix glyph_matrix; FT_Vector glyph_delta; @@ -416,25 +423,25 @@ FT_BEGIN_HEADER #define FT_MODULE_IS_DRIVER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ - ft_module_font_driver ) + FT_MODULE_FONT_DRIVER ) #define FT_MODULE_IS_RENDERER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ - ft_module_renderer ) + FT_MODULE_RENDERER ) #define FT_MODULE_IS_HINTER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ - ft_module_hinter ) + FT_MODULE_HINTER ) #define FT_MODULE_IS_STYLER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ - ft_module_styler ) + FT_MODULE_STYLER ) #define FT_DRIVER_IS_SCALABLE( x ) ( FT_MODULE_CLASS( x )->module_flags & \ - ft_module_driver_scalable ) + FT_MODULE_DRIVER_SCALABLE ) #define FT_DRIVER_USES_OUTLINES( x ) !( FT_MODULE_CLASS( x )->module_flags & \ - ft_module_driver_no_outlines ) + FT_MODULE_DRIVER_NO_OUTLINES ) #define FT_DRIVER_HAS_HINTER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ - ft_module_driver_has_hinter ) + FT_MODULE_DRIVER_HAS_HINTER ) /*************************************************************************/ @@ -462,6 +469,10 @@ FT_BEGIN_HEADER FT_Get_Module_Interface( FT_Library library, const char* mod_name ); + FT_BASE( FT_Pointer ) + ft_module_get_service( FT_Module module, + const char* service_id ); + /* */ @@ -537,28 +548,30 @@ FT_BEGIN_HEADER FT_Done_GlyphSlot( FT_GlyphSlot slot ); /* */ - + /* - * free the bitmap of a given glyphslot when needed - * (i.e. only when it was allocated with ft_glyphslot_alloc_bitmap) + * Free the bitmap of a given glyphslot when needed + * (i.e., only when it was allocated with ft_glyphslot_alloc_bitmap). */ FT_BASE( void ) ft_glyphslot_free_bitmap( FT_GlyphSlot slot ); - + + /* - * allocate a new bitmap buffer in a glyph slot + * Allocate a new bitmap buffer in a glyph slot. */ FT_BASE( FT_Error ) ft_glyphslot_alloc_bitmap( FT_GlyphSlot slot, FT_ULong size ); + /* - * set the bitmap buffer in a glyph slot to a given pointer. - * the buffer will not be freed by a later call to ft_glyphslot_free_bitmap + * Set the bitmap buffer in a glyph slot to a given pointer. + * The buffer will not be freed by a later call to ft_glyphslot_free_bitmap. */ FT_BASE( void ) - ft_glyphslot_set_bitmap( FT_GlyphSlot slot, - FT_Pointer buffer ); + ft_glyphslot_set_bitmap( FT_GlyphSlot slot, + FT_Byte* buffer ); /*************************************************************************/ @@ -667,8 +680,18 @@ FT_BEGIN_HEADER /*************************************************************************/ -#define FT_DEBUG_HOOK_TRUETYPE 0 -#define FT_DEBUG_HOOK_TYPE1 1 +/* this hook is used by the TrueType debugger. It must be set to an alternate + * truetype bytecode interpreter function + */ +#define FT_DEBUG_HOOK_TRUETYPE 0 + + +/* set this debug hook to a non-null pointer to force unpatented hinting + * for all faces when both TT_CONFIG_OPTION_BYTECODE_INTERPRETER and + * TT_CONFIG_OPTION_UNPATENTED_HINTING are defined. this is only used + * during debugging + */ +#define FT_DEBUG_HOOK_UNPATENTED_HINTING 1 /*************************************************************************/ @@ -688,6 +711,12 @@ FT_BEGIN_HEADER /* generic :: Client data variable. Used to extend the */ /* Library class by higher levels and clients. */ /* */ + /* version_major :: The major version number of the library. */ + /* */ + /* version_minor :: The minor version number of the library. */ + /* */ + /* version_patch :: The current patch level of the library. */ + /* */ /* num_modules :: The number of modules currently registered */ /* within this library. This is set to 0 for new */ /* libraries. New modules are added through the */ @@ -738,8 +767,6 @@ FT_BEGIN_HEADER FT_DebugHook_Func debug_hooks[4]; - FT_MetaClassRec meta_class; - } FT_LibraryRec; @@ -817,4 +844,4 @@ FT_END_HEADER #endif /* __FTOBJS_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/internal/ftrfork.h b/headers/libs/freetype2/freetype/internal/ftrfork.h new file mode 100644 index 0000000000..e7b10024ad --- /dev/null +++ b/headers/libs/freetype2/freetype/internal/ftrfork.h @@ -0,0 +1,184 @@ +/***************************************************************************/ +/* */ +/* ftrfork.h */ +/* */ +/* Embedded resource forks accessor (specification). */ +/* */ +/* Copyright 2004 by */ +/* Masatake YAMATO and Redhat K.K. */ +/* */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* Development of the code in this file is support of */ +/* Information-technology Promotion Agency, Japan. */ +/***************************************************************************/ + + +#ifndef __FTRFORK_H__ +#define __FTRFORK_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H + + +FT_BEGIN_HEADER + + + /* Number of guessing rules supported in `FT_Raccess_Guess'. */ + /* Don't forget to increment the number if you add a new guessing rule. */ +#define FT_RACCESS_N_RULES 8 + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Raccess_Guess */ + /* */ + /* <Description> */ + /* Guess a file name and offset where the actual resource fork is */ + /* stored. The macro FT_RACCESS_N_RULES holds the number of */ + /* guessing rules; the guessed result for the Nth rule is */ + /* represented as a triplet: a new file name (new_names[N]), a file */ + /* offset (offsets[N]), and an error code (errors[N]). */ + /* */ + /* <Input> */ + /* library :: */ + /* A FreeType library instance. */ + /* */ + /* stream :: */ + /* A file stream containing the resource fork. */ + /* */ + /* base_name :: */ + /* The (base) file name of the resource fork used for some */ + /* guessing rules. */ + /* */ + /* <Output> */ + /* new_names :: */ + /* An array of guessed file names in which the resource forks may */ + /* exist. If `new_names[N]' is NULL, the guessed file name is */ + /* equal to `base_name'. */ + /* */ + /* offsets :: */ + /* An array of guessed file offsets. `offsets[N]' holds the file */ + /* offset of the possible start of the resource fork in file */ + /* `new_names[N]'. */ + /* */ + /* errors :: */ + /* An array of FreeType error codes. `errors[N]' is the error */ + /* code of Nth guessing rule function. If `errors[N]' is not */ + /* FT_Err_Ok, `new_names[N]' and `offsets[N]' are meaningless. */ + /* */ + FT_BASE( void ) + FT_Raccess_Guess( FT_Library library, + FT_Stream stream, + char* base_name, + char** new_names, + FT_Long* offsets, + FT_Error* errors ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Raccess_Get_HeaderInfo */ + /* */ + /* <Description> */ + /* Get the information from the header of resource fork. The */ + /* information includes the file offset where the resource map */ + /* starts, and the file offset where the resource data starts. */ + /* `FT_Raccess_Get_DataOffsets' requires these two data. */ + /* */ + /* <Input> */ + /* library :: */ + /* A FreeType library instance. */ + /* */ + /* stream :: */ + /* A file stream containing the resource fork. */ + /* */ + /* rfork_offset :: */ + /* The file offset where the resource fork starts. */ + /* */ + /* <Output> */ + /* map_offset :: */ + /* The file offset where the resource map starts. */ + /* */ + /* rdata_pos :: */ + /* The file offset where the resource data starts. */ + /* */ + /* <Return> */ + /* FreeType error code. FT_Err_Ok means success. */ + /* */ + FT_BASE( FT_Error ) + FT_Raccess_Get_HeaderInfo( FT_Library library, + FT_Stream stream, + FT_Long rfork_offset, + FT_Long *map_offset, + FT_Long *rdata_pos ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Raccess_Get_DataOffsets */ + /* */ + /* <Description> */ + /* Get the data offsets for a tag in a resource fork. Offsets are */ + /* stored in an array because, in some cases, resources in a resource */ + /* fork have the same tag. */ + /* */ + /* <Input> */ + /* library :: */ + /* A FreeType library instance. */ + /* */ + /* stream :: */ + /* A file stream containing the resource fork. */ + /* */ + /* map_offset :: */ + /* The file offset where the resource map starts. */ + /* */ + /* rdata_pos :: */ + /* The file offset where the resource data starts. */ + /* */ + /* tag :: */ + /* The resource tag. */ + /* */ + /* <Output> */ + /* offsets :: */ + /* The stream offsets for the resource data specified by `tag'. */ + /* This array is allocated by the function, so you have to call */ + /* @FT_Free after use. */ + /* */ + /* count :: */ + /* The length of offsets array. */ + /* */ + /* <Return> */ + /* FreeType error code. FT_Err_Ok means success. */ + /* */ + /* <Note> */ + /* Normally you should use `FT_Raccess_Get_HeaderInfo' to get the */ + /* value for `map_offset' and `rdata_pos'. */ + /* */ + FT_BASE( FT_Error ) + FT_Raccess_Get_DataOffsets( FT_Library library, + FT_Stream stream, + FT_Long map_offset, + FT_Long rdata_pos, + FT_Long tag, + FT_Long **offsets, + FT_Long *count ); + + +FT_END_HEADER + +#endif /* __FTRFORK_H__ */ + + +/* END */ diff --git a/headers/libs/freetype2/freetype/internal/ftserv.h b/headers/libs/freetype2/freetype/internal/ftserv.h new file mode 100644 index 0000000000..e5ed8895b3 --- /dev/null +++ b/headers/libs/freetype2/freetype/internal/ftserv.h @@ -0,0 +1,260 @@ +/***************************************************************************/ +/* */ +/* ftserv.h */ +/* */ +/* The FreeType services (specification only). */ +/* */ +/* Copyright 2003 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. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* Each module can export one or more `services'. Each service is */ + /* identified by a constant string and modeled by a pointer; the latter */ + /* generally corresponds to a structure containing function pointers. */ + /* */ + /* Note that a service's data cannot be a mere function pointer because */ + /* in C it is possible that function pointers might be implemented */ + /* differently than data pointers (e.g. 48 bits instead of 32). */ + /* */ + /*************************************************************************/ + + +#ifndef __FTSERV_H__ +#define __FTSERV_H__ + + +FT_BEGIN_HEADER + + + /* + * @macro: + * FT_FACE_FIND_SERVICE + * + * @description: + * This macro is used to look up a service from a face's driver module. + * + * @input: + * face :: + * The source face handle. + * + * id :: + * A string describing the service as defined in the service's + * header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to + * `multi-masters'). It is automatically prefixed with + * `FT_SERVICE_ID_'. + * + * @output: + * ptr :: + * A variable that receives the service pointer. Will be NULL + * if not found. + */ +#define FT_FACE_FIND_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + FT_Module module = FT_MODULE( FT_FACE(face)->driver ); \ + /* the strange cast is to allow C++ compilation */ \ + FT_Pointer* Pptr = (FT_Pointer*) &(ptr); \ + \ + \ + *Pptr = NULL; \ + if ( module->clazz->get_interface ) \ + *Pptr = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \ + FT_END_STMNT + + + /* + * @macro: + * FT_FACE_FIND_GLOBAL_SERVICE + * + * @description: + * This macro is used to look up a service from all modules. + * + * @input: + * face :: + * The source face handle. + * + * id :: + * A string describing the service as defined in the service's + * header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to + * `multi-masters'). It is automatically prefixed with + * `FT_SERVICE_ID_'. + * + * @output: + * ptr :: + * A variable that receives the service pointer. Will be NULL + * if not found. + */ +#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + FT_Module module = FT_MODULE( FT_FACE(face)->driver ); \ + /* the strange cast is to allow C++ compilation */ \ + FT_Pointer* Pptr = (FT_Pointer*) &(ptr); \ + \ + \ + *Pptr = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \ + FT_END_STMNT + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** S E R V I C E D E S C R I P T O R S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* + * The following structure is used to _describe_ a given service + * to the library. This is useful to build simple static service lists. + */ + typedef struct FT_ServiceDescRec_ + { + const char* serv_id; /* service name */ + const void* serv_data; /* service pointer/data */ + + } FT_ServiceDescRec; + + typedef const FT_ServiceDescRec* FT_ServiceDesc; + + + /* + * Parse a list of FT_ServiceDescRec descriptors and look for + * a specific service by ID. Note that the last element in the + * array must be { NULL, NULL }, and that the function should + * return NULL if the service isn't available. + * + * This function can be used by modules to implement their + * `get_service' method. + */ + FT_BASE( FT_Pointer ) + ft_service_list_lookup( FT_ServiceDesc service_descriptors, + const char* service_id ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** S E R V I C E S C A C H E *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* + * This structure is used to store a cache for several frequently used + * services. It is the type of `face->internal->services'. You + * should only use FT_FACE_LOOKUP_SERVICE to access it. + * + * All fields should have the type FT_Pointer to relax compilation + * dependencies. We assume the developer isn't completely stupid. + * + * Each field must be named `service_XXXX' where `XXX' corresponds to + * the correct FT_SERVICE_ID_XXXX macro. See the definition of + * FT_FACE_LOOKUP_SERVICE below how this is implemented. + * + */ + typedef struct FT_ServiceCacheRec_ + { + FT_Pointer service_POSTSCRIPT_FONT_NAME; + FT_Pointer service_MULTI_MASTERS; + FT_Pointer service_GLYPH_DICT; + FT_Pointer service_PFR_METRICS; + FT_Pointer service_WINFNT; + + } FT_ServiceCacheRec, *FT_ServiceCache; + + + /* + * A magic number used within the services cache. + */ +#define FT_SERVICE_UNAVAILABLE ((FT_Pointer)-2) /* magic number */ + + + /* + * @macro: + * FT_FACE_LOOKUP_SERVICE + * + * @description: + * This macro is used to lookup a service from a face's driver module + * using its cache. + * + * @input: + * face:: + * The source face handle containing the cache. + * + * field :: + * The field name in the cache. + * + * id :: + * The service ID. + * + * @output: + * ptr :: + * A variable receiving the service data. NULL if not available. + */ +#define FT_FACE_LOOKUP_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + /* the strange cast is to allow C++ compilation */ \ + FT_Pointer* pptr = (FT_Pointer*)&(ptr); \ + FT_Pointer svc; \ + \ + \ + svc = FT_FACE(face)->internal->services. service_ ## id ; \ + if ( svc == FT_SERVICE_UNAVAILABLE ) \ + svc = NULL; \ + else if ( svc == NULL ) \ + { \ + FT_FACE_FIND_SERVICE( face, svc, id ); \ + \ + FT_FACE(face)->internal->services. service_ ## id = \ + (FT_Pointer)( svc != NULL ? svc \ + : FT_SERVICE_UNAVAILABLE ); \ + } \ + *pptr = svc; \ + FT_END_STMNT + + + /* + * A macro used to define new service structure types. + */ + +#define FT_DEFINE_SERVICE( name ) \ + typedef struct FT_Service_ ## name ## Rec_ \ + FT_Service_ ## name ## Rec ; \ + typedef struct FT_Service_ ## name ## Rec_ \ + const * FT_Service_ ## name ; \ + struct FT_Service_ ## name ## Rec_ + + /* */ + + /* + * The header files containing the services. + */ + +#define FT_SERVICE_MULTIPLE_MASTERS_H <freetype/internal/services/svmm.h> +#define FT_SERVICE_POSTSCRIPT_NAME_H <freetype/internal/services/svpostnm.h> +#define FT_SERVICE_POSTSCRIPT_CMAPS_H <freetype/internal/services/svpscmap.h> +#define FT_SERVICE_POSTSCRIPT_INFO_H <freetype/internal/services/svpsinfo.h> +#define FT_SERVICE_GLYPH_DICT_H <freetype/internal/services/svgldict.h> +#define FT_SERVICE_BDF_H <freetype/internal/services/svbdf.h> +#define FT_SERVICE_XFREE86_NAME_H <freetype/internal/services/svxf86nm.h> +#define FT_SERVICE_SFNT_H <freetype/internal/services/svsfnt.h> +#define FT_SERVICE_PFR_H <freetype/internal/services/svpfr.h> +#define FT_SERVICE_WINFNT_H <freetype/internal/services/svwinfnt.h> +#define FT_SERVICE_TT_CMAP_H <freetype/internal/services/svttcmap.h> + + /* */ + +FT_END_HEADER + +#endif /* __FTSERV_H__ */ + + +/* END */ diff --git a/headers/libs/freetype2/freetype/internal/ftstream.h b/headers/libs/freetype2/freetype/internal/ftstream.h index 75d27f46a4..87576fd0e9 100644 --- a/headers/libs/freetype2/freetype/internal/ftstream.h +++ b/headers/libs/freetype2/freetype/internal/ftstream.h @@ -4,7 +4,7 @@ /* */ /* Stream handling (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -315,6 +315,17 @@ FT_BEGIN_HEADER #endif /* FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM */ + /* create a new (input) stream from an FT_Open_Args structure */ + FT_BASE( FT_Error ) + FT_Stream_New( FT_Library library, + const FT_Open_Args* args, + FT_Stream *astream ); + + /* free a stream */ + FT_BASE( void ) + FT_Stream_Free( FT_Stream stream, + FT_Int external ); + /* initialize a stream for reading in-memory data */ FT_BASE( void ) FT_Stream_OpenMemory( FT_Stream stream, @@ -495,4 +506,4 @@ FT_END_HEADER #endif /* __FTSTREAM_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/internal/fttrace.h b/headers/libs/freetype2/freetype/internal/fttrace.h index dc811e3a9e..dffe9cfee9 100644 --- a/headers/libs/freetype2/freetype/internal/fttrace.h +++ b/headers/libs/freetype2/freetype/internal/fttrace.h @@ -4,7 +4,7 @@ /* */ /* Tracing handling (specification only). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,12 +16,12 @@ /***************************************************************************/ -/* definitions of trace levels for FreeType 2 */ + /* definitions of trace levels for FreeType 2 */ -/* the first level must always be `trace_any' */ + /* the first level must always be `trace_any' */ FT_TRACE_DEF( any ) -/* base components */ + /* base components */ FT_TRACE_DEF( calc ) /* calculations (ftcalc.c) */ FT_TRACE_DEF( memory ) /* memory manager (ftobjs.c) */ FT_TRACE_DEF( stream ) /* stream manager (ftstream.c) */ @@ -35,14 +35,15 @@ FT_TRACE_DEF( glyph ) /* glyph management (ftglyph.c) */ FT_TRACE_DEF( raster ) /* monochrome rasterizer (ftraster.c) */ FT_TRACE_DEF( smooth ) /* anti-aliasing raster (ftgrays.c) */ FT_TRACE_DEF( mm ) /* MM interface (ftmm.c) */ +FT_TRACE_DEF( raccess ) /* resource fork accessor (ftrfork.c) */ /* Cache sub-system */ -FT_TRACE_DEF( cache ) /* cache sub-system (ftcache.c, etc..) */ +FT_TRACE_DEF( cache ) /* cache sub-system (ftcache.c, etc.) */ /* SFNT driver components */ -FT_TRACE_DEF( sfobjs ) /* SFNT object handler (sfobjs.c) */ -FT_TRACE_DEF( ttcmap ) /* charmap handler (ttcmap.c) */ -FT_TRACE_DEF( ttload ) /* basic TrueType tables (ttload.c) */ +FT_TRACE_DEF( sfobjs ) /* SFNT object handler (sfobjs.c) */ +FT_TRACE_DEF( ttcmap ) /* charmap handler (ttcmap.c) */ +FT_TRACE_DEF( ttload ) /* basic TrueType tables (ttload.c) */ FT_TRACE_DEF( ttpost ) /* PS table processing (ttpost.c) */ FT_TRACE_DEF( ttsbit ) /* TrueType sbit handling (ttsbit.c) */ @@ -103,4 +104,4 @@ FT_TRACE_DEF( bdflib ) FT_TRACE_DEF( pfr ) -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/internal/internal.h b/headers/libs/freetype2/freetype/internal/internal.h index 2996c962e9..1e5ac44d54 100644 --- a/headers/libs/freetype2/freetype/internal/internal.h +++ b/headers/libs/freetype2/freetype/internal/internal.h @@ -4,7 +4,7 @@ /* */ /* Internal header files (specification only). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -27,26 +27,18 @@ #define FT_INTERNAL_OBJECTS_H <freetype/internal/ftobjs.h> #define FT_INTERNAL_STREAM_H <freetype/internal/ftstream.h> #define FT_INTERNAL_MEMORY_H <freetype/internal/ftmemory.h> -#define FT_INTERNAL_EXTENSION_H <freetype/internal/ftextend.h> #define FT_INTERNAL_DEBUG_H <freetype/internal/ftdebug.h> #define FT_INTERNAL_CALC_H <freetype/internal/ftcalc.h> #define FT_INTERNAL_DRIVER_H <freetype/internal/ftdriver.h> -#define FT_INTERNAL_EXTEND_H <freetype/internal/ftextend.h> #define FT_INTERNAL_TRACE_H <freetype/internal/fttrace.h> #define FT_INTERNAL_GLYPH_LOADER_H <freetype/internal/ftgloadr.h> #define FT_INTERNAL_SFNT_H <freetype/internal/sfnt.h> -#define FT_INTERNAL_HASH_H <freetype/internal/fthash.h> -#define FT_INTERNAL_OBJECT_H <freetype/internal/ftobject.h> +#define FT_INTERNAL_SERVICE_H <freetype/internal/ftserv.h> +#define FT_INTERNAL_RFORK_H <freetype/internal/ftrfork.h> #define FT_INTERNAL_TRUETYPE_TYPES_H <freetype/internal/tttypes.h> #define FT_INTERNAL_TYPE1_TYPES_H <freetype/internal/t1types.h> -#define FT_INTERNAL_TYPE42_TYPES_H <freetype/internal/t42types.h> -#define FT_INTERNAL_CFF_TYPES_H <freetype/internal/cfftypes.h> -#define FT_INTERNAL_FNT_TYPES_H <freetype/internal/fnttypes.h> -#define FT_INTERNAL_BDF_TYPES_H <freetype/internal/bdftypes.h> -#define FT_INTERNAL_PFR_H <freetype/internal/pfr.h> -#define FT_INTERNAL_POSTSCRIPT_NAMES_H <freetype/internal/psnames.h> #define FT_INTERNAL_POSTSCRIPT_AUX_H <freetype/internal/psaux.h> #define FT_INTERNAL_POSTSCRIPT_HINTS_H <freetype/internal/pshints.h> #define FT_INTERNAL_POSTSCRIPT_GLOBALS_H <freetype/internal/psglobal.h> @@ -54,4 +46,4 @@ #define FT_INTERNAL_AUTOHINT_H <freetype/internal/autohint.h> -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/internal/pcftypes.h b/headers/libs/freetype2/freetype/internal/pcftypes.h index eb90701dae..382796ffb4 100644 --- a/headers/libs/freetype2/freetype/internal/pcftypes.h +++ b/headers/libs/freetype2/freetype/internal/pcftypes.h @@ -2,7 +2,7 @@ FreeType font driver for pcf fonts - Copyright (C) 2000-2001 by + Copyright (C) 2000, 2001, 2002 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy @@ -53,4 +53,4 @@ FT_END_HEADER #endif /* __PCFTYPES_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/internal/pfr.h b/headers/libs/freetype2/freetype/internal/pfr.h deleted file mode 100644 index 49a0d40148..0000000000 --- a/headers/libs/freetype2/freetype/internal/pfr.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef __FT_INTERNAL_PFR_H__ -#define __FT_INTERNAL_PFR_H__ - -#include <ft2build.h> -#include FT_FREETYPE_H - -FT_BEGIN_HEADER - - typedef FT_Error (*FT_PFR_GetMetricsFunc)( FT_Face face, - FT_UInt *aoutline, - FT_UInt *ametrics, - FT_Fixed *ax_scale, - FT_Fixed *ay_scale ); - - typedef FT_Error (*FT_PFR_GetKerningFunc)( FT_Face face, - FT_UInt left, - FT_UInt right, - FT_Vector *avector ); - - typedef FT_Error (*FT_PFR_GetAdvanceFunc)( FT_Face face, - FT_UInt gindex, - FT_Pos *aadvance ); - - typedef struct FT_PFR_ServiceRec_ - { - FT_PFR_GetMetricsFunc get_metrics; - FT_PFR_GetKerningFunc get_kerning; - FT_PFR_GetAdvanceFunc get_advance; - - } FT_PFR_ServiceRec, *FT_PFR_Service; - -#define FT_PFR_SERVICE_NAME "pfr" - -FT_END_HEADER - -#endif /* __FT_INTERNAL_PFR_H__ */ diff --git a/headers/libs/freetype2/freetype/internal/psaux.h b/headers/libs/freetype2/freetype/internal/psaux.h index 67b3a32e4f..8d419be087 100644 --- a/headers/libs/freetype2/freetype/internal/psaux.h +++ b/headers/libs/freetype2/freetype/internal/psaux.h @@ -5,7 +5,7 @@ /* Auxiliary functions and data structures related to PostScript fonts */ /* (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,6 +24,7 @@ #include <ft2build.h> #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_TYPE1_TYPES_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H FT_BEGIN_HEADER @@ -70,10 +71,10 @@ FT_BEGIN_HEADER (*done)( PS_Table table ); FT_Error - (*add)( PS_Table table, - FT_Int index, - void* object, - FT_Int length ); + (*add)( PS_Table table, + FT_Int idx, + void* object, + FT_PtrDist length ); void (*release)( PS_Table table ); @@ -123,7 +124,7 @@ FT_BEGIN_HEADER FT_Int max_elems; FT_Int num_elems; FT_Byte** elements; /* addresses of table elements */ - FT_Int* lengths; /* lengths of table elements */ + FT_PtrDist* lengths; /* lengths of table elements */ FT_Memory memory; PS_Table_FuncsRec funcs; @@ -177,7 +178,9 @@ FT_BEGIN_HEADER T1_FIELD_TYPE_BOOL, T1_FIELD_TYPE_INTEGER, T1_FIELD_TYPE_FIXED, + T1_FIELD_TYPE_FIXED_1000, T1_FIELD_TYPE_STRING, + T1_FIELD_TYPE_KEY, T1_FIELD_TYPE_BBOX, T1_FIELD_TYPE_INTEGER_ARRAY, T1_FIELD_TYPE_FIXED_ARRAY, @@ -261,7 +264,7 @@ FT_BEGIN_HEADER }, -#define T1_FIELD_TYPE_BOOL( _ident, _fname ) \ +#define T1_FIELD_BOOL( _ident, _fname ) \ T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BOOL, _fname ) #define T1_FIELD_NUM( _ident, _fname ) \ @@ -270,9 +273,15 @@ FT_BEGIN_HEADER #define T1_FIELD_FIXED( _ident, _fname ) \ T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED, _fname ) +#define T1_FIELD_FIXED_1000( _ident, _fname ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED_1000, _fname ) + #define T1_FIELD_STRING( _ident, _fname ) \ T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_STRING, _fname ) +#define T1_FIELD_KEY( _ident, _fname ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_KEY, _fname ) + #define T1_FIELD_BBOX( _ident, _fname ) \ T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BBOX, _fname ) @@ -321,13 +330,21 @@ FT_BEGIN_HEADER void (*skip_spaces)( PS_Parser parser ); void - (*skip_alpha)( PS_Parser parser ); + (*skip_PS_token)( PS_Parser parser ); FT_Long (*to_int)( PS_Parser parser ); FT_Fixed (*to_fixed)( PS_Parser parser, FT_Int power_ten ); + + FT_Error + (*to_bytes)( PS_Parser parser, + FT_Byte* bytes, + FT_Long max_bytes, + FT_Long* pnum_bytes, + FT_Bool delimiters ); + FT_Int (*to_coord_array)( PS_Parser parser, FT_Int max_coords, @@ -634,14 +651,14 @@ FT_BEGIN_HEADER T1_Decoder_ZoneRec zones[T1_MAX_SUBRS_CALLS + 1]; T1_Decoder_Zone zone; - PSNames_Service psnames; /* for seac */ + FT_Service_PsCMaps psnames; /* for seac */ FT_UInt num_glyphs; FT_Byte** glyph_names; FT_Int lenIV; /* internal for sub routine calls */ FT_UInt num_subrs; FT_Byte** subrs; - FT_Int* subrs_len; /* array of subrs length (optional) */ + FT_PtrDist* subrs_len; /* array of subrs length (optional) */ FT_Matrix font_matrix; FT_Vector font_offset; @@ -652,7 +669,6 @@ FT_BEGIN_HEADER PS_Blend blend; /* for multiple master support */ - FT_UInt32 hint_flags; FT_Render_Mode hint_mode; T1_Decoder_Callback parse_callback; @@ -714,4 +730,4 @@ FT_END_HEADER #endif /* __PSAUX_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/internal/pshints.h b/headers/libs/freetype2/freetype/internal/pshints.h index 5f3005f717..cd48f6cf32 100644 --- a/headers/libs/freetype2/freetype/internal/pshints.h +++ b/headers/libs/freetype2/freetype/internal/pshints.h @@ -6,7 +6,7 @@ /* recorders (specification only). These are used to support native */ /* T1/T2 hints in the "type1", "cid" and "cff" font drivers. */ /* */ -/* Copyright 2001, 2002 by */ +/* Copyright 2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -261,13 +261,13 @@ FT_BEGIN_HEADER /* been recorded. */ /* */ /* @input: */ - /* hints :: A handle to the Type 1 hints recorder. */ + /* hints :: A handle to the Type 1 hints recorder. */ /* */ - /* outline :: A pointer to the target outline descriptor. */ + /* outline :: A pointer to the target outline descriptor. */ /* */ - /* globals :: The hinter globals for this font. */ + /* globals :: The hinter globals for this font. */ /* */ - /* hint_flags :: Hinter bit flags. */ + /* hint_mode :: Hinting information. */ /* */ /* @return: */ /* FreeType error code. 0 means success. */ @@ -542,13 +542,13 @@ FT_BEGIN_HEADER /* method. */ /* */ /* @input: */ - /* hints :: A handle to the Type 2 hints recorder. */ + /* hints :: A handle to the Type 2 hints recorder. */ /* */ - /* outline :: A pointer to the target outline descriptor. */ + /* outline :: A pointer to the target outline descriptor. */ /* */ - /* globals :: The hinter globals for this font. */ + /* globals :: The hinter globals for this font. */ /* */ - /* hint_flags :: Hinter bit flags. */ + /* hint_mode :: Hinting information. */ /* */ /* @return: */ /* FreeType error code. 0 means success. */ @@ -623,4 +623,4 @@ FT_END_HEADER #endif /* __PSHINTS_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/internal/psnames.h b/headers/libs/freetype2/freetype/internal/psnames.h deleted file mode 100644 index 5cf58b12c6..0000000000 --- a/headers/libs/freetype2/freetype/internal/psnames.h +++ /dev/null @@ -1,241 +0,0 @@ -/***************************************************************************/ -/* */ -/* psnames.h */ -/* */ -/* High-level interface for the `PSNames' module (in charge of */ -/* various functions related to Postscript glyph names conversion). */ -/* */ -/* Copyright 1996-2001, 2002 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. */ -/* */ -/***************************************************************************/ - - -#ifndef __PSNAMES_H__ -#define __PSNAMES_H__ - - -#include <ft2build.h> -#include FT_FREETYPE_H - - -FT_BEGIN_HEADER - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* PS_Unicode_Value_Func */ - /* */ - /* <Description> */ - /* A function used to return the Unicode index corresponding to a */ - /* given glyph name. */ - /* */ - /* <Input> */ - /* glyph_name :: The glyph name. */ - /* */ - /* <Return> */ - /* The Unicode character index resp. the non-Unicode value 0xFFFF if */ - /* the glyph name has no known Unicode meaning. */ - /* */ - /* <Note> */ - /* This function is able to map several different glyph names to the */ - /* same Unicode value, according to the rules defined in the Adobe */ - /* Glyph List table. */ - /* */ - /* This function will not be compiled if the configuration macro */ - /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST is undefined. */ - /* */ - typedef FT_UInt32 - (*PS_Unicode_Value_Func)( const char* glyph_name ); - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* PS_Unicode_Index_Func */ - /* */ - /* <Description> */ - /* A function used to return the glyph index corresponding to a given */ - /* Unicode value. */ - /* */ - /* <Input> */ - /* num_glyphs :: The number of glyphs in the face. */ - /* */ - /* glyph_names :: An array of glyph name pointers. */ - /* */ - /* unicode :: The Unicode value. */ - /* */ - /* <Return> */ - /* The glyph index resp. 0xFFFF if no glyph corresponds to this */ - /* Unicode value. */ - /* */ - /* <Note> */ - /* This function is able to recognize several glyph names per Unicode */ - /* value, according to the Adobe Glyph List. */ - /* */ - /* This function will not be compiled if the configuration macro */ - /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST is undefined. */ - /* */ - typedef FT_UInt - (*PS_Unicode_Index_Func)( FT_UInt num_glyphs, - const char** glyph_names, - FT_ULong unicode ); - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* PS_Macintosh_Name_Func */ - /* */ - /* <Description> */ - /* A function used to return the glyph name corresponding to an Apple */ - /* glyph name index. */ - /* */ - /* <Input> */ - /* name_index :: The index of the Mac name. */ - /* */ - /* <Return> */ - /* The glyph name, or 0 if the index is invalid. */ - /* */ - /* <Note> */ - /* This function will not be compiled if the configuration macro */ - /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES is undefined. */ - /* */ - typedef const char* - (*PS_Macintosh_Name_Func)( FT_UInt name_index ); - - - typedef const char* - (*PS_Adobe_Std_Strings_Func)( FT_UInt string_index ); - - - typedef struct PS_UniMap_ - { - FT_UInt unicode; - FT_UInt glyph_index; - - } PS_UniMap; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* PS_Unicodes */ - /* */ - /* <Description> */ - /* A simple table used to map Unicode values to glyph indices. It is */ - /* built by the PS_Build_Unicodes table according to the glyphs */ - /* present in a font file. */ - /* */ - /* <Fields> */ - /* num_codes :: The number of glyphs in the font that match a given */ - /* Unicode value. */ - /* */ - /* unicodes :: An array of unicode values, sorted in increasing */ - /* order. */ - /* */ - /* gindex :: An array of glyph indices, corresponding to each */ - /* Unicode value. */ - /* */ - /* <Note> */ - /* Use the function PS_Lookup_Unicode() to retrieve the glyph index */ - /* corresponding to a given Unicode character code. */ - /* */ - typedef struct PS_Unicodes_ - { - FT_UInt num_maps; - PS_UniMap* maps; - - } PS_Unicodes; - - - typedef FT_Error - (*PS_Build_Unicodes_Func)( FT_Memory memory, - FT_UInt num_glyphs, - const char** glyph_names, - PS_Unicodes* unicodes ); - - typedef FT_UInt - (*PS_Lookup_Unicode_Func)( PS_Unicodes* unicodes, - FT_UInt unicode ); - - typedef FT_ULong - (*PS_Next_Unicode_Func)( PS_Unicodes* unicodes, - FT_ULong unicode ); - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* PSNames_Interface */ - /* */ - /* <Description> */ - /* This structure defines the PSNames interface. */ - /* */ - /* <Fields> */ - /* unicode_value :: A function used to convert a glyph name */ - /* into a Unicode character code. */ - /* */ - /* build_unicodes :: A function which builds up the Unicode */ - /* mapping table. */ - /* */ - /* lookup_unicode :: A function used to return the glyph index */ - /* corresponding to a given Unicode */ - /* character. */ - /* */ - /* macintosh_name :: A function used to return the standard */ - /* Apple glyph Postscript name corresponding */ - /* to a given string index (used by the */ - /* TrueType `post' table). */ - /* */ - /* adobe_std_strings :: A function that returns a pointer to a */ - /* Adobe Standard String for a given SID. */ - /* */ - /* adobe_std_encoding :: A table of 256 unsigned shorts that maps */ - /* character codes in the Adobe Standard */ - /* Encoding to SIDs. */ - /* */ - /* adobe_expert_encoding :: A table of 256 unsigned shorts that maps */ - /* character codes in the Adobe Expert */ - /* Encoding to SIDs. */ - /* */ - /* <Note> */ - /* `unicode_value' and `unicode_index' will be set to 0 if the */ - /* configuration macro FT_CONFIG_OPTION_ADOBE_GLYPH_LIST is */ - /* undefined. */ - /* */ - /* `macintosh_name' will be set to 0 if the configuration macro */ - /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES is undefined. */ - /* */ - typedef struct PSNames_Interface_ - { - PS_Unicode_Value_Func unicode_value; - PS_Build_Unicodes_Func build_unicodes; - PS_Lookup_Unicode_Func lookup_unicode; - PS_Macintosh_Name_Func macintosh_name; - - PS_Adobe_Std_Strings_Func adobe_std_strings; - const unsigned short* adobe_std_encoding; - const unsigned short* adobe_expert_encoding; - - PS_Next_Unicode_Func next_unicode; - - } PSNames_Interface; - - - typedef PSNames_Interface* PSNames_Service; - - -FT_END_HEADER - -#endif /* __PSNAMES_H__ */ - - -/* END */ diff --git a/headers/libs/freetype2/freetype/internal/services/svbdf.h b/headers/libs/freetype2/freetype/internal/services/svbdf.h new file mode 100644 index 0000000000..0f7fc6115d --- /dev/null +++ b/headers/libs/freetype2/freetype/internal/services/svbdf.h @@ -0,0 +1,57 @@ +/***************************************************************************/ +/* */ +/* svbdf.h */ +/* */ +/* The FreeType BDF services (specification). */ +/* */ +/* Copyright 2003 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. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVBDF_H__ +#define __SVBDF_H__ + +#include FT_BDF_H +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_BDF "bdf" + + typedef FT_Error + (*FT_BDF_GetCharsetIdFunc)( FT_Face face, + const char* *acharset_encoding, + const char* *acharset_registry ); + + typedef FT_Error + (*FT_BDF_GetPropertyFunc)( FT_Face face, + const char* prop_name, + BDF_PropertyRec *aproperty ); + + + FT_DEFINE_SERVICE( BDF ) + { + FT_BDF_GetCharsetIdFunc get_charset_id; + FT_BDF_GetPropertyFunc get_property; + }; + + /* */ + + +FT_END_HEADER + + +#endif /* __SVBDF_H__ */ + + +/* END */ diff --git a/headers/libs/freetype2/freetype/internal/services/svgldict.h b/headers/libs/freetype2/freetype/internal/services/svgldict.h new file mode 100644 index 0000000000..e5e56b253c --- /dev/null +++ b/headers/libs/freetype2/freetype/internal/services/svgldict.h @@ -0,0 +1,60 @@ +/***************************************************************************/ +/* */ +/* svgldict.h */ +/* */ +/* The FreeType glyph dictionary services (specification). */ +/* */ +/* Copyright 2003 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. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVGLDICT_H__ +#define __SVGLDICT_H__ + +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + + /* + * A service used to retrieve glyph names, as well as to find the + * index of a given glyph name in a font. + * + */ + +#define FT_SERVICE_ID_GLYPH_DICT "glyph-dict" + + + typedef FT_Error + (*FT_GlyphDict_GetNameFunc)( FT_Face face, + FT_UInt glyph_index, + FT_Pointer buffer, + FT_UInt buffer_max ); + + typedef FT_UInt + (*FT_GlyphDict_NameIndexFunc)( FT_Face face, + FT_String* glyph_name ); + + + FT_DEFINE_SERVICE( GlyphDict ) + { + FT_GlyphDict_GetNameFunc get_name; + FT_GlyphDict_NameIndexFunc name_index; /* optional */ + }; + + /* */ + + +FT_END_HEADER + + +#endif /* __SVGLDICT_H__ */ diff --git a/headers/libs/freetype2/freetype/internal/services/svmm.h b/headers/libs/freetype2/freetype/internal/services/svmm.h new file mode 100644 index 0000000000..926975ce88 --- /dev/null +++ b/headers/libs/freetype2/freetype/internal/services/svmm.h @@ -0,0 +1,68 @@ +/***************************************************************************/ +/* */ +/* svmm.h */ +/* */ +/* The FreeType Multiple Masters services (specification). */ +/* */ +/* Copyright 2003 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. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVMM_H__ +#define __SVMM_H__ + +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + + /* + * A service used to manage multiple-masters data in a given face. + * + * See the related APIs in `ftmm.h' (FT_MULTIPLE_MASTERS_H). + * + */ + +#define FT_SERVICE_ID_MULTI_MASTERS "multi-masters" + + + typedef FT_Error + (*FT_Get_MM_Func)( FT_Face face, + FT_Multi_Master* master ); + + typedef FT_Error + (*FT_Set_MM_Design_Func)( FT_Face face, + FT_UInt num_coords, + FT_Long* coords ); + + typedef FT_Error + (*FT_Set_MM_Blend_Func)( FT_Face face, + FT_UInt num_coords, + FT_Long* coords ); + + + FT_DEFINE_SERVICE( MultiMasters ) + { + FT_Get_MM_Func get_mm; + FT_Set_MM_Design_Func set_mm_design; + FT_Set_MM_Blend_Func set_mm_blend; + }; + + /* */ + + +FT_END_HEADER + +#endif /* __SVMM_H__ */ + + +/* END */ diff --git a/headers/libs/freetype2/freetype/internal/services/svpfr.h b/headers/libs/freetype2/freetype/internal/services/svpfr.h new file mode 100644 index 0000000000..b61050543e --- /dev/null +++ b/headers/libs/freetype2/freetype/internal/services/svpfr.h @@ -0,0 +1,65 @@ +/***************************************************************************/ +/* */ +/* svpfr.h */ +/* */ +/* Internal PFR service functions (specification). */ +/* */ +/* Copyright 2003 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. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVPFR_H__ +#define __SVPFR_H__ + +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_PFR_METRICS "pfr-metrics" + + + typedef FT_Error + (*FT_PFR_GetMetricsFunc)( FT_Face face, + FT_UInt *aoutline, + FT_UInt *ametrics, + FT_Fixed *ax_scale, + FT_Fixed *ay_scale ); + + typedef FT_Error + (*FT_PFR_GetKerningFunc)( FT_Face face, + FT_UInt left, + FT_UInt right, + FT_Vector *avector ); + + typedef FT_Error + (*FT_PFR_GetAdvanceFunc)( FT_Face face, + FT_UInt gindex, + FT_Pos *aadvance ); + + + FT_DEFINE_SERVICE( PfrMetrics ) + { + FT_PFR_GetMetricsFunc get_metrics; + FT_PFR_GetKerningFunc get_kerning; + FT_PFR_GetAdvanceFunc get_advance; + + }; + + /* */ + +FT_END_HEADER + +#endif /* __SVPFR_H__ */ + + +/* END */ diff --git a/headers/libs/freetype2/freetype/internal/services/svpostnm.h b/headers/libs/freetype2/freetype/internal/services/svpostnm.h new file mode 100644 index 0000000000..7f1700adb3 --- /dev/null +++ b/headers/libs/freetype2/freetype/internal/services/svpostnm.h @@ -0,0 +1,58 @@ +/***************************************************************************/ +/* */ +/* svpostnm.h */ +/* */ +/* The FreeType PostScript name services (specification). */ +/* */ +/* Copyright 2003 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. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVPOSTNM_H__ +#define __SVPOSTNM_H__ + +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + /* + * A trivial service used to retrieve the PostScript name of a given + * font when available. The `get_name' field should never be NULL. + * + * The correponding function can return NULL to indicate that the + * PostScript name is not available. + * + * The name is owned by the face and will be destroyed with it. + */ + +#define FT_SERVICE_ID_POSTSCRIPT_FONT_NAME "postscript-font-name" + + + typedef const char* + (*FT_PsName_GetFunc)( FT_Face face ); + + + FT_DEFINE_SERVICE( PsFontName ) + { + FT_PsName_GetFunc get_ps_font_name; + }; + + /* */ + + +FT_END_HEADER + + +#endif /* __SVPOSTNM_H__ */ + + +/* END */ diff --git a/headers/libs/freetype2/freetype/internal/services/svpscmap.h b/headers/libs/freetype2/freetype/internal/services/svpscmap.h new file mode 100644 index 0000000000..ade96ef8f1 --- /dev/null +++ b/headers/libs/freetype2/freetype/internal/services/svpscmap.h @@ -0,0 +1,113 @@ +/***************************************************************************/ +/* */ +/* svpscmap.h */ +/* */ +/* The FreeType PostScript charmap service (specification). */ +/* */ +/* Copyright 2003 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. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVPSCMAP_H__ +#define __SVPSCMAP_H__ + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_POSTSCRIPT_CMAPS "postscript-cmaps" + + + /* + * Adobe glyph name to unicode value + */ + typedef FT_UInt32 + (*PS_Unicode_ValueFunc)( const char* glyph_name ); + + /* + * Unicode value to Adobe glyph name index. 0xFFFF if not found. + */ + typedef FT_UInt + (*PS_Unicode_Index_Func)( FT_UInt num_glyphs, + const char** glyph_names, + FT_ULong unicode ); + + /* + * Macintosh name id to glyph name. NULL if invalid index. + */ + typedef const char* + (*PS_Macintosh_Name_Func)( FT_UInt name_index ); + + /* + * Adobe standard string ID to glyph name. NULL if invalid index. + */ + typedef const char* + (*PS_Adobe_Std_Strings_Func)( FT_UInt string_index ); + + /* + * Simple unicode -> glyph index charmap built from font glyph names + * table. + */ + typedef struct PS_UniMap_ + { + FT_UInt unicode; + FT_UInt glyph_index; + + } PS_UniMap; + + + typedef struct PS_Unicodes_ + { + FT_UInt num_maps; + PS_UniMap* maps; + + } PS_Unicodes; + + + typedef FT_Error + (*PS_Unicodes_InitFunc)( FT_Memory memory, + FT_UInt num_glyphs, + const char** glyph_names, + PS_Unicodes* unicodes ); + + typedef FT_UInt + (*PS_Unicodes_CharIndexFunc)( PS_Unicodes* unicodes, + FT_UInt unicode ); + + typedef FT_ULong + (*PS_Unicodes_CharNextFunc)( PS_Unicodes* unicodes, + FT_ULong unicode ); + + + FT_DEFINE_SERVICE( PsCMaps ) + { + PS_Unicode_ValueFunc unicode_value; + + PS_Unicodes_InitFunc unicodes_init; + PS_Unicodes_CharIndexFunc unicodes_char_index; + PS_Unicodes_CharNextFunc unicodes_char_next; + + PS_Macintosh_Name_Func macintosh_name; + PS_Adobe_Std_Strings_Func adobe_std_strings; + const unsigned short* adobe_std_encoding; + const unsigned short* adobe_expert_encoding; + }; + + /* */ + + +FT_END_HEADER + + +#endif /* __SVPSCMAP_H__ */ + + +/* END */ diff --git a/headers/libs/freetype2/freetype/internal/services/svpsinfo.h b/headers/libs/freetype2/freetype/internal/services/svpsinfo.h new file mode 100644 index 0000000000..73c02cdb73 --- /dev/null +++ b/headers/libs/freetype2/freetype/internal/services/svpsinfo.h @@ -0,0 +1,55 @@ +/***************************************************************************/ +/* */ +/* svpsinfo.h */ +/* */ +/* The FreeType PostScript info service (specification). */ +/* */ +/* Copyright 2003 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. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVPSINFO_H__ +#define __SVPSINFO_H__ + +#include FT_INTERNAL_SERVICE_H +#include FT_INTERNAL_TYPE1_TYPES_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_POSTSCRIPT_INFO "postscript-info" + + + typedef FT_Error + (*PS_GetFontInfoFunc)( FT_Face face, + PS_FontInfoRec* afont_info ); + + typedef FT_Int + (*PS_HasGlyphNamesFunc)( FT_Face face ); + + + FT_DEFINE_SERVICE( PsInfo ) + { + PS_GetFontInfoFunc ps_get_font_info; + PS_HasGlyphNamesFunc ps_has_glyph_names; + }; + + /* */ + + +FT_END_HEADER + + +#endif /* __SVPSINFO_H__ */ + + +/* END */ diff --git a/headers/libs/freetype2/freetype/internal/services/svsfnt.h b/headers/libs/freetype2/freetype/internal/services/svsfnt.h new file mode 100644 index 0000000000..06a5b1c23d --- /dev/null +++ b/headers/libs/freetype2/freetype/internal/services/svsfnt.h @@ -0,0 +1,69 @@ +/***************************************************************************/ +/* */ +/* svsfnt.h */ +/* */ +/* The FreeType PostScript name services (specification). */ +/* */ +/* Copyright 2003 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. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVSFNT_H__ +#define __SVSFNT_H__ + +#include FT_INTERNAL_SERVICE_H +#include FT_TRUETYPE_TABLES_H + + +FT_BEGIN_HEADER + + + /* + * SFNT table loading service. + */ + +#define FT_SERVICE_ID_SFNT_TABLE "sfnt-table" + + + /* + * Used to implement FT_Load_Sfnt_Table(). + */ + typedef FT_Error + (*FT_SFNT_TableLoadFunc)( FT_Face face, + FT_ULong tag, + FT_Long offset, + FT_Byte* buffer, + FT_ULong* length ); + + /* + * Used to implement FT_Get_Sfnt_Table(). + */ + typedef void* + (*FT_SFNT_TableGetFunc)( FT_Face face, + FT_Sfnt_Tag tag ); + + + FT_DEFINE_SERVICE( SFNT_Table ) + { + FT_SFNT_TableLoadFunc load_table; + FT_SFNT_TableGetFunc get_table; + }; + + /* */ + + +FT_END_HEADER + + +#endif /* __SVSFNT_H__ */ + + +/* END */ diff --git a/headers/libs/freetype2/freetype/internal/services/svttcmap.h b/headers/libs/freetype2/freetype/internal/services/svttcmap.h new file mode 100644 index 0000000000..f92fcd0e2c --- /dev/null +++ b/headers/libs/freetype2/freetype/internal/services/svttcmap.h @@ -0,0 +1,77 @@ +/***************************************************************************/ +/* */ +/* svsttcmap.h */ +/* */ +/* The FreeType TrueType/sfnt cmap extra information service. */ +/* */ +/* Copyright 2003 by */ +/* Masatake YAMATO, Redhat K.K. */ +/* */ +/* Copyright 2003 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. */ +/* */ +/***************************************************************************/ + +/* Development of this service is support of + Information-technology Promotion Agency, Japan. */ + +#ifndef __SVTTCMAP_H__ +#define __SVTTCMAP_H__ + +#include FT_INTERNAL_SERVICE_H +#include FT_TRUETYPE_TABLES_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_TT_CMAP "tt-cmaps" + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_CMapInfo */ + /* */ + /* <Description> */ + /* A structure used to store TrueType/sfnt specific cmap information */ + /* which is not covered by the generic @FT_CharMap structure. This */ + /* structure can be accessed with the @FT_Get_TT_CMap_Info function. */ + /* */ + /* <Fields> */ + /* language :: */ + /* The language ID used in Mac fonts. Definitions of values are in */ + /* freetype/ttnameid.h. */ + /* */ + typedef struct TT_CMapInfo_ + { + FT_ULong language; + + } TT_CMapInfo; + + + typedef FT_Error + (*TT_CMap_Info_GetFunc)( FT_CharMap charmap, + TT_CMapInfo *cmap_info ); + + + FT_DEFINE_SERVICE( TTCMaps ) + { + TT_CMap_Info_GetFunc get_cmap_info; + }; + + /* */ + + +FT_END_HEADER + +#endif /* __SVTTCMAP_H__ */ + + +/* END */ diff --git a/src/libs/freetype2/sfnt/ttcmap.h b/headers/libs/freetype2/freetype/internal/services/svwinfnt.h similarity index 64% rename from src/libs/freetype2/sfnt/ttcmap.h rename to headers/libs/freetype2/freetype/internal/services/svwinfnt.h index 8daa7ada19..57f7765d92 100644 --- a/src/libs/freetype2/sfnt/ttcmap.h +++ b/headers/libs/freetype2/freetype/internal/services/svwinfnt.h @@ -1,10 +1,10 @@ /***************************************************************************/ /* */ -/* ttcmap.h */ +/* svwinfnt.h */ /* */ -/* TrueType character mapping table (cmap) support (specification). */ +/* The FreeType Windows FNT/FONT service (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,30 +16,35 @@ /***************************************************************************/ -#ifndef __TTCMAP_H__ -#define __TTCMAP_H__ +#ifndef __SVWINFNT_H__ +#define __SVWINFNT_H__ - -#include <ft2build.h> -#include FT_INTERNAL_TRUETYPE_TYPES_H +#include FT_INTERNAL_SERVICE_H +#include FT_WINFONTS_H FT_BEGIN_HEADER - FT_LOCAL( FT_Error ) - tt_face_load_charmap( TT_Face face, - TT_CMapTable cmap, - FT_Stream input ); +#define FT_SERVICE_ID_WINFNT "winfonts" - FT_LOCAL( FT_Error ) - tt_face_free_charmap( TT_Face face, - TT_CMapTable cmap ); + typedef FT_Error + (*FT_WinFnt_GetHeaderFunc)( FT_Face face, + FT_WinFNT_HeaderRec *aheader ); + + + FT_DEFINE_SERVICE( WinFnt ) + { + FT_WinFnt_GetHeaderFunc get_header; + }; + + /* */ FT_END_HEADER -#endif /* __TTCMAP_H__ */ + +#endif /* __SVWINFNT_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/internal/services/svxf86nm.h b/headers/libs/freetype2/freetype/internal/services/svxf86nm.h new file mode 100644 index 0000000000..3a33abcd8d --- /dev/null +++ b/headers/libs/freetype2/freetype/internal/services/svxf86nm.h @@ -0,0 +1,55 @@ +/***************************************************************************/ +/* */ +/* svxf86nm.h */ +/* */ +/* The FreeType XFree86 services (specification only). */ +/* */ +/* Copyright 2003 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. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVXF86NM_H__ +#define __SVXF86NM_H__ + +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + + /* + * A trivial service used to return the name of a face's font driver, + * according to the XFree86 nomenclature. Note that the service data + * is a simple constant string pointer. + */ + +#define FT_SERVICE_ID_XF86_NAME "xf86-driver-name" + +#define FT_XF86_FORMAT_TRUETYPE "TrueType" +#define FT_XF86_FORMAT_TYPE_1 "Type 1" +#define FT_XF86_FORMAT_BDF "BDF" +#define FT_XF86_FORMAT_PCF "PCF" +#define FT_XF86_FORMAT_TYPE_42 "Type 42" +#define FT_XF86_FORMAT_CID "CID Type 1" +#define FT_XF86_FORMAT_CFF "CFF" +#define FT_XF86_FORMAT_PFR "PFR" +#define FT_XF86_FORMAT_WINFNT "Windows FNT" + + /* */ + + +FT_END_HEADER + + +#endif /* __SVXF86NM_H__ */ + + +/* END */ diff --git a/headers/libs/freetype2/freetype/internal/sfnt.h b/headers/libs/freetype2/freetype/internal/sfnt.h index 011e894193..9a23b1f829 100644 --- a/headers/libs/freetype2/freetype/internal/sfnt.h +++ b/headers/libs/freetype2/freetype/internal/sfnt.h @@ -4,7 +4,7 @@ /* */ /* High-level `sfnt' driver interface (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -125,11 +125,6 @@ FT_BEGIN_HEADER (*TT_Done_Face_Func)( TT_Face face ); - typedef FT_Module_Interface - (*SFNT_Get_Interface_Func)( FT_Module module, - const char* func_interface ); - - /*************************************************************************/ /* */ /* <FuncType> */ @@ -245,6 +240,76 @@ FT_BEGIN_HEADER FT_ULong* length ); + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Find_SBit_Image_Func */ + /* */ + /* <Description> */ + /* Checks whether an embedded bitmap (an `sbit') exists for a given */ + /* glyph, at a given strike. */ + /* */ + /* <Input> */ + /* face :: The target face object. */ + /* */ + /* glyph_index :: The glyph index. */ + /* */ + /* strike_index :: The current strike index. */ + /* */ + /* <Output> */ + /* arange :: The SBit range containing the glyph index. */ + /* */ + /* astrike :: The SBit strike containing the glyph index. */ + /* */ + /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. Returns */ + /* SFNT_Err_Invalid_Argument if no sbit exists for the requested */ + /* glyph. */ + /* */ + typedef FT_Error + (*TT_Find_SBit_Image_Func)( TT_Face face, + FT_UInt glyph_index, + FT_ULong strike_index, + TT_SBit_Range *arange, + TT_SBit_Strike *astrike, + FT_ULong *aglyph_offset ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_SBit_Metrics_Func */ + /* */ + /* <Description> */ + /* Gets the big metrics for a given embedded bitmap. */ + /* */ + /* <Input> */ + /* stream :: The input stream. */ + /* */ + /* range :: The SBit range containing the glyph. */ + /* */ + /* <Output> */ + /* big_metrics :: A big SBit metrics structure for the glyph. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The stream cursor must be positioned at the glyph's offset within */ + /* the `EBDT' table before the call. */ + /* */ + /* If the image format uses variable metrics, the stream cursor is */ + /* positioned just after the metrics header in the `EBDT' table on */ + /* function exit. */ + /* */ + typedef FT_Error + (*TT_Load_SBit_Metrics_Func)( FT_Stream stream, + TT_SBit_Range range, + TT_SBit_Metrics metrics ); + + /*************************************************************************/ /* */ /* <FuncType> */ @@ -255,20 +320,27 @@ FT_BEGIN_HEADER /* returns its metrics. */ /* */ /* <Input> */ - /* face :: The target face object. */ + /* face :: */ + /* The target face object. */ /* */ - /* x_ppem :: The horizontal resolution in points per EM. */ + /* strike_index :: */ + /* The strike index. */ /* */ - /* y_ppem :: The vertical resolution in points per EM. */ + /* glyph_index :: */ + /* The current glyph index. */ /* */ - /* glyph_index :: The current glyph index. */ + /* load_flags :: */ + /* The current load flags. */ /* */ - /* stream :: The input stream. */ + /* stream :: */ + /* The input stream. */ /* */ /* <Output> */ - /* amap :: The target pixmap. */ + /* amap :: */ + /* The target pixmap. */ /* */ - /* ametrics :: A big sbit metrics structure for the glyph image. */ + /* ametrics :: */ + /* A big sbit metrics structure for the glyph image. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. Returns an error if no */ @@ -312,8 +384,8 @@ FT_BEGIN_HEADER /* */ typedef FT_Error (*TT_Set_SBit_Strike_Func)( TT_Face face, - FT_Int x_ppem, - FT_Int y_ppem, + FT_UInt x_ppem, + FT_UInt y_ppem, FT_ULong *astrike_index ); @@ -366,57 +438,6 @@ FT_BEGIN_HEADER FT_Bool vertical ); - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_CharMap_Load_Func */ - /* */ - /* <Description> */ - /* Loads a given TrueType character map into memory. */ - /* */ - /* <Input> */ - /* face :: A handle to the parent face object. */ - /* */ - /* stream :: A handle to the current stream object. */ - /* */ - /* <InOut> */ - /* cmap :: A pointer to a cmap object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - /* <Note> */ - /* The function assumes that the stream is already in use (i.e., */ - /* opened). In case of error, all partially allocated tables are */ - /* released. */ - /* */ - typedef FT_Error - (*TT_CharMap_Load_Func)( TT_Face face, - TT_CMapTable cmap, - FT_Stream input ); - - - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* TT_CharMap_Free_Func */ - /* */ - /* <Description> */ - /* Destroys a character mapping table. */ - /* */ - /* <Input> */ - /* face :: A handle to the parent face object. */ - /* */ - /* cmap :: A handle to a cmap object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - typedef FT_Error - (*TT_CharMap_Free_Func)( TT_Face face, - TT_CMapTable cmap ); - - /*************************************************************************/ /* */ /* <FuncType> */ @@ -457,21 +478,6 @@ FT_BEGIN_HEADER (*TT_Free_Table_Func)( TT_Face face ); - /*************************************************************************/ - /* */ - /* <FuncType> */ - /* SFNT_Load_Table_Func */ - /* */ - /* <Description> */ - /* Loads a given SFNT table in memory */ - /* */ - typedef FT_Error - (*SFNT_Load_Table_Func)( FT_Face face, - FT_ULong tag, - FT_Long offset, - FT_Byte* buffer, - FT_ULong* length ); - /*************************************************************************/ /* */ /* <Struct> */ @@ -491,7 +497,7 @@ FT_BEGIN_HEADER TT_Init_Face_Func init_face; TT_Load_Face_Func load_face; TT_Done_Face_Func done_face; - SFNT_Get_Interface_Func get_interface; + FT_Module_Requester get_interface; TT_Load_Any_Func load_any; TT_Load_SFNT_HeaderRec_Func load_sfnt_header; @@ -523,6 +529,8 @@ FT_BEGIN_HEADER /* see `ttsbit.h' */ TT_Set_SBit_Strike_Func set_sbit_strike; TT_Load_Table_Func load_sbits; + TT_Find_SBit_Image_Func find_sbit_image; + TT_Load_SBit_Metrics_Func load_sbit_metrics; TT_Load_SBit_Image_Func load_sbit_image; TT_Free_Table_Func free_sbits; @@ -530,10 +538,6 @@ FT_BEGIN_HEADER TT_Get_PS_Name_Func get_psname; TT_Free_Table_Func free_psnames; - /* see `ttcmap.h' */ - TT_CharMap_Load_Func load_charmap; - TT_CharMap_Free_Func free_charmap; - } SFNT_Interface; @@ -546,4 +550,4 @@ FT_END_HEADER #endif /* __SFNT_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/internal/t1types.h b/headers/libs/freetype2/freetype/internal/t1types.h index ed2081db6a..702bb1e4c6 100644 --- a/headers/libs/freetype2/freetype/internal/t1types.h +++ b/headers/libs/freetype2/freetype/internal/t1types.h @@ -5,7 +5,7 @@ /* Basic Type1/Type2 type definitions and interface (specification */ /* only). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,8 +23,9 @@ #include <ft2build.h> #include FT_TYPE1_TABLES_H -#include FT_INTERNAL_POSTSCRIPT_NAMES_H #include FT_INTERNAL_POSTSCRIPT_HINTS_H +#include FT_INTERNAL_SERVICE_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H FT_BEGIN_HEADER @@ -101,12 +102,12 @@ FT_BEGIN_HEADER FT_Int num_subrs; FT_Byte** subrs; - FT_Int* subrs_len; + FT_PtrDist* subrs_len; FT_Int num_glyphs; FT_String** glyph_names; /* array of glyph names */ FT_Byte** charstrings; /* array of glyph charstrings */ - FT_Int* charstrings_len; + FT_PtrDist* charstrings_len; FT_Byte paint_type; FT_Byte font_type; @@ -115,7 +116,7 @@ FT_BEGIN_HEADER FT_BBox font_bbox; FT_Long font_id; - FT_Int stroke_width; + FT_Fixed stroke_width; } T1_FontRec, *T1_Font; @@ -141,17 +142,6 @@ FT_BEGIN_HEADER /*************************************************************************/ - /*************************************************************************/ - /* */ - /* This structure/class is defined here because it is common to the */ - /* following formats: TTF, OpenType-TT, and OpenType-CFF. */ - /* */ - /* Note, however, that the classes TT_Size, TT_GlyphSlot, and TT_CharMap */ - /* are not shared between font drivers, and are thus defined normally in */ - /* `ttobjs.h'. */ - /* */ - /*************************************************************************/ - typedef struct T1_FaceRec_* T1_Face; typedef struct CID_FaceRec_* CID_Face; @@ -169,7 +159,7 @@ FT_BEGIN_HEADER /* support for Multiple Masters fonts */ PS_Blend blend; - + /* since FT 2.1 - interface to PostScript hinter */ const void* pshinter; @@ -183,8 +173,10 @@ FT_BEGIN_HEADER void* psaux; CID_FaceInfoRec cid; void* afm_data; + FT_Byte* binary_data; /* used if hex data has been converted */ + FT_Stream cid_stream; CID_Subrs subrs; - + /* since FT 2.1 - interface to PostScript hinter */ void* pshinter; @@ -196,4 +188,4 @@ FT_END_HEADER #endif /* __T1TYPES_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/internal/tttypes.h b/headers/libs/freetype2/freetype/internal/tttypes.h index 4870b4b3cc..02db8b4fc8 100644 --- a/headers/libs/freetype2/freetype/internal/tttypes.h +++ b/headers/libs/freetype2/freetype/internal/tttypes.h @@ -105,41 +105,6 @@ FT_BEGIN_HEADER } SFNT_HeaderRec, *SFNT_Header; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_TableDirRec */ - /* */ - /* <Description> */ - /* This structure models a TrueType table directory. It is used to */ - /* access the various tables of the font face. */ - /* */ - /* <Fields> */ - /* version :: The version number; starts with 0x00010000. */ - /* */ - /* numTables :: The number of tables. */ - /* */ - /* searchRange :: Unused. */ - /* */ - /* entrySelector :: Unused. */ - /* */ - /* rangeShift :: Unused. */ - /* */ - /* <Note> */ - /* This structure is only used during font opening. */ - /* */ - typedef struct TT_TableDirRec_ - { - FT_Fixed version; /* should be 0x10000 */ - FT_UShort numTables; /* number of tables */ - - FT_UShort searchRange; /* These parameters are only used */ - FT_UShort entrySelector; /* for a dichotomy search in the */ - FT_UShort rangeShift; /* directory. We ignore them. */ - - } TT_TableDirRec; - - /*************************************************************************/ /* */ /* <Struct> */ @@ -168,61 +133,6 @@ FT_BEGIN_HEADER } TT_TableRec, *TT_Table; - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_CMapDirRec */ - /* */ - /* <Description> */ - /* This structure describes the directory of the `cmap' table, */ - /* containing the font's character mappings table. */ - /* */ - /* <Fields> */ - /* tableVersionNumber :: The version number. */ - /* */ - /* numCMaps :: The number of charmaps in the font. */ - /* */ - /* <Note> */ - /* This structure is only used during font loading. */ - /* */ - typedef struct TT_CMapDirRec_ - { - FT_UShort tableVersionNumber; - FT_UShort numCMaps; - - } TT_CMapDirRec, *TT_CMapDir; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_CMapDirEntryRec */ - /* */ - /* <Description> */ - /* This structure describes a charmap in a TrueType font. */ - /* */ - /* <Fields> */ - /* platformID :: An ID used to specify for which platform this */ - /* charmap is defined (FreeType manages all platforms). */ - /* */ - /* encodingID :: A platform-specific ID used to indicate which source */ - /* encoding is used in this charmap. */ - /* */ - /* offset :: The offset of the charmap relative to the start of */ - /* the `cmap' table. */ - /* */ - /* <Note> */ - /* This structure is only used during font loading. */ - /* */ - typedef struct TT_CMapDirEntryRec_ - { - FT_UShort platformID; - FT_UShort platformEncodingID; - FT_Long offset; - - } TT_CMapDirEntryRec, *TT_CMapDirEntry; - - /*************************************************************************/ /* */ /* <Struct> */ @@ -908,201 +818,6 @@ FT_BEGIN_HEADER } TT_Post_NamesRec, *TT_Post_Names; - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*** ***/ - /*** ***/ - /*** TRUETYPE CHARMAPS SUPPORT ***/ - /*** ***/ - /*** ***/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /* format 0 */ - - typedef struct TT_CMap0_ - { - FT_ULong language; /* for Mac fonts (originally ushort) */ - - FT_Byte* glyphIdArray; - - } TT_CMap0Rec, *TT_CMap0; - - - /* format 2 */ - - typedef struct TT_CMap2SubHeaderRec_ - { - FT_UShort firstCode; /* first valid low byte */ - FT_UShort entryCount; /* number of valid low bytes */ - FT_Short idDelta; /* delta value to glyphIndex */ - FT_UShort idRangeOffset; /* offset from here to 1st code */ - - } TT_CMap2SubHeaderRec, *TT_CMap2SubHeader; - - - typedef struct TT_CMap2Rec_ - { - FT_ULong language; /* for Mac fonts (originally ushort) */ - - FT_UShort* subHeaderKeys; /* high byte mapping table */ - /* value = subHeader index * 8 */ - TT_CMap2SubHeader subHeaders; - FT_UShort* glyphIdArray; - FT_UShort numGlyphId; /* control value */ - - } TT_CMap2Rec, *TT_CMap2; - - - /* format 4 */ - - typedef struct TT_CMap4Segment_ - { - FT_UShort endCount; - FT_UShort startCount; - FT_Short idDelta; - FT_UShort idRangeOffset; - - } TT_CMap4SegmentRec, *TT_CMap4Segment; - - - typedef struct TT_CMap4Rec_ - { - FT_ULong language; /* for Mac fonts (originally ushort) */ - - FT_UShort segCountX2; /* number of segments * 2 */ - FT_UShort searchRange; /* these parameters can be used */ - FT_UShort entrySelector; /* for a binary search */ - FT_UShort rangeShift; - - TT_CMap4Segment segments; - FT_UShort* glyphIdArray; - FT_UShort numGlyphId; /* control value */ - - TT_CMap4Segment last_segment; /* last used segment; this is a small */ - /* cache to potentially increase speed */ - } TT_CMap4Rec, *TT_CMap4; - - - /* format 6 */ - - typedef struct TT_CMap6_ - { - FT_ULong language; /* for Mac fonts (originally ushort) */ - - FT_UShort firstCode; /* first character code of subrange */ - FT_UShort entryCount; /* number of character codes in subrange */ - - FT_UShort* glyphIdArray; - - } TT_CMap6Rec, *TT_CMap6; - - - /* auxiliary table for format 8 and 12 */ - - typedef struct TT_CMapGroupRec_ - { - FT_ULong startCharCode; - FT_ULong endCharCode; - FT_ULong startGlyphID; - - } TT_CMapGroupRec, *TT_CMapGroup; - - - /* FreeType handles format 8 and 12 identically. It is not necessary to - cover mixed 16bit and 32bit codes since FreeType always uses FT_ULong - for input character codes -- converting Unicode surrogates to 32bit - character codes must be done by the application. */ - - typedef struct TT_CMap8_12Rec_ - { - FT_ULong language; /* for Mac fonts */ - - FT_ULong nGroups; - TT_CMapGroup groups; - - TT_CMapGroup last_group; /* last used group; this is a small */ - /* cache to potentially increase speed */ - } TT_CMap8_12Rec, *TT_CMap8_12; - - - /* format 10 */ - - typedef struct TT_CMap10Rec_ - { - FT_ULong language; /* for Mac fonts */ - - FT_ULong startCharCode; /* first character covered */ - FT_ULong numChars; /* number of characters covered */ - - FT_UShort* glyphs; - - } TT_CMap10Rec, *TT_CMap10; - - - typedef struct TT_CMapTableRec_* TT_CMapTable; - - - typedef FT_UInt - (*TT_CharMap_Func)( TT_CMapTable charmap, - FT_ULong char_code ); - - typedef FT_ULong - (*TT_CharNext_Func)( TT_CMapTable charmap, - FT_ULong char_code ); - - - /* charmap table */ - typedef struct TT_CMapTableRec_ - { - FT_UShort platformID; - FT_UShort platformEncodingID; - FT_UShort format; - FT_ULong length; /* must be ulong for formats 8, 10, and 12 */ - - FT_Bool loaded; - FT_ULong offset; - - union - { - TT_CMap0Rec cmap0; - TT_CMap2Rec cmap2; - TT_CMap4Rec cmap4; - TT_CMap6Rec cmap6; - TT_CMap8_12Rec cmap8_12; - TT_CMap10Rec cmap10; - } c; - - TT_CharMap_Func get_index; - TT_CharNext_Func get_next_char; - - } TT_CMapTableRec; - - - /*************************************************************************/ - /* */ - /* <Struct> */ - /* TT_CharMapRec */ - /* */ - /* <Description> */ - /* The TrueType character map object type. */ - /* */ - /* <Fields> */ - /* root :: The parent character map structure. */ - /* */ - /* cmap :: The used character map. */ - /* */ - typedef struct TT_CharMapRec_ - { - FT_CharMapRec root; - TT_CMapTableRec cmap; - - } TT_CharMapRec; - - /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ @@ -1121,9 +836,8 @@ FT_BEGIN_HEADER /* This structure/class is defined here because it is common to the */ /* following formats: TTF, OpenType-TT, and OpenType-CFF. */ /* */ - /* Note, however, that the classes TT_Size, TT_GlyphSlot, and TT_CharMap */ - /* are not shared between font drivers, and are thus defined in */ - /* `ttobjs.h'. */ + /* Note, however, that the classes TT_Size and TT_GlyphSlot are not */ + /* shared between font drivers, and are thus defined in `ttobjs.h'. */ /* */ /*************************************************************************/ @@ -1145,17 +859,6 @@ FT_BEGIN_HEADER typedef struct TT_FaceRec_* TT_Face; - /*************************************************************************/ - /* */ - /* <Type> */ - /* TT_CharMap */ - /* */ - /* <Description> */ - /* A handle to a TrueType character mapping object. */ - /* */ - typedef struct TT_CharMapRec_* TT_CharMap; - - /* a function type used for the truetype bytecode interpreter hooks */ typedef FT_Error (*TT_Interpreter)( void* exec_context ); @@ -1341,15 +1044,6 @@ FT_BEGIN_HEADER /* cmap_size :: The size in bytes of the `cmap_table' */ /* described above. */ /* */ - /* num_charmaps :: The number of character mappings in the */ - /* font. */ - /* */ - /* charmaps :: The array of charmap objects for this font */ - /* file. Note that this field is a typeless */ - /* pointer. The Reason is that the format of */ - /* charmaps varies with the underlying font */ - /* format and cannot be determined here. */ - /* */ /* goto_table :: A function called by each TrueType table */ /* loader to position a stream's cursor to */ /* the start of a given table according to */ @@ -1375,10 +1069,9 @@ FT_BEGIN_HEADER /* It must be called after the header was */ /* read, and before the `forget'. */ /* */ - /* sfnt :: A pointer to the SFNT `driver' interface. */ + /* sfnt :: A pointer to the SFNT service. */ /* */ - /* psnames :: A pointer to the `PSNames' module */ - /* interface. */ + /* psnames :: A pointer to the PostScript names service. */ /* */ /* hdmx :: The face's horizontal device metrics */ /* (`hdmx' table). This table is optional in */ @@ -1456,6 +1149,9 @@ FT_BEGIN_HEADER /* interpreters field is also used to hook */ /* the debugger in `ttdebug'. */ /* */ + /* unpatented_hinting :: If true, use only unpatented methods in */ + /* the bytecode interpreter. */ + /* */ /* extra :: Reserved for third-party font drivers. */ /* */ typedef struct TT_FaceRec_ @@ -1494,14 +1190,15 @@ FT_BEGIN_HEADER TT_Loader_ReadGlyphFunc read_simple_glyph; TT_Loader_ReadGlyphFunc read_composite_glyph; - /* a typeless pointer to the SFNT_Interface table used to load */ - /* the basic TrueType tables in the face object */ + /* a typeless pointer to the SFNT_Interface table used to load */ + /* the basic TrueType tables in the face object */ void* sfnt; - /* a typeless pointer to the PSNames_Interface table used to */ - /* handle glyph names <-> unicode & Mac values */ + /* a typeless pointer to the FT_Service_PsCMapsRec table used to */ + /* handle glyph names <-> unicode & Mac values */ void* psnames; + /***********************************************************************/ /* */ /* Optional TrueType/OpenType tables */ @@ -1559,6 +1256,10 @@ FT_BEGIN_HEADER /* used to hook the debugger for the `ttdebug' utility. */ TT_Interpreter interpreter; +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + /* Use unpatented hinting only. */ + FT_Bool unpatented_hinting; +#endif /***********************************************************************/ /* */ @@ -1569,6 +1270,8 @@ FT_BEGIN_HEADER FT_Generic extra; + const char* postscript_name; + } TT_FaceRec; @@ -1639,11 +1342,15 @@ FT_BEGIN_HEADER FT_BBox bbox; FT_Int left_bearing; FT_Int advance; + FT_Int top_bearing; + FT_Int vadvance; FT_Int linear; FT_Bool linear_def; FT_Bool preserve_pps; FT_Vector pp1; FT_Vector pp2; + FT_Vector pp3; + FT_Vector pp4; FT_ULong glyf_offset; @@ -1666,4 +1373,4 @@ FT_END_HEADER #endif /* __TTTYPES_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/t1tables.h b/headers/libs/freetype2/freetype/t1tables.h index dc2189c672..1b89c5f511 100644 --- a/headers/libs/freetype2/freetype/t1tables.h +++ b/headers/libs/freetype2/freetype/t1tables.h @@ -5,7 +5,7 @@ /* Basic Type 1/Type 2 tables definitions and interface (specification */ /* only). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,6 +24,12 @@ #include <ft2build.h> #include FT_FREETYPE_H +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + FT_BEGIN_HEADER @@ -129,6 +135,8 @@ FT_BEGIN_HEADER FT_Short snap_widths [13]; /* including std width */ FT_Short snap_heights[13]; /* including std height */ + FT_Fixed expansion_factor; + FT_Long language_group; FT_Long password; @@ -157,7 +165,7 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* A set of flags used to indicate which fields are present in a */ - /* given blen dictionary (font info or private). Used to support */ + /* given blend dictionary (font info or private). Used to support */ /* Multiple Masters fonts. */ /* */ typedef enum @@ -314,7 +322,7 @@ FT_BEGIN_HEADER /* CID_Info */ /* */ /* <Description> */ - /* This type is equivalent to @CID_FaceInfoRec. It is deprecated but */ + /* This type is equivalent to CID_FaceInfoRec. It is deprecated but */ /* kept to maintain source compatibility between various versions of */ /* FreeType. */ /* */ @@ -373,7 +381,7 @@ FT_BEGIN_HEADER * the face and don't need to be freed by the caller. * * If the font's format is not Postscript-based, this function will - * return the @FT_Err_Invalid_Argument error code. + * return the FT_Err_Invalid_Argument error code. */ FT_EXPORT( FT_Error ) FT_Get_PS_Font_Info( FT_Face face, @@ -388,4 +396,4 @@ FT_END_HEADER #endif /* __T1TABLES_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/ttnameid.h b/headers/libs/freetype2/freetype/ttnameid.h index d39d66f317..848374fe22 100644 --- a/headers/libs/freetype2/freetype/ttnameid.h +++ b/headers/libs/freetype2/freetype/ttnameid.h @@ -4,7 +4,7 @@ /* */ /* TrueType name ID definitions (specification only). */ /* */ -/* Copyright 1996-2002 by */ +/* Copyright 1996-2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -41,7 +41,7 @@ FT_BEGIN_HEADER * * @description: * A list of valid values for the `platform_id' identifier code in - * @FT_CharmapRec and @FT_SfntName structures. + * @FT_CharMapRec and @FT_SfntName structures. * * @values: * TT_PLATFORM_APPLE_UNICODE :: @@ -231,34 +231,33 @@ FT_BEGIN_HEADER * * @values: * TT_MS_ID_SYMBOL_CS :: - * Corresponds to symbol encodings. see @FT_ENCODING_MS_SYMBOL. + * Corresponds to Microsoft symbol encoding. See + * @FT_ENCODING_MS_SYMBOL. * * TT_MS_ID_UNICODE_CS :: * Corresponds to a Microsoft WGL4 charmap, matching Unicode. See * @FT_ENCODING_UNICODE. * * TT_MS_ID_SJIS :: - * Corresponds to Microsoft SJIS Japanese encoding. - * See @FT_ENCODING_MS_SJIS. + * Corresponds to SJIS Japanese encoding. See @FT_ENCODING_SJIS. * * TT_MS_ID_GB2312 :: - * Corresponds to Microsoft Simplified Chinese as used in Mainland - * China. See @FT_ENCODING_MS_GB2312. + * Corresponds to Simplified Chinese as used in Mainland China. See + * @FT_ENCODING_GB2312. * * TT_MS_ID_BIG_5 :: - * Corresponds to Microsoft Traditional Chinese as used in Taiwan and - * Hong Kong. See @FT_ENCODING_MS_BIG5. + * Corresponds to Traditional Chinese as used in Taiwan and Hong Kong. + * See @FT_ENCODING_BIG5. * * TT_MS_ID_WANSUNG :: - * Corresponds to Microsoft Korean Wansung encoding. See - * @FT_ENCODING_MS_WANSUNG. + * Corresponds to Korean Wansung encoding. See @FT_ENCODING_WANSUNG. * * TT_MS_ID_JOHAB :: - * Corresponds to Microsoft Johab encoding. See @FT_ENCODING_MS_JOHAB. + * Corresponds to Johab encoding. See @FT_ENCODING_JOHAB. * * TT_MS_ID_UCS_4 :: - * Corresponds to UCS-4 or UTF-32 charmaps. This has been added into - * OpenType specification as of version 1.4 (mid-2001.) + * Corresponds to UCS-4 or UTF-32 charmaps. This has been added to + * the OpenType specification version 1.4 (mid-2001.) */ #define TT_MS_ID_SYMBOL_CS 0 @@ -292,6 +291,7 @@ FT_BEGIN_HEADER #define TT_ADOBE_ID_STANDARD 0 #define TT_ADOBE_ID_EXPERT 1 #define TT_ADOBE_ID_CUSTOM 2 +#define TT_ADOBE_ID_LATIN_1 3 /*************************************************************************/ @@ -705,8 +705,8 @@ FT_BEGIN_HEADER #define TT_MS_LANGID_SPANISH_UNITED_STATES 0x540a /* The following two IDs blatantly violate MS specs by using a */ /* sublanguage > 0x1F. */ -#define TT_MS_LANGID_SPANISH_LATIN_AMERICA 0xE40a -#define TT_MS_LANGID_FRENCH_NORTH_AFRICA 0xE40c +#define TT_MS_LANGID_SPANISH_LATIN_AMERICA 0xE40aU +#define TT_MS_LANGID_FRENCH_NORTH_AFRICA 0xE40cU #define TT_MS_LANGID_FRENCH_MOROCCO 0x380c #define TT_MS_LANGID_FRENCH_HAITI 0x3c0c @@ -1073,4 +1073,4 @@ FT_END_HEADER #endif /* __TTNAMEID_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/tttables.h b/headers/libs/freetype2/freetype/tttables.h index ee9563d418..22247913ef 100644 --- a/headers/libs/freetype2/freetype/tttables.h +++ b/headers/libs/freetype2/freetype/tttables.h @@ -5,7 +5,7 @@ /* Basic SFNT/TrueType tables definitions and interface */ /* (specification only). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,6 +24,12 @@ #include <ft2build.h> #include FT_FREETYPE_H +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + FT_BEGIN_HEADER @@ -541,8 +547,15 @@ FT_BEGIN_HEADER } TT_MaxProfile; - /* */ - + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Sfnt_Tag */ + /* */ + /* <Description> */ + /* An enumeration used to specify the index of an SFNT table. */ + /* Used in the @FT_Get_Sfnt_Table API function. */ + /* */ typedef enum { ft_sfnt_head = 0, @@ -553,15 +566,11 @@ FT_BEGIN_HEADER ft_sfnt_post = 5, ft_sfnt_pclt = 6, - sfnt_max /* don't remove */ + sfnt_max /* internal end mark */ } FT_Sfnt_Tag; - - /* internal use only */ - typedef void* - (*FT_Get_Sfnt_Table_Func)( FT_Face face, - FT_Sfnt_Tag tag ); + /* */ /*************************************************************************/ @@ -586,13 +595,14 @@ FT_BEGIN_HEADER /* The table is owned by the face object and disappears with it. */ /* */ /* This function is only useful to access SFNT tables that are loaded */ - /* by the sfnt/truetype/opentype drivers. See FT_Sfnt_Tag for a */ + /* by the sfnt/truetype/opentype drivers. See @FT_Sfnt_Tag for a */ /* list. */ /* */ FT_EXPORT( void* ) FT_Get_Sfnt_Table( FT_Face face, FT_Sfnt_Tag tag ); + /************************************************************************** * * <Function> @@ -602,54 +612,77 @@ FT_BEGIN_HEADER * Loads any font table into client memory. * * <Input> - * face :: handle to source face. - * tag :: the 4-byte tag of the table to load. Use the value 0 if - * you want to access the whole font file. Else, you can use - * one of the definitions found in the @FT_TRUETYPE_TAGS_H - * file, or forge a new one with @FT_MAKE_TAG + * face :: A handle to the source face. + * + * tag :: The 4-byte tag of the table to load. Use the value 0 if + * you want to access the whole font file. Otherwise, you can + * use one of the definitions found in the @FT_TRUETYPE_TAGS_H + * file, or forge a new one with @FT_MAKE_TAG. * - * offset :: the starting offset in the table (or file if tag == 0) + * offset :: The starting offset in the table (or file if tag == 0). * * <Output> - * buffer :: target buffer address. client must ensure that there are - * enough bytes in it. + * buffer :: The target buffer address. The client must ensure that + * the memory array is big enough to hold the data. * * <InOut> - * length :: if the 'length' parameter is NULL, then try to load the whole - * table, and return an error code if it fails. + * length :: If the `length' parameter is NULL, then try to load the whole + * table. Return an error code if it fails. * - * else, if '*length' is 0, then exit immediately while returning + * Else, if `*length' is 0, exit immediately while returning * the table's (or file) full size in it. * - * else, the number of bytes to read from the table or file, + * Else the number of bytes to read from the table or file, * from the starting offset. * * <Return> - * error code. 0 means success + * FreeType error code. 0 means success. * * <Note> - * if you need to determine the table's length you should first call this - * function with "*length" set to 0, as in the following example: + * If you need to determine the table's length you should first call this + * function with `*length' set to 0, as in the following example: * * { * FT_ULong length = 0; * + * * error = FT_Load_Sfnt_Table( face, tag, 0, NULL, &length ); * if ( error ) { ... table does not exist ... } * * buffer = malloc( length ); - * if ( buffer == NULL ) { ... not enough memory ... } + * if ( buffer == NULL ) { ... not enough memory ... } * * error = FT_Load_Sfnt_Table( face,tag, 0, buffer, &length ); * if ( error ) { ... could not load table ... } * } */ FT_EXPORT( FT_Error ) - FT_Load_Sfnt_Table( FT_Face face, - FT_ULong tag, - FT_Long offset, - FT_Byte* buffer, - FT_ULong* length ); + FT_Load_Sfnt_Table( FT_Face face, + FT_ULong tag, + FT_Long offset, + FT_Byte* buffer, + FT_ULong* length ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_CMap_Language_ID */ + /* */ + /* <Description> */ + /* Return TrueType/sfnt specific cmap language ID. Definitions of */ + /* language ID values are in freetype/ttnameid.h. */ + /* */ + /* <Input> */ + /* charmap :: */ + /* The target charmap. */ + /* */ + /* <Return> */ + /* The language ID of `charmap'. If `charmap' doesn't belong to a */ + /* TrueType/sfnt face, just return 0 as the default value. */ + /* */ + FT_EXPORT( FT_ULong ) + FT_Get_CMap_Language_ID( FT_CharMap charmap ); /* */ @@ -659,4 +692,4 @@ FT_END_HEADER #endif /* __TTTABLES_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/tttags.h b/headers/libs/freetype2/freetype/tttags.h index 091a14b523..ac64758b10 100644 --- a/headers/libs/freetype2/freetype/tttags.h +++ b/headers/libs/freetype2/freetype/tttags.h @@ -23,6 +23,12 @@ #include <ft2build.h> #include FT_FREETYPE_H +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + FT_BEGIN_HEADER @@ -71,4 +77,4 @@ FT_END_HEADER #endif /* __TTAGS_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/ttunpat.h b/headers/libs/freetype2/freetype/ttunpat.h new file mode 100644 index 0000000000..0bc0a6fe09 --- /dev/null +++ b/headers/libs/freetype2/freetype/ttunpat.h @@ -0,0 +1,59 @@ +/***************************************************************************/ +/* */ +/* ttunpat.h */ +/* */ +/* Definitions for the unpatented TrueType hinting system */ +/* */ +/* Copyright 2003 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* Written by Graham Asher <graham.asher@btinternet.com> */ +/* */ +/* 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. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTUNPAT_H__ +#define __TTUNPAT_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************** + * + * @constant: + * FT_PARAM_TAG_UNPATENTED_HINTING + * + * @description: + * A constant used as the tag of an @FT_Parameter structure to indicate + * that unpatented methods only should be used by the TrueType bytecode + * interpreter for a typeface opened by FT_Open_Face. + * + */ +#define FT_PARAM_TAG_UNPATENTED_HINTING FT_MAKE_TAG( 'u', 'n', 'p', 'a' ) + + /* */ + +FT_END_HEADER + + +#endif /* __TTUNPAT_H__ */ + + +/* END */ diff --git a/headers/libs/freetype2/ft2build.h b/headers/libs/freetype2/ft2build.h index 9ab34d9ee8..2ecfdeab10 100644 --- a/headers/libs/freetype2/ft2build.h +++ b/headers/libs/freetype2/ft2build.h @@ -1,39 +1,39 @@ -/***************************************************************************/ -/* */ -/* ft2build.h */ -/* */ -/* FreeType 2 build and setup macros. */ -/* (Generic version) */ -/* */ -/* Copyright 1996-2001 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This file corresponds to the default "ft2build.h" file for */ - /* FreeType 2. It uses the "freetype" include root. */ - /* */ - /* Note that specific platforms might use a different configuration. */ - /* See builds/unix/ft2unix.h for an example. */ - /* */ - /*************************************************************************/ - - -#ifndef __FT2_BUILD_GENERIC_H__ -#define __FT2_BUILD_GENERIC_H__ - -#include <freetype/config/ftheader.h> - -#endif /* __FT2_BUILD_GENERIC_H__ */ - - -/* END */ +/***************************************************************************/ +/* */ +/* ft2build.h */ +/* */ +/* FreeType 2 build and setup macros. */ +/* (Generic version) */ +/* */ +/* Copyright 1996-2001 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file corresponds to the default "ft2build.h" file for */ + /* FreeType 2. It uses the "freetype" include root. */ + /* */ + /* Note that specific platforms might use a different configuration. */ + /* See builds/unix/ft2unix.h for an example. */ + /* */ + /*************************************************************************/ + + +#ifndef __FT2_BUILD_GENERIC_H__ +#define __FT2_BUILD_GENERIC_H__ + +#include <freetype/config/ftheader.h> + +#endif /* __FT2_BUILD_GENERIC_H__ */ + + +/* END */ diff --git a/src/libs/freetype2/autofit/Jamfile b/src/libs/freetype2/autofit/Jamfile new file mode 100644 index 0000000000..e0bc1ab429 --- /dev/null +++ b/src/libs/freetype2/autofit/Jamfile @@ -0,0 +1,24 @@ +# FreeType 2 src/autofit Jamfile (c) 2001 David Turner +# + +SubDir OBOS_TOP src libs freetype2 autofit ; + +UseFreeTypeHeaders ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = autofit afmodule afloader aflatin afhints afglobal afdummy afangles ; + } + else + { + _sources = autofit ; + } + + FT2_Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/autofit Jamfile + diff --git a/src/libs/freetype2/autofit/afangles.c b/src/libs/freetype2/autofit/afangles.c new file mode 100644 index 0000000000..10a8cff257 --- /dev/null +++ b/src/libs/freetype2/autofit/afangles.c @@ -0,0 +1,214 @@ +#include "aftypes.h" + + /* this table was generated for AF_ANGLE_PI = 256 */ +#define AF_ANGLE_MAX_ITERS 8 +#define AF_TRIG_MAX_ITERS 9 + + static const FT_Fixed + af_angle_arctan_table[9] = + { + 90, 64, 38, 20, 10, 5, 3, 1, 1 + }; + + + static FT_Int + af_angle_prenorm( FT_Vector* vec ) + { + FT_Fixed x, y, z; + FT_Int shift; + + + x = vec->x; + y = vec->y; + + z = ( ( x >= 0 ) ? x : - x ) | ( (y >= 0) ? y : -y ); + shift = 0; + + if ( z < ( 1L << 27 ) ) + { + do + { + shift++; + z <<= 1; + } while ( z < ( 1L << 27 ) ); + + vec->x = x << shift; + vec->y = y << shift; + } + else if ( z > ( 1L << 28 ) ) + { + do + { + shift++; + z >>= 1; + } while ( z > ( 1L << 28 ) ); + + vec->x = x >> shift; + vec->y = y >> shift; + shift = -shift; + } + return shift; + } + + + static void + af_angle_pseudo_polarize( FT_Vector* vec ) + { + FT_Fixed theta; + FT_Fixed yi, i; + FT_Fixed x, y; + const FT_Fixed *arctanptr; + + + x = vec->x; + y = vec->y; + + /* Get the vector into the right half plane */ + theta = 0; + if ( x < 0 ) + { + x = -x; + y = -y; + theta = 2 * AF_ANGLE_PI2; + } + + if ( y > 0 ) + theta = - theta; + + arctanptr = af_angle_arctan_table; + + if ( y < 0 ) + { + /* Rotate positive */ + yi = y + ( x << 1 ); + x = x - ( y << 1 ); + y = yi; + theta -= *arctanptr++; /* Subtract angle */ + } + else + { + /* Rotate negative */ + yi = y - ( x << 1 ); + x = x + ( y << 1 ); + y = yi; + theta += *arctanptr++; /* Add angle */ + } + + i = 0; + do + { + if ( y < 0 ) + { + /* Rotate positive */ + yi = y + ( x >> i ); + x = x - ( y >> i ); + y = yi; + theta -= *arctanptr++; + } + else + { + /* Rotate negative */ + yi = y - ( x >> i ); + x = x + ( y >> i ); + y = yi; + theta += *arctanptr++; + } + } while ( ++i < AF_TRIG_MAX_ITERS ); + + /* round theta */ + if ( theta >= 0 ) + theta = FT_PAD_ROUND( theta, 4 ); + else + theta = - FT_PAD_ROUND( theta, 4 ); + + vec->x = x; + vec->y = theta; + } + + + /* documentation is in fttrigon.h */ + + FT_LOCAL_DEF( AF_Angle ) + af_angle_atan( FT_Fixed dx, + FT_Fixed dy ) + { + FT_Vector v; + + + if ( dx == 0 && dy == 0 ) + return 0; + + v.x = dx; + v.y = dy; + af_angle_prenorm( &v ); + af_angle_pseudo_polarize( &v ); + + return v.y; + } + + + + FT_LOCAL_DEF( AF_Angle ) + af_angle_diff( AF_Angle angle1, + AF_Angle angle2 ) + { + AF_Angle delta = angle2 - angle1; + + delta %= AF_ANGLE_2PI; + if ( delta < 0 ) + delta += AF_ANGLE_2PI; + + if ( delta > AF_ANGLE_PI ) + delta -= AF_ANGLE_2PI; + + return delta; + } + + + /* well, this needs to be somewhere, right :-) + */ + + FT_LOCAL_DEF( void ) + af_sort_pos( FT_UInt count, + FT_Pos* table ) + { + FT_UInt i, j; + FT_Pos swap; + + + for ( i = 1; i < count; i++ ) + { + for ( j = i; j > 0; j-- ) + { + if ( table[j] > table[j - 1] ) + break; + + swap = table[j]; + table[j] = table[j - 1]; + table[j - 1] = swap; + } + } + } + + + FT_LOCAL_DEF( void ) + af_sort_widths( FT_UInt count, + AF_Width table ) + { + FT_UInt i, j; + AF_WidthRec swap; + + + for ( i = 1; i < count; i++ ) + { + for ( j = i; j > 0; j-- ) + { + if ( table[j].org > table[j - 1].org ) + break; + + swap = table[j]; + table[j] = table[j - 1]; + table[j - 1] = swap; + } + } + } diff --git a/src/libs/freetype2/autofit/afdummy.c b/src/libs/freetype2/autofit/afdummy.c new file mode 100644 index 0000000000..bae5f70a32 --- /dev/null +++ b/src/libs/freetype2/autofit/afdummy.c @@ -0,0 +1,35 @@ +#include "afdummy.h" + + + static FT_Error + af_dummy_hints_init( AF_GlyphHints hints, + FT_Outline* outline, + AF_ScriptMetrics metrics ) + { + return af_glyph_hints_reset( hints, + &metrics->scaler, + metrics, + outline ); + } + + static FT_Error + af_dummy_hints_apply( AF_GlyphHints hints, + FT_Outline* outline ) + { + af_glyph_hints_save( hints, outline ); + } + + + FT_LOCAL_DEF( const AF_ScriptClassRec ) af_dummy_script_class = + { + AF_SCRIPT_NONE, + NULL, + + sizeof( AF_ScriptMetricsRec ), + (AF_Script_InitMetricsFunc) NULL, + (AF_Script_ScaleMetricsFunc) NULL, + (AF_Script_DoneMetricsFunc) NULL, + + (AF_Script_InitHintsFunc) af_dummy_hints_init, + (AF_Script_ApplyHintsFunc) af_dummy_hints_apply + }; diff --git a/src/libs/freetype2/autofit/afdummy.h b/src/libs/freetype2/autofit/afdummy.h new file mode 100644 index 0000000000..f4594c0f9f --- /dev/null +++ b/src/libs/freetype2/autofit/afdummy.h @@ -0,0 +1,18 @@ +#ifndef __AFDUMMY_H__ +#define __AFDUMMY_H__ + +#include "aftypes.h" + +FT_BEGIN_HEADER + + /* a dummy script metrics class used when no hinting should + * be performed. This is the default for non-latin glyphs ! + */ + + FT_LOCAL( const AF_ScriptClassRec ) af_dummy_script_class; + +/* */ + +FT_END_HEADER + +#endif /* __AFDUMMY_H__ */ diff --git a/src/libs/freetype2/autofit/afglobal.c b/src/libs/freetype2/autofit/afglobal.c new file mode 100644 index 0000000000..cadc803473 --- /dev/null +++ b/src/libs/freetype2/autofit/afglobal.c @@ -0,0 +1,236 @@ +#include "afglobal.h" +#include "afdummy.h" +#include "aflatin.h" + + /* populate this list when you add new scripts + */ + static AF_ScriptClass const af_script_classes[] = + { + & af_dummy_script_class, + & af_latin_script_class, + + NULL /* do not remove */ + }; + +#define AF_SCRIPT_LIST_DEFAULT 0 /* index of default script in 'af_script_classes' */ +#define AF_SCRIPT_LIST_NONE 255 /* indicates an uncovered glyph */ + + /* + * note that glyph_scripts[] is used to map each glyph into + * an index into the 'af_script_classes' array. + * + */ + typedef struct AF_FaceGlobalsRec_ + { + FT_Face face; + FT_UInt glyph_count; /* same as face->num_glyphs */ + FT_Byte* glyph_scripts; + + AF_ScriptMetrics metrics[ AF_SCRIPT_MAX ]; + + } AF_FaceGlobalsRec; + + + + + /* this function is used to compute the script index of each glyph + * within a given face + */ + static FT_Error + af_face_globals_compute_script_coverage( AF_FaceGlobals globals ) + { + FT_Error error = 0; + FT_Face face = globals->face; + FT_CharMap old_charmap = face->charmap; + FT_Byte* gscripts = globals->glyph_scripts; + FT_UInt ss; + + /* the value 255 means "uncovered glyph" + */ + FT_MEM_SET( globals->glyph_scripts, + AF_SCRIPT_LIST_NONE, + globals->glyph_count ); + + error = FT_Select_Charmap( face, FT_ENCODING_UNICODE ); + if ( error ) + { + /* ignore this error, we'll simply use Latin as the standard + * script. XXX: Shouldn't we rather disable hinting ?? + */ + error = 0; + goto Exit; + } + + /* scan each script in a Unicode charmap + */ + for ( ss = 0; af_script_classes[ss]; ss++ ) + { + AF_ScriptClass clazz = af_script_classes[ss]; + AF_Script_UniRange range; + + if ( clazz->script_uni_ranges == NULL ) + continue; + + /* scan all unicode points in the range, and set the corresponding + * glyph script index + */ + for ( range = clazz->script_uni_ranges; range->first != 0; range++ ) + { + FT_ULong charcode = range->first; + FT_UInt gindex; + + gindex = FT_Get_Char_Index( face, charcode ); + + if ( gindex != 0 && + gindex < globals->glyph_count && + gscripts[ gindex ] == AF_SCRIPT_LIST_NONE ) + { + gscripts[ gindex ] = (FT_Byte) ss; + } + for (;;) + { + charcode = FT_Get_Next_Char( face, charcode, &gindex ); + + if ( gindex == 0 || charcode > range->last ) + break; + + if ( gindex < globals->glyph_count && + gscripts[ gindex ] == AF_SCRIPT_LIST_NONE ) + { + gscripts[ gindex ] = (FT_Byte) ss; + } + } + } + } + + Exit: + /* by default, all uncovered glyphs are set to the latin script + * XXX: shouldnt' we disable hinting or do something similar ? + */ + { + FT_UInt nn; + + for ( nn = 0; nn < globals->glyph_count; nn++ ) + { + if ( gscripts[ nn ] == AF_SCRIPT_LIST_NONE ) + gscripts[ nn ] = AF_SCRIPT_LIST_DEFAULT; + } + } + + FT_Set_Charmap( face, old_charmap ); + return error; + } + + + + FT_LOCAL_DEF( FT_Error ) + af_face_globals_new( FT_Face face, + AF_FaceGlobals *aglobals ) + { + FT_Error error; + FT_Memory memory; + AF_FaceGlobals globals; + + memory = face->memory; + + if ( !FT_ALLOC( globals, sizeof(*globals) + + face->num_glyphs*sizeof(FT_Byte) ) ) + { + globals->face = face; + globals->glyph_count = face->num_glyphs; + globals->glyph_scripts = (FT_Byte*)( globals+1 ); + + error = af_face_globals_compute_script_coverage( globals ); + if ( error ) + { + af_face_globals_free( globals ); + globals = NULL; + } + } + + *aglobals = globals; + return error; + } + + + FT_LOCAL_DEF( void ) + af_face_globals_free( AF_FaceGlobals globals ) + { + if ( globals ) + { + FT_Memory memory = globals->face->memory; + FT_UInt nn; + + for ( nn = 0; nn < AF_SCRIPT_MAX; nn++ ) + { + if ( globals->metrics[nn] ) + { + AF_ScriptClass clazz = af_script_classes[nn]; + + FT_ASSERT( globals->metrics[nn]->clazz == clazz ); + + if ( clazz->script_metrics_done ) + clazz->script_metrics_done( globals->metrics[nn] ); + + FT_FREE( globals->metrics[nn] ); + } + } + + globals->glyph_count = 0; + globals->glyph_scripts = NULL; /* no need to free this one !! */ + globals->face = NULL; + FT_FREE( globals ); + } + } + + + FT_LOCAL_DEF( FT_Error ) + af_face_globals_get_metrics( AF_FaceGlobals globals, + FT_UInt gindex, + AF_ScriptMetrics *ametrics ) + { + AF_ScriptMetrics metrics = NULL; + FT_UInt index; + AF_ScriptClass clazz; + FT_Error error = 0; + + if ( gindex >= globals->glyph_count ) + { + error = FT_Err_Invalid_Argument; + goto Exit; + } + + index = globals->glyph_scripts[ gindex ]; + clazz = af_script_classes[ index ]; + metrics = globals->metrics[ clazz->script ]; + if ( metrics == NULL ) + { + /* create the global metrics object when needed + */ + FT_Memory memory = globals->face->memory; + + if ( FT_ALLOC( metrics, clazz->script_metrics_size ) ) + goto Exit; + + metrics->clazz = clazz; + + if ( clazz->script_metrics_init ) + { + error = clazz->script_metrics_init( metrics, globals->face ); + if ( error ) + { + if ( clazz->script_metrics_done ) + clazz->script_metrics_done( metrics ); + + FT_FREE( metrics ); + goto Exit; + } + } + + globals->metrics[ clazz->script ] = metrics; + } + + Exit: + *ametrics = metrics; + return error; + } diff --git a/src/libs/freetype2/autofit/afglobal.h b/src/libs/freetype2/autofit/afglobal.h new file mode 100644 index 0000000000..64f35c3fff --- /dev/null +++ b/src/libs/freetype2/autofit/afglobal.h @@ -0,0 +1,41 @@ +#ifndef __AF_GLOBAL_H__ +#define __AF_GLOBAL_H__ + +#include "aftypes.h" + +FT_BEGIN_HEADER + + /**************************************************************************/ + /**************************************************************************/ + /***** *****/ + /***** F A C E G L O B A L S *****/ + /***** *****/ + /**************************************************************************/ + /**************************************************************************/ + + + /* + * models the global hints data for a given face, decomposed into + * script-specific items.. + * + */ + typedef struct AF_FaceGlobalsRec_* AF_FaceGlobals; + + + FT_LOCAL( FT_Error ) + af_face_globals_new( FT_Face face, + AF_FaceGlobals *aglobals ); + + FT_LOCAL( FT_Error ) + af_face_globals_get_metrics( AF_FaceGlobals globals, + FT_UInt gindex, + AF_ScriptMetrics *ametrics ); + + FT_LOCAL( void ) + af_face_globals_free( AF_FaceGlobals globals ); + + /* */ + +FT_END_HEADER + +#endif /* __AF_GLOBALS_H__ */ diff --git a/src/libs/freetype2/autofit/afhints.c b/src/libs/freetype2/autofit/afhints.c new file mode 100644 index 0000000000..d0dca1526f --- /dev/null +++ b/src/libs/freetype2/autofit/afhints.c @@ -0,0 +1,986 @@ +#include "afhints.h" + +#ifdef AF_DEBUG + +#include <stdio.h> + + static const char* af_dir_str( AF_Direction dir ) + { + const char* result; + + switch (dir) + { + case AF_DIR_UP: result = "up"; break; + case AF_DIR_DOWN: result = "down"; break; + case AF_DIR_LEFT: result = "left"; break; + case AF_DIR_RIGHT: result = "right"; break; + default: result = "none"; + } + return result; + } + +#define AF_INDEX_NUM(ptr,base) ( (ptr) ? ((ptr)-(base)) : -1 ) + + void + af_glyph_hints_dump_points( AF_GlyphHints hints ) + { + AF_Point points = hints->points; + AF_Point limit = points + hints->num_points; + AF_Point point; + + printf( "Table of points:\n" ); + printf( " [ index | xorg | yorg | xscale | yscale | xfit | yfit | flags ]\n" ); + for ( point = points; point < limit; point++ ) + { + printf( " [ %5d | %5d | %5d | %-5.2f | %-5.2f | %-5.2f | %-5.2f | %c%c%c%c%c%c ]\n", + point - points, + point->fx, + point->fy, + point->ox/64.0, + point->oy/64.0, + point->x/64.0, + point->y/64.0, + (point->flags & AF_FLAG_WEAK_INTERPOLATION) ? 'w' : ' ', + (point->flags & AF_FLAG_INFLECTION) ? 'i' : ' ', + (point->flags & AF_FLAG_EXTREMA_X) ? '<' : ' ', + (point->flags & AF_FLAG_EXTREMA_Y) ? 'v' : ' ', + (point->flags & AF_FLAG_ROUND_X) ? '(' : ' ', + (point->flags & AF_FLAG_ROUND_Y) ? 'u' : ' ' + ); + } + printf( "\n" ); + } + + + /* A function used to dump the array of linked segments */ + void + af_glyph_hints_dump_segments( AF_GlyphHints hints ) + { + AF_Point points = hints->points; + FT_Int dimension; + + for ( dimension = 1; dimension >= 0; dimension-- ) + { + AF_AxisHints axis = &hints->axis[dimension]; + AF_Segment segments = axis->segments; + AF_Segment limit = segments + axis->num_segments; + AF_Segment seg; + + + printf ( "Table of %s segments:\n", + dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" ); + printf ( " [ index | pos | dir | link | serif |" + " numl | first | start ]\n" ); + + for ( seg = segments; seg < limit; seg++ ) + { + printf ( " [ %5d | %4d | %5s | %4d | %5d | %4d | %5d | %5d ]\n", + seg - segments, + (int)seg->pos, + af_dir_str( seg->dir ), + AF_INDEX_NUM( seg->link, segments ), + AF_INDEX_NUM( seg->serif, segments ), + (int)seg->num_linked, + seg->first - points, + seg->last - points ); + } + printf( "\n" ); + } + } + + + void + af_glyph_hints_dump_edges( AF_GlyphHints hints ) + { + FT_Int dimension; + + for ( dimension = 1; dimension >= 0; dimension-- ) + { + AF_AxisHints axis = &hints->axis[ dimension ]; + AF_Edge edges = axis->edges; + AF_Edge limit = edges + axis->num_edges; + AF_Edge edge; + + /* note: AF_DIMENSION_HORZ corresponds to _vertical_ edges + * since they have constant X coordinate + */ + printf ( "Table of %s edges:\n", + dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" ); + printf ( " [ index | pos | dir | link |" + " serif | blue | opos | pos ]\n" ); + + for ( edge = edges; edge < limit; edge++ ) + { + printf ( " [ %5d | %4d | %5s | %4d | %5d | %c | %5.2f | %5.2f ]\n", + edge - edges, + (int)edge->fpos, + af_dir_str( edge->dir ), + AF_INDEX_NUM( edge->link, edges ), + AF_INDEX_NUM( edge->serif, edges ), + edge->blue_edge ? 'y' : 'n', + edge->opos / 64.0, + edge->pos / 64.0 ); + } + + printf( "\n" ); + } + } + + + +#endif /* AF_DEBUG */ + + + /* compute the direction value of a given vector */ + FT_LOCAL_DEF( AF_Direction ) + af_direction_compute( FT_Pos dx, + FT_Pos dy ) + { + AF_Direction dir; + FT_Pos ax = FT_ABS( dx ); + FT_Pos ay = FT_ABS( dy ); + + + dir = AF_DIR_NONE; + + /* atan(1/12) == 4.7 degrees */ + + /* test for vertical direction */ + if ( ax * 12 < ay ) + { + dir = dy > 0 ? AF_DIR_UP : AF_DIR_DOWN; + } + /* test for horizontal direction */ + else if ( ay * 12 < ax ) + { + dir = dx > 0 ? AF_DIR_RIGHT : AF_DIR_LEFT; + } + + return dir; + } + + + /* compute all inflex points in a given glyph */ + static void + af_glyph_hints_compute_inflections( AF_GlyphHints hints ) + { + AF_Point* contour = hints->contours; + AF_Point* contour_limit = contour + hints->num_contours; + + + /* do each contour separately */ + for ( ; contour < contour_limit; contour++ ) + { + AF_Point point = contour[0]; + AF_Point first = point; + AF_Point start = point; + AF_Point end = point; + AF_Point before; + AF_Point after; + AF_Angle angle_in, angle_seg, angle_out; + AF_Angle diff_in, diff_out; + FT_Int finished = 0; + + + /* compute first segment in contour */ + first = point; + + start = end = first; + do + { + end = end->next; + if ( end == first ) + goto Skip; + + } while ( end->fx == first->fx && end->fy == first->fy ); + + angle_seg = af_angle_atan( end->fx - start->fx, + end->fy - start->fy ); + + /* extend the segment start whenever possible */ + before = start; + do + { + do + { + start = before; + before = before->prev; + if ( before == first ) + goto Skip; + + } while ( before->fx == start->fx && before->fy == start->fy ); + + angle_in = af_angle_atan( start->fx - before->fx, + start->fy - before->fy ); + + } while ( angle_in == angle_seg ); + + first = start; + diff_in = af_angle_diff( angle_in, angle_seg ); + + /* now, process all segments in the contour */ + do + { + /* first, extend current segment's end whenever possible */ + after = end; + do + { + do + { + end = after; + after = after->next; + if ( after == first ) + finished = 1; + + } while ( end->fx == after->fx && end->fy == after->fy ); + + angle_out = af_angle_atan( after->fx - end->fx, + after->fy - end->fy ); + + } while ( angle_out == angle_seg ); + + diff_out = af_angle_diff( angle_seg, angle_out ); + + if ( ( diff_in ^ diff_out ) < 0 ) + { + /* diff_in and diff_out have different signs, we have */ + /* inflection points here... */ + do + { + start->flags |= AF_FLAG_INFLECTION; + start = start->next; + + } while ( start != end ); + + start->flags |= AF_FLAG_INFLECTION; + } + + start = end; + end = after; + angle_seg = angle_out; + diff_in = diff_out; + + } while ( !finished ); + + Skip: + ; + } + } + + + + FT_LOCAL_DEF( void ) + af_glyph_hints_init( AF_GlyphHints hints, + FT_Memory memory ) + { + FT_ZERO( hints ); + hints->memory = memory; + } + + + + FT_LOCAL_DEF( void ) + af_glyph_hints_done( AF_GlyphHints hints ) + { + if ( hints && hints->memory ) + { + FT_Memory memory = hints->memory; + AF_Dimension dim; + + /* note that we don't need to free the segment and edge + * buffers, since they're really within the hints->points array + */ + for ( dim = 0; dim < 2; dim++ ) + { + AF_AxisHints axis = &hints->axis[ dim ]; + + axis->num_segments = 0; + axis->num_edges = 0; + axis->segments = NULL; + axis->edges = NULL; + } + + FT_FREE( hints->contours ); + hints->max_contours = 0; + hints->num_contours = 0; + + FT_FREE( hints->points ); + hints->num_points = 0; + hints->max_points = 0; + + hints->memory = NULL; + } + } + + + + FT_LOCAL_DEF( FT_Error ) + af_glyph_hints_reset( AF_GlyphHints hints, + AF_Scaler scaler, + AF_ScriptMetrics metrics, + FT_Outline* outline ) + { + FT_Error error = FT_Err_Ok; + AF_Point points; + FT_UInt old_max, new_max; + FT_Fixed x_scale = scaler->x_scale; + FT_Fixed y_scale = scaler->y_scale; + FT_Pos x_delta = scaler->x_delta; + FT_Pos y_delta = scaler->y_delta; + FT_Memory memory = hints->memory; + + hints->metrics = metrics; + + hints->scaler_flags = scaler->flags; + hints->other_flags = 0; + + hints->num_points = 0; + hints->num_contours = 0; + + hints->axis[0].num_segments = 0; + hints->axis[0].num_edges = 0; + hints->axis[1].num_segments = 0; + hints->axis[1].num_edges = 0; + + /* first of all, reallocate the contours array when necessary + */ + new_max = (FT_UInt) outline->n_contours; + old_max = hints->max_contours; + if ( new_max > old_max ) + { + new_max = (new_max + 3) & ~3; + + if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) ) + goto Exit; + + hints->max_contours = new_max; + } + + /* then, reallocate the points, segments & edges arrays if needed -- + * note that we reserved two additional point positions, used to + * hint metrics appropriately + */ + new_max = (FT_UInt)( outline->n_points + 2 ); + old_max = hints->max_points; + if ( new_max > old_max ) + { + FT_Byte* items; + FT_ULong off1, off2, off3; + + /* we store in a single buffer the following arrays: + * + * - an array of N AF_PointRec items + * - an array of 2*N AF_SegmentRec items + * - an array of 2*N AF_EdgeRec items + * + */ + + new_max = ( new_max + 2 + 7 ) & ~7; + +#define OFF_PAD2(x,y) (((x)+(y)-1) & ~((y)-1)) +#define OFF_PADX(x,y) ((((x)+(y)-1)/(y))*(y)) +#define OFF_PAD(x,y) ( ((y) & ((y)-1)) ? OFF_PADX(x,y) : OFF_PAD2(x,y) ) + +#undef OFF_INCREMENT +#define OFF_INCREMENT( _off, _type, _count ) \ + ( OFF_PAD( _off, sizeof(_type) ) + (_count)*sizeof(_type)) + + off1 = OFF_INCREMENT( 0, AF_PointRec, new_max ); + off2 = OFF_INCREMENT( off1, AF_SegmentRec, new_max*2 ); + off3 = OFF_INCREMENT( off2, AF_EdgeRec, new_max*2 ); + + FT_FREE( hints->points ); + + if ( FT_ALLOC( items, off3 ) ) + { + hints->max_points = 0; + hints->axis[0].segments = NULL; + hints->axis[0].edges = NULL; + hints->axis[1].segments = NULL; + hints->axis[1].edges = NULL; + goto Exit; + } + + /* readjust some pointers + */ + hints->max_points = new_max; + hints->points = (AF_Point) items; + + hints->axis[0].segments = (AF_Segment)( items + off1 ); + hints->axis[1].segments = hints->axis[0].segments + new_max; + + hints->axis[0].edges = (AF_Edge) ( items + off2 ); + hints->axis[1].edges = hints->axis[0].edges + new_max; + } + + hints->num_points = outline->n_points; + hints->num_contours = outline->n_contours; + + + /* We can't rely on the value of `FT_Outline.flags' to know the fill */ + /* direction used for a glyph, given that some fonts are broken (e.g. */ + /* the Arphic ones). We thus recompute it each time we need to. */ + /* */ + hints->axis[ AF_DIMENSION_HORZ ].major_dir = AF_DIR_UP; + hints->axis[ AF_DIMENSION_VERT ].major_dir = AF_DIR_LEFT; + + if ( FT_Outline_Get_Orientation( outline ) == FT_ORIENTATION_POSTSCRIPT ) + { + hints->axis[ AF_DIMENSION_HORZ ].major_dir = AF_DIR_DOWN; + hints->axis[ AF_DIMENSION_VERT ].major_dir = AF_DIR_RIGHT; + } + + hints->x_scale = x_scale; + hints->y_scale = y_scale; + hints->x_delta = x_delta; + hints->y_delta = y_delta; + + points = hints->points; + if ( hints->num_points == 0 ) + goto Exit; + + { + AF_Point point; + AF_Point point_limit = points + hints->num_points; + + + /* compute coordinates & bezier flags */ + { + FT_Vector* vec = outline->points; + char* tag = outline->tags; + + + for ( point = points; point < point_limit; point++, vec++, tag++ ) + { + point->fx = vec->x; + point->fy = vec->y; + point->ox = point->x = FT_MulFix( vec->x, x_scale ) + x_delta; + point->oy = point->y = FT_MulFix( vec->y, y_scale ) + y_delta; + + switch ( FT_CURVE_TAG( *tag ) ) + { + case FT_CURVE_TAG_CONIC: + point->flags = AF_FLAG_CONIC; + break; + case FT_CURVE_TAG_CUBIC: + point->flags = AF_FLAG_CUBIC; + break; + default: + point->flags = 0; + ; + } + } + } + + /* compute `next' and `prev' */ + { + FT_Int contour_index; + AF_Point prev; + AF_Point first; + AF_Point end; + + + contour_index = 0; + + first = points; + end = points + outline->contours[0]; + prev = end; + + for ( point = points; point < point_limit; point++ ) + { + point->prev = prev; + if ( point < end ) + { + point->next = point + 1; + prev = point; + } + else + { + point->next = first; + contour_index++; + if ( point + 1 < point_limit ) + { + end = points + outline->contours[contour_index]; + first = point + 1; + prev = end; + } + } + } + } + + /* set-up the contours array */ + { + AF_Point* contour = hints->contours; + AF_Point* contour_limit = contour + hints->num_contours; + short* end = outline->contours; + short idx = 0; + + + for ( ; contour < contour_limit; contour++, end++ ) + { + contour[0] = points + idx; + idx = (short)( end[0] + 1 ); + } + } + + /* compute directions of in & out vectors */ + { + for ( point = points; point < point_limit; point++ ) + { + AF_Point prev; + AF_Point next; + FT_Pos in_x, in_y, out_x, out_y; + + + prev = point->prev; + in_x = point->fx - prev->fx; + in_y = point->fy - prev->fy; + + point->in_dir = af_direction_compute( in_x, in_y ); + + next = point->next; + out_x = next->fx - point->fx; + out_y = next->fy - point->fy; + + point->out_dir = af_direction_compute( out_x, out_y ); + + if ( point->flags & ( AF_FLAG_CONIC | AF_FLAG_CUBIC ) ) + { + Is_Weak_Point: + point->flags |= AF_FLAG_WEAK_INTERPOLATION; + } + else if ( point->out_dir == point->in_dir ) + { + AF_Angle angle_in, angle_out, delta; + + + if ( point->out_dir != AF_DIR_NONE ) + goto Is_Weak_Point; + + angle_in = af_angle_atan( in_x, in_y ); + angle_out = af_angle_atan( out_x, out_y ); + delta = af_angle_diff( angle_in, angle_out ); + + if ( delta < 2 && delta > -2 ) + goto Is_Weak_Point; + } + else if ( point->in_dir == -point->out_dir ) + goto Is_Weak_Point; + } + } + } + + /* compute inflection points + */ + af_glyph_hints_compute_inflections( hints ); + + Exit: + return error; + } + + + FT_LOCAL_DEF( void ) + af_glyph_hints_save( AF_GlyphHints hints, + FT_Outline* outline ) + { + AF_Point point = hints->points; + AF_Point limit = point + hints->num_points; + FT_Vector* vec = outline->points; + char* tag = outline->tags; + + for ( ; point < limit; point++, vec++, tag++ ) + { + vec->x = (FT_Pos) point->x; + vec->y = (FT_Pos) point->y; + + if ( point->flags & AF_FLAG_CONIC ) + tag[0] = FT_CURVE_TAG_CONIC; + else if ( point->flags & AF_FLAG_CUBIC ) + tag[0] = FT_CURVE_TAG_CUBIC; + else + tag[0] = FT_CURVE_TAG_ON; + } + } + + + /* + * + * E D G E P O I N T G R I D - F I T T I N G + * + */ + + + FT_LOCAL_DEF( void ) + af_glyph_hints_align_edge_points( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = & hints->axis[ dim ]; + AF_Edge edges = axis->edges; + AF_Edge edge_limit = edges + axis->num_edges; + AF_Edge edge; + + for ( edge = edges; edge < edge_limit; edge++ ) + { + /* move the points of each segment */ + /* in each edge to the edge's position */ + AF_Segment seg = edge->first; + + + do + { + AF_Point point = seg->first; + + + for (;;) + { + if ( dim == AF_DIMENSION_HORZ ) + { + point->x = edge->pos; + point->flags |= AF_FLAG_TOUCH_X; + } + else + { + point->y = edge->pos; + point->flags |= AF_FLAG_TOUCH_Y; + } + + if ( point == seg->last ) + break; + + point = point->next; + } + + seg = seg->edge_next; + + } while ( seg != edge->first ); + } + } + + + /* + * + * S T R O N G P O I N T I N T E R P O L A T I O N + * + */ + + + /* hint the strong points -- this is equivalent to the TrueType `IP' */ + /* hinting instruction */ + FT_LOCAL_DEF( void ) + af_glyph_hints_align_strong_points( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_Point points = hints->points; + AF_Point point_limit = points + hints->num_points; + AF_AxisHints axis = &hints->axis[dim]; + AF_Edge edges = axis->edges; + AF_Edge edge_limit = edges + axis->num_edges; + AF_Flags touch_flag; + + + if ( dim == AF_DIMENSION_HORZ ) + touch_flag = AF_FLAG_TOUCH_X; + else + touch_flag = AF_FLAG_TOUCH_Y; + + if ( edges < edge_limit ) + { + AF_Point point; + AF_Edge edge; + + for ( point = points; point < point_limit; point++ ) + { + FT_Pos u, ou, fu; /* point position */ + FT_Pos delta; + + + if ( point->flags & touch_flag ) + continue; + + /* if this point is candidate to weak interpolation, we will */ + /* interpolate it after all strong points have been processed */ + if ( ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) && + !( point->flags & AF_FLAG_INFLECTION ) ) + continue; + + if ( dim == AF_DIMENSION_VERT ) + { + u = point->fy; + ou = point->oy; + } + else + { + u = point->fx; + ou = point->ox; + } + + fu = u; + + /* is the point before the first edge? */ + edge = edges; + delta = edge->fpos - u; + if ( delta >= 0 ) + { + u = edge->pos - ( edge->opos - ou ); + goto Store_Point; + } + + /* is the point after the last edge? */ + edge = edge_limit - 1; + delta = u - edge->fpos; + if ( delta >= 0 ) + { + u = edge->pos + ( ou - edge->opos ); + goto Store_Point; + } + + { + FT_UInt min, max, mid; + FT_Pos fpos; + + + /* find enclosing edges */ + min = 0; + max = edge_limit - edges; + + while ( min < max ) + { + mid = ( max + min ) >> 1; + edge = edges + mid; + fpos = edge->fpos; + + if ( u < fpos ) + max = mid; + else if ( u > fpos ) + min = mid + 1; + else + { + /* we are on the edge */ + u = edge->pos; + goto Store_Point; + } + } + + { + AF_Edge before = edges + min - 1; + AF_Edge after = edges + min + 0; + + + /* assert( before && after && before != after ) */ + if ( before->scale == 0 ) + before->scale = FT_DivFix( after->pos - before->pos, + after->fpos - before->fpos ); + + u = before->pos + FT_MulFix( fu - before->fpos, + before->scale ); + } + } + + + Store_Point: + + /* save the point position */ + if ( dim == AF_DIMENSION_HORZ ) + point->x = u; + else + point->y = u; + + point->flags |= touch_flag; + } + } + } + + + /* + * + * W E A K P O I N T I N T E R P O L A T I O N + * + */ + + static void + af_iup_shift( AF_Point p1, + AF_Point p2, + AF_Point ref ) + { + AF_Point p; + FT_Pos delta = ref->u - ref->v; + + + for ( p = p1; p < ref; p++ ) + p->u = p->v + delta; + + for ( p = ref + 1; p <= p2; p++ ) + p->u = p->v + delta; + } + + + static void + af_iup_interp( AF_Point p1, + AF_Point p2, + AF_Point ref1, + AF_Point ref2 ) + { + AF_Point p; + FT_Pos u; + FT_Pos v1 = ref1->v; + FT_Pos v2 = ref2->v; + FT_Pos d1 = ref1->u - v1; + FT_Pos d2 = ref2->u - v2; + + + if ( p1 > p2 ) + return; + + if ( v1 == v2 ) + { + for ( p = p1; p <= p2; p++ ) + { + u = p->v; + + if ( u <= v1 ) + u += d1; + else + u += d2; + + p->u = u; + } + return; + } + + if ( v1 < v2 ) + { + for ( p = p1; p <= p2; p++ ) + { + u = p->v; + + if ( u <= v1 ) + u += d1; + else if ( u >= v2 ) + u += d2; + else + u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 ); + + p->u = u; + } + } + else + { + for ( p = p1; p <= p2; p++ ) + { + u = p->v; + + if ( u <= v2 ) + u += d2; + else if ( u >= v1 ) + u += d1; + else + u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 ); + + p->u = u; + } + } + } + + + FT_LOCAL_DEF( void ) + af_glyph_hints_align_weak_points( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_Point points = hints->points; + AF_Point point_limit = points + hints->num_points; + AF_Point* contour = hints->contours; + AF_Point* contour_limit = contour + hints->num_contours; + AF_Flags touch_flag; + AF_Point point; + AF_Point end_point; + AF_Point first_point; + + + /* PASS 1: Move segment points to edge positions */ + + if ( dim == AF_DIMENSION_HORZ ) + { + touch_flag = AF_FLAG_TOUCH_X; + + for ( point = points; point < point_limit; point++ ) + { + point->u = point->x; + point->v = point->ox; + } + } + else + { + touch_flag = AF_FLAG_TOUCH_Y; + + for ( point = points; point < point_limit; point++ ) + { + point->u = point->y; + point->v = point->oy; + } + } + + point = points; + + for ( ; contour < contour_limit; contour++ ) + { + point = *contour; + end_point = point->prev; + first_point = point; + + while ( point <= end_point && !( point->flags & touch_flag ) ) + point++; + + if ( point <= end_point ) + { + AF_Point first_touched = point; + AF_Point cur_touched = point; + + + point++; + while ( point <= end_point ) + { + if ( point->flags & touch_flag ) + { + /* we found two successive touched points; we interpolate */ + /* all contour points between them */ + af_iup_interp( cur_touched + 1, point - 1, + cur_touched, point ); + cur_touched = point; + } + point++; + } + + if ( cur_touched == first_touched ) + { + /* this is a special case: only one point was touched in the */ + /* contour; we thus simply shift the whole contour */ + af_iup_shift( first_point, end_point, cur_touched ); + } + else + { + /* now interpolate after the last touched point to the end */ + /* of the contour */ + af_iup_interp( cur_touched + 1, end_point, + cur_touched, first_touched ); + + /* if the first contour point isn't touched, interpolate */ + /* from the contour start to the first touched point */ + if ( first_touched > points ) + af_iup_interp( first_point, first_touched - 1, + cur_touched, first_touched ); + } + } + } + + /* now save the interpolated values back to x/y */ + if ( dim == AF_DIMENSION_HORZ ) + { + for ( point = points; point < point_limit; point++ ) + point->x = point->u; + } + else + { + for ( point = points; point < point_limit; point++ ) + point->y = point->u; + } + } diff --git a/src/libs/freetype2/autofit/afhints.h b/src/libs/freetype2/autofit/afhints.h new file mode 100644 index 0000000000..c69cdc66c6 --- /dev/null +++ b/src/libs/freetype2/autofit/afhints.h @@ -0,0 +1,246 @@ +#ifndef __AFHINTS_H__ +#define __AFHINTS_H__ + +#include "aftypes.h" + +FT_BEGIN_HEADER + + /* + * The definition of outline glyph hints. These are shared by all + * script analysis routines (until now) + * + */ + + typedef enum + { + AF_DIMENSION_HORZ = 0, /* x coordinates, i.e. vertical segments & edges */ + AF_DIMENSION_VERT = 1, /* y coordinates, i.e. horizontal segments & edges */ + + AF_DIMENSION_MAX /* do not remove */ + + } AF_Dimension; + + + /* hint directions -- the values are computed so that two vectors are */ + /* in opposite directions iff `dir1+dir2 == 0' */ + typedef enum + { + AF_DIR_NONE = 4, + AF_DIR_RIGHT = 1, + AF_DIR_LEFT = -1, + AF_DIR_UP = 2, + AF_DIR_DOWN = -2 + + } AF_Direction; + + + /* point hint flags */ + typedef enum + { + AF_FLAG_NONE = 0, + + /* point type flags */ + AF_FLAG_CONIC = (1 << 0), + AF_FLAG_CUBIC = (1 << 1), + AF_FLAG_CONTROL = AF_FLAG_CONIC | AF_FLAG_CUBIC, + + /* point extremum flags */ + AF_FLAG_EXTREMA_X = (1 << 2), + AF_FLAG_EXTREMA_Y = (1 << 3), + + /* point roundness flags */ + AF_FLAG_ROUND_X = (1 << 4), + AF_FLAG_ROUND_Y = (1 << 5), + + /* point touch flags */ + AF_FLAG_TOUCH_X = (1 << 6), + AF_FLAG_TOUCH_Y = (1 << 7), + + /* candidates for weak interpolation have this flag set */ + AF_FLAG_WEAK_INTERPOLATION = (1 << 8), + + /* all inflection points in the outline have this flag set */ + AF_FLAG_INFLECTION = (1 << 9) + + } AF_Flags; + + + /* edge hint flags */ + typedef enum + { + AF_EDGE_NORMAL = 0, + AF_EDGE_ROUND = (1 << 0), + AF_EDGE_SERIF = (1 << 1), + AF_EDGE_DONE = (1 << 2) + + } AF_Edge_Flags; + + + + typedef struct AF_PointRec_* AF_Point; + typedef struct AF_SegmentRec_* AF_Segment; + typedef struct AF_EdgeRec_* AF_Edge; + + + typedef struct AF_PointRec_ + { + AF_Flags flags; /* point flags used by hinter */ + FT_Pos ox, oy; /* original, scaled position */ + FT_Pos fx, fy; /* original, unscaled position (font units) */ + FT_Pos x, y; /* current position */ + FT_Pos u, v; /* current (x,y) or (y,x) depending on context */ + + AF_Direction in_dir; /* direction of inwards vector */ + AF_Direction out_dir; /* direction of outwards vector */ + + AF_Point next; /* next point in contour */ + AF_Point prev; /* previous point in contour */ + + } AF_PointRec; + + + typedef struct AF_SegmentRec_ + { + AF_Edge_Flags flags; /* edge/segment flags for this segment */ + AF_Direction dir; /* segment direction */ + FT_Pos pos; /* position of segment */ + FT_Pos min_coord; /* minimum coordinate of segment */ + FT_Pos max_coord; /* maximum coordinate of segment */ + + AF_Edge edge; /* the segment's parent edge */ + AF_Segment edge_next; /* link to next segment in parent edge */ + + AF_Segment link; /* (stem) link segment */ + AF_Segment serif; /* primary segment for serifs */ + FT_Pos num_linked; /* number of linked segments */ + FT_Pos score; /* used during stem matching */ + + AF_Point first; /* first point in edge segment */ + AF_Point last; /* last point in edge segment */ + AF_Point* contour; /* ptr to first point of segment's contour */ + + } AF_SegmentRec; + + + typedef struct AF_EdgeRec_ + { + FT_Pos fpos; /* original, unscaled position (font units) */ + FT_Pos opos; /* original, scaled position */ + FT_Pos pos; /* current position */ + + AF_Edge_Flags flags; /* edge flags */ + AF_Direction dir; /* edge direction */ + FT_Fixed scale; /* used to speed up interpolation between edges */ + AF_Width blue_edge; /* non-NULL if this is a blue edge */ + + AF_Edge link; + AF_Edge serif; + FT_Int num_linked; + + FT_Int score; + + AF_Segment first; + AF_Segment last; + + } AF_EdgeRec; + + + typedef struct AF_AxisHintsRec_ + { + FT_Int num_segments; + AF_Segment segments; + + FT_Int num_edges; + AF_Edge edges; + + AF_Direction major_dir; + + } AF_AxisHintsRec, *AF_AxisHints; + + + typedef struct AF_GlyphHintsRec_ + { + FT_Memory memory; + + FT_Fixed x_scale; + FT_Pos x_delta; + + FT_Fixed y_scale; + FT_Pos y_delta; + + FT_Pos edge_distance_threshold; + + FT_Int max_points; + FT_Int num_points; + AF_Point points; + + FT_Int max_contours; + FT_Int num_contours; + AF_Point* contours; + + AF_AxisHintsRec axis[ AF_DIMENSION_MAX ]; + + FT_UInt32 scaler_flags; /* copy of scaler flags */ + FT_UInt32 other_flags; /* free for script-specific implementations */ + AF_ScriptMetrics metrics; + + } AF_GlyphHintsRec; + + +#define AF_HINTS_TEST_SCALER(h,f) ( (h)->scaler_flags & (f) ) +#define AF_HINTS_TEST_OTHER(h,f) ( (h)->other_flags & (f) ) + +#define AF_HINTS_DO_HORIZONTAL(h) \ + !AF_HINTS_TEST_SCALER(h,AF_SCALER_FLAG_NO_HORIZONTAL) + +#define AF_HINTS_DO_VERTICAL(h) \ + !AF_HINTS_TEST_SCALER(h,AF_SCALER_FLAG_NO_VERTICAL) + +#define AF_HINTS_DO_ADVANCE(h) \ + !AF_HINTS_TEST_SCALER(h,AF_SCALER_FLAG_NO_ADVANCE) + + + FT_LOCAL( AF_Direction ) + af_direction_compute( FT_Pos dx, + FT_Pos dy ); + + + FT_LOCAL( void ) + af_glyph_hints_init( AF_GlyphHints hints, + FT_Memory memory ); + + + + /* recomputes all AF_Point in a AF_GlyphHints from the definitions + * in a source outline + */ + FT_LOCAL( FT_Error ) + af_glyph_hints_reset( AF_GlyphHints hints, + AF_Scaler scaler, + AF_ScriptMetrics metrics, + FT_Outline* outline ); + + FT_LOCAL( void ) + af_glyph_hints_save( AF_GlyphHints hints, + FT_Outline* outline ); + + FT_LOCAL( void ) + af_glyph_hints_align_edge_points( AF_GlyphHints hints, + AF_Dimension dim ); + + FT_LOCAL( void ) + af_glyph_hints_align_strong_points( AF_GlyphHints hints, + AF_Dimension dim ); + + FT_LOCAL( void ) + af_glyph_hints_align_weak_points( AF_GlyphHints hints, + AF_Dimension dim ); + + FT_LOCAL( void ) + af_glyph_hints_done( AF_GlyphHints hints ); + +/* */ + +FT_END_HEADER + +#endif /* __AFHINTS_H__ */ diff --git a/src/libs/freetype2/autofit/aflatin.c b/src/libs/freetype2/autofit/aflatin.c new file mode 100644 index 0000000000..9a20110fbb --- /dev/null +++ b/src/libs/freetype2/autofit/aflatin.c @@ -0,0 +1,1789 @@ +#include "aflatin.h" + + /***************************************************************************/ + /***************************************************************************/ + /***** *****/ + /***** L A T I N G L O B A L M E T R I C S *****/ + /***** *****/ + /***************************************************************************/ + /***************************************************************************/ + + static void + af_latin_metrics_init_widths( AF_LatinMetrics metrics, + FT_Face face ) + { + /* scan the array of segments in each direction */ + AF_GlyphHintsRec hints[1]; + + af_glyph_hints_init( hints, face->memory ); + + metrics->axis[ AF_DIMENSION_HORZ ].width_count = 0; + metrics->axis[ AF_DIMENSION_VERT ].width_count = 0; + + /* For now, compute the standard width and height from the `o' */ + { + FT_Error error; + FT_UInt glyph_index; + AF_Dimension dim; + AF_ScalerRec scaler[1]; + + + glyph_index = FT_Get_Char_Index( face, 'o' ); + if ( glyph_index == 0 ) + goto Exit; + + error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); + if ( error || face->glyph->outline.n_points <= 0 ) + goto Exit; + + scaler->x_scale = scaler->y_scale = 0x10000L; + scaler->x_delta = scaler->y_delta = 0; + scaler->face = face; + scaler->render_mode = 0; + scaler->flags = 0; + + error = af_glyph_hints_reset( hints, scaler, + (AF_ScriptMetrics) metrics, + &face->glyph->outline ); + if ( error ) + goto Exit; + + for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) + { + AF_LatinAxis axis = & metrics->axis[ dim ]; + AF_AxisHints axhints = & hints->axis[ dim ]; + AF_Segment seg, limit, link; + FT_UInt num_widths = 0; + FT_Pos edge_distance_threshold = 32000; + + af_latin_hints_compute_segments( hints, dim ); + af_latin_hints_link_segments ( hints, dim ); + + seg = axhints->segments; + limit = seg + axhints->num_segments; + + for ( ; seg < limit; seg++ ) + { + link = seg->link; + /* we only consider stem segments there! */ + if ( link && link->link == seg && link > seg ) + { + FT_Pos dist; + + + dist = seg->pos - link->pos; + if ( dist < 0 ) + dist = -dist; + + if ( num_widths < AF_LATIN_MAX_WIDTHS ) + axis->widths[ num_widths++ ].org = dist; + } + } + + af_sort_widths( num_widths, axis->widths ); + axis->width_count = num_widths; + + /* we will now try to find the smallest width */ + if ( num_widths > 0 && axis->widths[0].org < edge_distance_threshold ) + edge_distance_threshold = axis->widths[0].org; + + /* Now, compute the edge distance threshold as a fraction of the */ + /* smallest width in the font. Set it in `hinter->glyph' too! */ + if ( edge_distance_threshold == 32000 ) + edge_distance_threshold = 50; + + /* let's try 20% */ + axis->edge_distance_threshold = edge_distance_threshold / 5; + } + } + + Exit: + af_glyph_hints_done( hints ); + } + + + +#define AF_LATIN_MAX_TEST_CHARACTERS 12 + + + static const char* const af_latin_blue_chars[ AF_LATIN_MAX_BLUES ] = + { + "THEZOCQS", + "HEZLOCUS", + "fijkdbh", + "xzroesc", + "xzroesc", + "pqgjy" + }; + + + static void + af_latin_metrics_init_blues( AF_LatinMetrics metrics, + FT_Face face ) + { + FT_Pos flats [ AF_LATIN_MAX_TEST_CHARACTERS ]; + FT_Pos rounds[ AF_LATIN_MAX_TEST_CHARACTERS ]; + FT_Int num_flats; + FT_Int num_rounds; + FT_Int bb; + AF_LatinBlue blue; + FT_Error error; + AF_LatinAxis axis = &metrics->axis[ AF_DIMENSION_VERT ]; + FT_GlyphSlot glyph = face->glyph; + + /* we compute the blues simply by loading each character from the */ + /* 'af_latin_blue_chars[blues]' string, then compute its top-most or */ + /* bottom-most points (depending on `AF_IS_TOP_BLUE') */ + + AF_LOG(( "blue zones computation\n" )); + AF_LOG(( "------------------------------------------------\n" )); + + for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ ) + { + const char* p = af_latin_blue_chars[bb]; + const char* limit = p + AF_LATIN_MAX_TEST_CHARACTERS; + FT_Pos* blue_ref; + FT_Pos* blue_shoot; + + AF_LOG(( "blue %3d: ", bb )); + + num_flats = 0; + num_rounds = 0; + + for ( ; p < limit && *p; p++ ) + { + FT_UInt glyph_index; + FT_Vector* extremum; + FT_Vector* points; + FT_Vector* point_limit; + FT_Vector* point; + FT_Bool round; + + + AF_LOG(( "'%c'", *p )); + + /* load the character in the face -- skip unknown or empty ones */ + glyph_index = FT_Get_Char_Index( face, (FT_UInt)*p ); + if ( glyph_index == 0 ) + continue; + + error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); + if ( error || glyph->outline.n_points <= 0 ) + continue; + + /* now compute min or max point indices and coordinates */ + points = glyph->outline.points; + point_limit = points + glyph->outline.n_points; + point = points; + extremum = point; + point++; + + if ( AF_LATIN_IS_TOP_BLUE( bb ) ) + { + for ( ; point < point_limit; point++ ) + if ( point->y > extremum->y ) + extremum = point; + } + else + { + for ( ; point < point_limit; point++ ) + if ( point->y < extremum->y ) + extremum = point; + } + + AF_LOG(( "%5d", (int)extremum->y )); + + /* now, check whether the point belongs to a straight or round */ + /* segment; we first need to find in which contour the extremum */ + /* lies, then see its previous and next points */ + { + FT_Int idx = (FT_Int)( extremum - points ); + FT_Int n; + FT_Int first, last, prev, next, end; + FT_Pos dist; + + + last = -1; + first = 0; + + for ( n = 0; n < glyph->outline.n_contours; n++ ) + { + end = glyph->outline.contours[n]; + if ( end >= idx ) + { + last = end; + break; + } + first = end + 1; + } + + /* XXX: should never happen! */ + if ( last < 0 ) + continue; + + /* now look for the previous and next points that are not on the */ + /* same Y coordinate. Threshold the `closeness'... */ + + prev = idx; + next = prev; + + do + { + if ( prev > first ) + prev--; + else + prev = last; + + dist = points[prev].y - extremum->y; + if ( dist < -5 || dist > 5 ) + break; + + } while ( prev != idx ); + + do + { + if ( next < last ) + next++; + else + next = first; + + dist = points[next].y - extremum->y; + if ( dist < -5 || dist > 5 ) + break; + + } while ( next != idx ); + + /* now, set the `round' flag depending on the segment's kind */ + round = FT_BOOL( + FT_CURVE_TAG( glyph->outline.tags[prev] ) != FT_CURVE_TAG_ON || + FT_CURVE_TAG( glyph->outline.tags[next] ) != FT_CURVE_TAG_ON ); + + AF_LOG(( "%c ", round ? 'r' : 'f' )); + } + + if ( round ) + rounds[num_rounds++] = extremum->y; + else + flats[num_flats++] = extremum->y; + } + + AF_LOG(( "\n" )); + + if ( num_flats == 0 && num_rounds == 0 ) + { + /* we couldn't find a single glyph to compute this blue zone, + * we will simply ignore it then + */ + AF_LOG(( "empty !!\n" )); + continue; + } + + /* we have computed the contents of the `rounds' and `flats' tables, */ + /* now determine the reference and overshoot position of the blue -- */ + /* we simply take the median value after a simple sort */ + af_sort_pos( num_rounds, rounds ); + af_sort_pos( num_flats, flats ); + + blue = & axis->blues[ axis->blue_count ]; + blue_ref = & blue->ref.org; + blue_shoot = & blue->shoot.org; + + axis->blue_count ++; + + if ( num_flats == 0 ) + { + *blue_ref = + *blue_shoot = rounds[num_rounds / 2]; + } + else if ( num_rounds == 0 ) + { + *blue_ref = + *blue_shoot = flats[num_flats / 2]; + } + else + { + *blue_ref = flats[num_flats / 2]; + *blue_shoot = rounds[num_rounds / 2]; + } + + /* there are sometimes problems: if the overshoot position of top */ + /* zones is under its reference position, or the opposite for bottom */ + /* zones. We must thus check everything there and correct the errors */ + if ( *blue_shoot != *blue_ref ) + { + FT_Pos ref = *blue_ref; + FT_Pos shoot = *blue_shoot; + FT_Bool over_ref = FT_BOOL( shoot > ref ); + + + if ( AF_LATIN_IS_TOP_BLUE( bb ) ^ over_ref ) + *blue_shoot = *blue_ref = ( shoot + ref ) / 2; + } + + blue->flags = 0; + if ( AF_LATIN_IS_TOP_BLUE(bb) ) + blue->flags |= AF_LATIN_BLUE_TOP; + + AF_LOG(( "-- ref = %ld, shoot = %ld\n", *blue_ref, *blue_shoot )); + } + + return; + } + + + FT_LOCAL_DEF( FT_Error ) + af_latin_metrics_init( AF_LatinMetrics metrics, + FT_Face face ) + { + FT_Error error; + FT_CharMap oldmap = face->charmap; + + /* do we have a Unicode charmap in there? */ + error = FT_Select_Charmap( face, FT_ENCODING_UNICODE ); + if ( error ) goto Exit; + + metrics->units_per_em = face->units_per_EM; + + af_latin_metrics_init_widths( metrics, face ); + af_latin_metrics_init_blues( metrics, face ); + + Exit: + FT_Set_Charmap( face, oldmap ); + return error; + } + + + static void + af_latin_metrics_scale_dim( AF_LatinMetrics metrics, + AF_Scaler scaler, + AF_Dimension dim ) + { + FT_Fixed scale; + FT_Pos delta; + AF_LatinAxis axis; + FT_UInt nn; + + if ( dim == AF_DIMENSION_HORZ ) + { + scale = scaler->x_scale; + delta = scaler->x_delta; + } + else + { + scale = scaler->y_scale; + delta = scaler->y_delta; + } + + axis = & metrics->axis[ dim ]; + + if ( axis->org_scale == scale && axis->org_delta == delta ) + return; + + axis->org_scale = scale; + axis->org_delta = delta; + + /* XXX: TODO: Correct Y and X scale according to Chester rules + */ + axis->scale = scale; + axis->delta = delta; + + if ( dim == AF_DIMENSION_HORZ ) + { + metrics->root.scaler.x_scale = scale; + metrics->root.scaler.x_delta = delta; + } + else + { + metrics->root.scaler.y_scale = scale; + metrics->root.scaler.y_delta = delta; + } + + /* scale the standard widths + */ + for ( nn = 0; nn < axis->width_count; nn++ ) + { + AF_Width width = axis->widths + nn; + + width->cur = FT_MulFix( width->org, scale ); + width->fit = width->cur; + } + + if ( dim == AF_DIMENSION_VERT ) + { + /* scale the blue zones + */ + for ( nn = 0; nn < axis->blue_count; nn++ ) + { + AF_LatinBlue blue = & axis->blues[nn]; + FT_Pos dist; + + blue->ref.cur = FT_MulFix( blue->ref.org, scale ) + delta; + blue->ref.fit = blue->ref.cur; + + blue->shoot.cur = FT_MulFix( blue->shoot.org, scale ) + delta; + blue->shoot.fit = blue->shoot.cur; + + /* a blue zone is only active when it is less than 3/4 pixels tall + */ + dist = FT_MulFix( blue->ref.org - blue->shoot.org, scale ); + if ( dist >= 48 || dist <= -48 ) + blue->flags |= ~AF_LATIN_BLUE_ACTIVE; + } + } + } + + + FT_LOCAL_DEF( void ) + af_latin_metrics_scale( AF_LatinMetrics metrics, + AF_Scaler scaler ) + { + af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_HORZ ); + af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_VERT ); + } + + + /***************************************************************************/ + /***************************************************************************/ + /***** *****/ + /***** L A T I N G L Y P H A N A L Y S I S *****/ + /***** *****/ + /***************************************************************************/ + /***************************************************************************/ + + FT_LOCAL_DEF( void ) + af_latin_hints_compute_segments( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = &hints->axis[dim]; + AF_Segment segments = axis->segments; + AF_Segment segment = segments; + FT_Int num_segments = 0; + AF_Point* contour = hints->contours; + AF_Point* contour_limit = contour + hints->num_contours; + AF_Direction major_dir, segment_dir; + +#ifdef AF_HINT_METRICS + AF_Point min_point = 0; + AF_Point max_point = 0; + FT_Pos min_coord = 32000; + FT_Pos max_coord = -32000; +#endif + + major_dir = FT_ABS( axis->major_dir ); + segment_dir = major_dir; + + /* set up (u,v) in each point */ + if ( dim == AF_DIMENSION_HORZ ) + { + AF_Point point = hints->points; + AF_Point limit = point + hints->num_points; + + for ( ; point < limit; point++ ) + { + point->u = point->fx; + point->v = point->fy; + } + } + else + { + AF_Point point = hints->points; + AF_Point limit = point + hints->num_points; + + for ( ; point < limit; point++ ) + { + point->u = point->fy; + point->v = point->fx; + } + } + + + /* do each contour separately */ + for ( ; contour < contour_limit; contour++ ) + { + AF_Point point = contour[0]; + AF_Point last = point->prev; + int on_edge = 0; + FT_Pos min_pos = 32000; /* minimum segment pos != min_coord */ + FT_Pos max_pos = -32000; /* maximum segment pos != max_coord */ + FT_Bool passed; + + +#ifdef AF_HINT_METRICS + if ( point->u < min_coord ) + { + min_coord = point->u; + min_point = point; + } + if ( point->u > max_coord ) + { + max_coord = point->u; + max_point = point; + } +#endif + + if ( point == last ) /* skip singletons -- just in case */ + continue; + + if ( FT_ABS( last->out_dir ) == major_dir && + FT_ABS( point->out_dir ) == major_dir ) + { + /* we are already on an edge, try to locate its start */ + last = point; + + for (;;) + { + point = point->prev; + if ( FT_ABS( point->out_dir ) != major_dir ) + { + point = point->next; + break; + } + if ( point == last ) + break; + } + } + + last = point; + passed = 0; + + for (;;) + { + FT_Pos u, v; + + + if ( on_edge ) + { + u = point->u; + if ( u < min_pos ) + min_pos = u; + if ( u > max_pos ) + max_pos = u; + + if ( point->out_dir != segment_dir || point == last ) + { + /* we are just leaving an edge; record a new segment! */ + segment->last = point; + segment->pos = ( min_pos + max_pos ) >> 1; + + /* a segment is round if either its first or last point */ + /* is a control point */ + if ( ( segment->first->flags | point->flags ) & + AF_FLAG_CONTROL ) + segment->flags |= AF_EDGE_ROUND; + + /* compute segment size */ + min_pos = max_pos = point->v; + + v = segment->first->v; + if ( v < min_pos ) + min_pos = v; + if ( v > max_pos ) + max_pos = v; + + segment->min_coord = min_pos; + segment->max_coord = max_pos; + + on_edge = 0; + num_segments++; + segment++; + /* fallthrough */ + } + } + + /* now exit if we are at the start/end point */ + if ( point == last ) + { + if ( passed ) + break; + passed = 1; + } + + if ( !on_edge && FT_ABS( point->out_dir ) == major_dir ) + { + /* this is the start of a new segment! */ + segment_dir = point->out_dir; + + /* clear all segment fields */ + FT_ZERO( segment ); + + segment->dir = segment_dir; + segment->flags = AF_EDGE_NORMAL; + min_pos = max_pos = point->u; + segment->first = point; + segment->last = point; + segment->contour = contour; + segment->score = 32000; + segment->link = NULL; + on_edge = 1; + +#ifdef AF_HINT_METRICS + if ( point == max_point ) + max_point = 0; + + if ( point == min_point ) + min_point = 0; +#endif + } + + point = point->next; + } + + } /* contours */ + +#ifdef AF_HINT_METRICS + /* we need to ensure that there are edges on the left-most and */ + /* right-most points of the glyph in order to hint the metrics; */ + /* we do this by inserting fake segments when needed */ + if ( dim == AF_DIMENSION_HORZ ) + { + AF_Point point = hints->points; + AF_Point point_limit = point + hints->num_points; + + FT_Pos min_pos = 32000; + FT_Pos max_pos = -32000; + + + min_point = 0; + max_point = 0; + + /* compute minimum and maximum points */ + for ( ; point < point_limit; point++ ) + { + FT_Pos x = point->fx; + + + if ( x < min_pos ) + { + min_pos = x; + min_point = point; + } + if ( x > max_pos ) + { + max_pos = x; + max_point = point; + } + } + + /* insert minimum segment */ + if ( min_point ) + { + /* clear all segment fields */ + FT_ZERO( segment ); + + segment->dir = segment_dir; + segment->flags = AF_EDGE_NORMAL; + segment->first = min_point; + segment->last = min_point; + segment->pos = min_pos; + segment->score = 32000; + segment->link = NULL; + + num_segments++; + segment++; + } + + /* insert maximum segment */ + if ( max_point ) + { + /* clear all segment fields */ + FT_ZERO( segment ); + + segment->dir = segment_dir; + segment->flags = AF_EDGE_NORMAL; + segment->first = max_point; + segment->last = max_point; + segment->pos = max_pos; + segment->score = 32000; + segment->link = NULL; + + num_segments++; + segment++; + } + } +#endif /* AF_HINT_METRICS */ + + axis->num_segments = num_segments; + } + + + FT_LOCAL_DEF( void ) + af_latin_hints_link_segments( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = &hints->axis[dim]; + AF_Segment segments = axis->segments; + AF_Segment segment_limit = segments + axis->num_segments; + AF_Direction major_dir = axis->major_dir; + AF_Segment seg1, seg2; + + /* now compare each segment to the others */ + for ( seg1 = segments; seg1 < segment_limit; seg1++ ) + { + /* the fake segments are introduced to hint the metrics -- */ + /* we must never link them to anything */ + if ( seg1->first == seg1->last || seg1->dir != major_dir ) + continue; + + for ( seg2 = segments; seg2 < segment_limit; seg2++ ) + if ( seg2 != seg1 && seg1->dir + seg2->dir == 0 ) + { + FT_Pos pos1 = seg1->pos; + FT_Pos pos2 = seg2->pos; + FT_Pos dist = pos2 - pos1; + + + if ( dist < 0 ) + continue; + + { + FT_Pos min = seg1->min_coord; + FT_Pos max = seg1->max_coord; + FT_Pos len, score; + + + if ( min < seg2->min_coord ) + min = seg2->min_coord; + + if ( max > seg2->max_coord ) + max = seg2->max_coord; + + len = max - min; + if ( len >= 8 ) + { + score = dist + 3000 / len; + + if ( score < seg1->score ) + { + seg1->score = score; + seg1->link = seg2; + } + + if ( score < seg2->score ) + { + seg2->score = score; + seg2->link = seg1; + } + } + } + } + } + + /* now, compute the `serif' segments */ + for ( seg1 = segments; seg1 < segment_limit; seg1++ ) + { + seg2 = seg1->link; + + if ( seg2 ) + { + seg2->num_linked++; + if ( seg2->link != seg1 ) + { + seg1->link = 0; + seg1->serif = seg2->link; + } + } + } + } + + + FT_LOCAL_DEF( void ) + af_latin_hints_compute_edges( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = &hints->axis[dim]; + AF_Edge edges = axis->edges; + AF_Edge edge, edge_limit; + + AF_Segment segments = axis->segments; + AF_Segment segment_limit = segments + axis->num_segments; + AF_Segment seg; + + AF_Direction up_dir; + FT_Fixed scale; + FT_Pos edge_distance_threshold; + + + scale = ( dim == AF_DIMENSION_HORZ ) ? hints->x_scale + : hints->y_scale; + + up_dir = ( dim == AF_DIMENSION_HORZ ) ? AF_DIR_UP + : AF_DIR_RIGHT; + + /*********************************************************************/ + /* */ + /* We will begin by generating a sorted table of edges for the */ + /* current direction. To do so, we simply scan each segment and try */ + /* to find an edge in our table that corresponds to its position. */ + /* */ + /* If no edge is found, we create and insert a new edge in the */ + /* sorted table. Otherwise, we simply add the segment to the edge's */ + /* list which will be processed in the second step to compute the */ + /* edge's properties. */ + /* */ + /* Note that the edges table is sorted along the segment/edge */ + /* position. */ + /* */ + /*********************************************************************/ + + edge_distance_threshold = FT_MulFix( hints->edge_distance_threshold, + scale ); + if ( edge_distance_threshold > 64 / 4 ) + edge_distance_threshold = 64 / 4; + + edge_distance_threshold = FT_DivFix( edge_distance_threshold, + scale ); + + edge_limit = edges; + for ( seg = segments; seg < segment_limit; seg++ ) + { + AF_Edge found = 0; + + + /* look for an edge corresponding to the segment */ + for ( edge = edges; edge < edge_limit; edge++ ) + { + FT_Pos dist; + + + dist = seg->pos - edge->fpos; + if ( dist < 0 ) + dist = -dist; + + if ( dist < edge_distance_threshold ) + { + found = edge; + break; + } + } + + if ( !found ) + { + /* insert a new edge in the list and */ + /* sort according to the position */ + while ( edge > edges && edge[-1].fpos > seg->pos ) + { + edge[0] = edge[-1]; + edge--; + } + edge_limit++; + + /* clear all edge fields */ + FT_ZERO( edge ); + + /* add the segment to the new edge's list */ + edge->first = seg; + edge->last = seg; + edge->fpos = seg->pos; + edge->opos = edge->pos = FT_MulFix( seg->pos, scale ); + seg->edge_next = seg; + } + else + { + /* if an edge was found, simply add the segment to the edge's */ + /* list */ + seg->edge_next = edge->first; + edge->last->edge_next = seg; + edge->last = seg; + } + } + axis->num_edges = (FT_Int)( edge_limit - edges ); + + + /*********************************************************************/ + /* */ + /* Good, we will now compute each edge's properties according to */ + /* segments found on its position. Basically, these are: */ + /* */ + /* - edge's main direction */ + /* - stem edge, serif edge or both (which defaults to stem then) */ + /* - rounded edge, straight or both (which defaults to straight) */ + /* - link for edge */ + /* */ + /*********************************************************************/ + + /* first of all, set the `edge' field in each segment -- this is */ + /* required in order to compute edge links */ + + /* Note that I've tried to remove this loop, setting + * the "edge" field of each segment directly in the + * code above. For some reason, it slows down execution + * speed -- on a Sun. + */ + for ( edge = edges; edge < edge_limit; edge++ ) + { + seg = edge->first; + if ( seg ) + do + { + seg->edge = edge; + seg = seg->edge_next; + } + while ( seg != edge->first ); + } + + /* now, compute each edge properties */ + for ( edge = edges; edge < edge_limit; edge++ ) + { + FT_Int is_round = 0; /* does it contain round segments? */ + FT_Int is_straight = 0; /* does it contain straight segments? */ + FT_Pos ups = 0; /* number of upwards segments */ + FT_Pos downs = 0; /* number of downwards segments */ + + + seg = edge->first; + + do + { + FT_Bool is_serif; + + + /* check for roundness of segment */ + if ( seg->flags & AF_EDGE_ROUND ) + is_round++; + else + is_straight++; + + /* check for segment direction */ + if ( seg->dir == up_dir ) + ups += seg->max_coord-seg->min_coord; + else + downs += seg->max_coord-seg->min_coord; + + /* check for links -- if seg->serif is set, then seg->link must */ + /* be ignored */ + is_serif = (FT_Bool)( seg->serif && seg->serif->edge != edge ); + + if ( seg->link || is_serif ) + { + AF_Edge edge2; + AF_Segment seg2; + + + edge2 = edge->link; + seg2 = seg->link; + + if ( is_serif ) + { + seg2 = seg->serif; + edge2 = edge->serif; + } + + if ( edge2 ) + { + FT_Pos edge_delta; + FT_Pos seg_delta; + + + edge_delta = edge->fpos - edge2->fpos; + if ( edge_delta < 0 ) + edge_delta = -edge_delta; + + seg_delta = seg->pos - seg2->pos; + if ( seg_delta < 0 ) + seg_delta = -seg_delta; + + if ( seg_delta < edge_delta ) + edge2 = seg2->edge; + } + else + edge2 = seg2->edge; + + if ( is_serif ) + { + edge->serif = edge2; + edge2->flags |= AF_EDGE_SERIF; + } + else + edge->link = edge2; + } + + seg = seg->edge_next; + + } while ( seg != edge->first ); + + /* set the round/straight flags */ + edge->flags = AF_EDGE_NORMAL; + + if ( is_round > 0 && is_round >= is_straight ) + edge->flags |= AF_EDGE_ROUND; + + /* set the edge's main direction */ + edge->dir = AF_DIR_NONE; + + if ( ups > downs ) + edge->dir = up_dir; + + else if ( ups < downs ) + edge->dir = -up_dir; + + else if ( ups == downs ) + edge->dir = 0; /* both up and down! */ + + /* gets rid of serifs if link is set */ + /* XXX: This gets rid of many unpleasant artefacts! */ + /* Example: the `c' in cour.pfa at size 13 */ + + if ( edge->serif && edge->link ) + edge->serif = 0; + } + } + + + FT_LOCAL_DEF( void ) + af_latin_hints_detect_features( AF_GlyphHints hints, + AF_Dimension dim ) + { + af_latin_hints_compute_segments( hints, dim ); + af_latin_hints_link_segments ( hints, dim ); + af_latin_hints_compute_edges ( hints, dim ); + } + + + FT_LOCAL_DEF( void ) + af_latin_hints_compute_blue_edges( AF_GlyphHints hints, + AF_LatinMetrics metrics ) + { + AF_AxisHints axis = &hints->axis[ AF_DIMENSION_VERT ]; + AF_Edge edge = axis->edges; + AF_Edge edge_limit = edge + axis->num_edges; + AF_LatinAxis latin = &metrics->axis[ AF_DIMENSION_VERT ]; + FT_Fixed scale = latin->scale; + + + /* compute which blue zones are active, i.e. have their scaled */ + /* size < 3/4 pixels */ + + /* for each horizontal edge search the blue zone which is closest */ + for ( ; edge < edge_limit; edge++ ) + { + FT_Int bb; + AF_Width best_blue = NULL; + FT_Pos best_dist; /* initial threshold */ + + + /* compute the initial threshold as a fraction of the EM size */ + best_dist = FT_MulFix( metrics->units_per_em / 40, scale ); + + if ( best_dist > 64 / 2 ) + best_dist = 64 / 2; + + for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ ) + { + AF_LatinBlue blue = latin->blues + bb; + FT_Bool is_top_blue, is_major_dir; + + /* skip inactive blue zones (i.e. those that are too small + */ + if ( !(blue->flags & AF_LATIN_BLUE_ACTIVE) ) + continue; + + /* if it is a top zone, check for right edges -- if it is a bottom */ + /* zone, check for left edges */ + /* */ + /* of course, that's for TrueType */ + is_top_blue = (blue->flags & AF_LATIN_BLUE_TOP) != 0; + is_major_dir = FT_BOOL( edge->dir == axis->major_dir ); + + /* if it is a top zone, the edge must be against the major */ + /* direction; if it is a bottom zone, it must be in the major */ + /* direction */ + if ( is_top_blue ^ is_major_dir ) + { + FT_Pos dist; + + + /* first of all, compare it to the reference position */ + dist = edge->fpos - blue->ref.org; + if ( dist < 0 ) + dist = -dist; + + dist = FT_MulFix( dist, scale ); + if ( dist < best_dist ) + { + best_dist = dist; + best_blue = & blue->ref; + } + + /* now, compare it to the overshoot position if the edge is */ + /* rounded, and if the edge is over the reference position of a */ + /* top zone, or under the reference position of a bottom zone */ + if ( edge->flags & AF_EDGE_ROUND && dist != 0 ) + { + FT_Bool is_under_ref = FT_BOOL( edge->fpos < blue->ref.org ); + + + if ( is_top_blue ^ is_under_ref ) + { + blue = latin->blues + bb; + dist = edge->fpos - blue->shoot.org; + if ( dist < 0 ) + dist = -dist; + + dist = FT_MulFix( dist, scale ); + if ( dist < best_dist ) + { + best_dist = dist; + best_blue = & blue->shoot; + } + } + } + } + } + + if ( best_blue ) + edge->blue_edge = best_blue; + } + } + + + static FT_Error + af_latin_hints_init( AF_GlyphHints hints, + FT_Outline* outline, + AF_LatinMetrics metrics ) + { + FT_Error error; + FT_Render_Mode mode; + + error = af_glyph_hints_reset( hints, &metrics->root.scaler, + (AF_ScriptMetrics) metrics, + outline ); + if (error) + goto Exit; + + + /* compute flags depending on render mode, etc... + */ + + mode = metrics->root.scaler.render_mode; + + /* we snap the width of vertical stems for the monochrome and + * horizontal LCD rendering targets only. + */ + if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD ) + hints->other_flags |= AF_LATIN_HINTS_HORZ_SNAP; + + /* we snap the width of horizontal stems for the monochrome and + * vertical LCD rendering targets only. + */ + if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD_V ) + hints->other_flags |= AF_LATIN_HINTS_VERT_SNAP; + + /* XXX + */ + if ( mode != FT_RENDER_MODE_LIGHT ) + hints->other_flags |= AF_LATIN_HINTS_STEM_ADJUST; + + if ( mode == FT_RENDER_MODE_MONO ) + hints->other_flags |= AF_LATIN_HINTS_MONO; + + /* analyze glyph outline + */ + if ( AF_HINTS_DO_HORIZONTAL(hints) ) + af_latin_hints_detect_features( hints, AF_DIMENSION_HORZ ); + + if ( AF_HINTS_DO_VERTICAL(hints) ) + { + af_latin_hints_detect_features( hints, AF_DIMENSION_VERT ); + af_latin_hints_compute_blue_edges( hints, metrics ); + } + + Exit: + return error; + } + + /***************************************************************************/ + /***************************************************************************/ + /***** *****/ + /***** L A T I N G L Y P H G R I D - F I T T I N G *****/ + /***** *****/ + /***************************************************************************/ + /***************************************************************************/ + + /* snap a given width in scaled coordinates to one of the */ + /* current standard widths */ + static FT_Pos + af_latin_snap_width( AF_Width widths, + FT_Int count, + FT_Pos width ) + { + int n; + FT_Pos best = 64 + 32 + 2; + FT_Pos reference = width; + FT_Pos scaled; + + + for ( n = 0; n < count; n++ ) + { + FT_Pos w; + FT_Pos dist; + + + w = widths[n].cur; + dist = width - w; + if ( dist < 0 ) + dist = -dist; + if ( dist < best ) + { + best = dist; + reference = w; + } + } + + scaled = FT_PIX_ROUND( reference ); + + if ( width >= reference ) + { + if ( width < scaled + 48 ) + width = reference; + } + else + { + if ( width > scaled - 48 ) + width = reference; + } + + return width; + } + + + /* compute the snapped width of a given stem */ + + static FT_Pos + af_latin_compute_stem_width( AF_GlyphHints hints, + AF_Dimension dim, + FT_Pos width, + AF_Edge_Flags base_flags, + AF_Edge_Flags stem_flags ) + { + AF_LatinMetrics metrics = (AF_LatinMetrics) hints->metrics; + AF_LatinAxis axis = & metrics->axis[ dim ]; + FT_Pos dist = width; + FT_Int sign = 0; + FT_Int vertical = AF_HINTS_DO_VERTICAL( hints ); + + + if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) ) + return width; + + if ( dist < 0 ) + { + dist = -width; + sign = 1; + } + + if ( ( vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) || + ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) ) + { + /* smooth hinting process: very lightly quantize the stem width */ + /* */ + + /* leave the widths of serifs alone */ + + if ( ( stem_flags & AF_EDGE_SERIF ) && vertical && ( dist < 3 * 64 ) ) + goto Done_Width; + + else if ( ( base_flags & AF_EDGE_ROUND ) ) + { + if ( dist < 80 ) + dist = 64; + } + else if ( dist < 56 ) + dist = 56; + + if ( axis->width_count > 0 ) + { + FT_Pos delta; + + /* compare to standard width + */ + if ( axis->width_count > 0 ) + { + delta = dist - axis->widths[0].cur; + + if ( delta < 0 ) + delta = -delta; + + if ( delta < 40 ) + { + dist = axis->widths[ 0 ].cur; + if ( dist < 48 ) + dist = 48; + + goto Done_Width; + } + } + + if ( dist < 3 * 64 ) + { + delta = dist & 63; + dist &= -64; + + if ( delta < 10 ) + dist += delta; + + else if ( delta < 32 ) + dist += 10; + + else if ( delta < 54 ) + dist += 54; + + else + dist += delta; + } + else + dist = ( dist + 32 ) & ~63; + } + } + else + { + /* strong hinting process: snap the stem width to integer pixels */ + /* */ + dist = af_latin_snap_width( axis->widths, axis->width_count, dist ); + + if ( vertical ) + { + /* in the case of vertical hinting, always round */ + /* the stem heights to integer pixels */ + if ( dist >= 64 ) + dist = ( dist + 16 ) & ~63; + else + dist = 64; + } + else + { + if ( AF_LATIN_HINTS_DO_MONO( hints ) ) + { + /* monochrome horizontal hinting: snap widths to integer pixels */ + /* with a different threshold */ + if ( dist < 64 ) + dist = 64; + else + dist = ( dist + 32 ) & ~63; + } + else + { + /* for horizontal anti-aliased hinting, we adopt a more subtle */ + /* approach: we strengthen small stems, round stems whose size */ + /* is between 1 and 2 pixels to an integer, otherwise nothing */ + if ( dist < 48 ) + dist = ( dist + 64 ) >> 1; + + else if ( dist < 128 ) + dist = ( dist + 22 ) & ~63; + else + /* round otherwise to prevent color fringes in LCD mode */ + dist = ( dist + 32 ) & ~63; + } + } + } + + Done_Width: + if ( sign ) + dist = -dist; + + return dist; + } + + + + /* align one stem edge relative to the previous stem edge */ + static void + af_latin_align_linked_edge( AF_GlyphHints hints, + AF_Dimension dim, + AF_Edge base_edge, + AF_Edge stem_edge ) + { + FT_Pos dist = stem_edge->opos - base_edge->opos; + + FT_Pos fitted_width = af_latin_compute_stem_width( hints, + dim, + dist, + base_edge->flags, + stem_edge->flags ); + + stem_edge->pos = base_edge->pos + fitted_width; + } + + + static void + af_latin_align_serif_edge( AF_GlyphHints hints, + AF_Edge base, + AF_Edge serif ) + { + FT_UNUSED( hints ); + + serif->pos = base->pos + (serif->opos - base->opos); + } + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** E D G E H I N T I N G ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_LOCAL_DEF( void ) + af_latin_hint_edges( AF_GlyphHints hints, + AF_Dimension dim ) + { + AF_AxisHints axis = & hints->axis[dim]; + AF_Edge edges = axis->edges; + AF_Edge edge_limit = edges + axis->num_edges; + FT_Int n_edges; + AF_Edge edge; + AF_Edge anchor = 0; + FT_Int has_serifs = 0; + + + /* we begin by aligning all stems relative to the blue zone */ + /* if needed -- that's only for horizontal edges */ + if ( dim == AF_DIMENSION_VERT ) + { + for ( edge = edges; edge < edge_limit; edge++ ) + { + AF_Width blue; + AF_Edge edge1, edge2; + + + if ( edge->flags & AF_EDGE_DONE ) + continue; + + blue = edge->blue_edge; + edge1 = NULL; + edge2 = edge->link; + + if ( blue ) + { + edge1 = edge; + } + else if ( edge2 && edge2->blue_edge ) + { + blue = edge2->blue_edge; + edge1 = edge2; + edge2 = edge; + } + + if ( !edge1 ) + continue; + + edge1->pos = blue->fit; + edge1->flags |= AF_EDGE_DONE; + + if ( edge2 && !edge2->blue_edge ) + { + af_latin_align_linked_edge( hints, dim, edge1, edge2 ); + edge2->flags |= AF_EDGE_DONE; + } + + if ( !anchor ) + anchor = edge; + } + } + + /* now we will align all stem edges, trying to maintain the */ + /* relative order of stems in the glyph */ + for ( edge = edges; edge < edge_limit; edge++ ) + { + AF_Edge edge2; + + + if ( edge->flags & AF_EDGE_DONE ) + continue; + + /* skip all non-stem edges */ + edge2 = edge->link; + if ( !edge2 ) + { + has_serifs++; + continue; + } + + /* now align the stem */ + + /* this should not happen, but it's better to be safe */ + if ( edge2->blue_edge || edge2 < edge ) + { + af_latin_align_linked_edge( hints, dim, edge2, edge ); + edge->flags |= AF_EDGE_DONE; + continue; + } + + if ( !anchor ) + { + FT_Pos org_len, org_center, cur_len; + FT_Pos cur_pos1, error1, error2, u_off, d_off; + + + org_len = edge2->opos - edge->opos; + cur_len = af_latin_compute_stem_width( hints, dim, org_len, + edge->flags, edge2->flags ); + if ( cur_len <= 64 ) + u_off = d_off = 32; + else + { + u_off = 38; + d_off = 26; + } + + if ( cur_len < 96 ) + { + org_center = edge->opos + ( org_len >> 1 ); + + cur_pos1 = FT_PIX_ROUND( org_center ); + + error1 = org_center - ( cur_pos1 - u_off ); + if ( error1 < 0 ) + error1 = -error1; + + error2 = org_center - ( cur_pos1 + d_off ); + if ( error2 < 0 ) + error2 = -error2; + + if ( error1 < error2 ) + cur_pos1 -= u_off; + else + cur_pos1 += d_off; + + edge->pos = cur_pos1 - cur_len / 2; + edge2->pos = cur_pos1 + cur_len / 2; + + } + else + edge->pos = FT_PIX_ROUND( edge->opos ); + + anchor = edge; + + edge->flags |= AF_EDGE_DONE; + + af_latin_align_linked_edge( hints, dim, edge, edge2 ); + } + else + { + FT_Pos org_pos, org_len, org_center, cur_len; + FT_Pos cur_pos1, cur_pos2, delta1, delta2; + + + org_pos = anchor->pos + ( edge->opos - anchor->opos ); + org_len = edge2->opos - edge->opos; + org_center = org_pos + ( org_len >> 1 ); + + cur_len = af_latin_compute_stem_width( hints, dim, org_len, + edge->flags, edge2->flags ); + + if ( cur_len < 96 ) + { + FT_Pos u_off, d_off; + + + cur_pos1 = FT_PIX_ROUND( org_center ); + + if (cur_len <= 64 ) + u_off = d_off = 32; + else + { + u_off = 38; + d_off = 26; + } + + delta1 = org_center - ( cur_pos1 - u_off ); + if ( delta1 < 0 ) + delta1 = -delta1; + + delta2 = org_center - ( cur_pos1 + d_off ); + if ( delta2 < 0 ) + delta2 = -delta2; + + if ( delta1 < delta2 ) + cur_pos1 -= u_off; + else + cur_pos1 += d_off; + + edge->pos = cur_pos1 - cur_len / 2; + edge2->pos = cur_pos1 + cur_len / 2; + } + else + { + org_pos = anchor->pos + ( edge->opos - anchor->opos ); + org_len = edge2->opos - edge->opos; + org_center = org_pos + ( org_len >> 1 ); + + cur_len = af_latin_compute_stem_width( hints, dim, org_len, + edge->flags, edge2->flags ); + + cur_pos1 = FT_PIX_ROUND( org_pos ); + delta1 = ( cur_pos1 + ( cur_len >> 1 ) - org_center ); + if ( delta1 < 0 ) + delta1 = -delta1; + + cur_pos2 = FT_PIX_ROUND( org_pos + org_len ) - cur_len; + delta2 = ( cur_pos2 + ( cur_len >> 1 ) - org_center ); + if ( delta2 < 0 ) + delta2 = -delta2; + + edge->pos = ( delta1 < delta2 ) ? cur_pos1 : cur_pos2; + edge2->pos = edge->pos + cur_len; + } + + edge->flags |= AF_EDGE_DONE; + edge2->flags |= AF_EDGE_DONE; + + if ( edge > edges && edge->pos < edge[-1].pos ) + edge->pos = edge[-1].pos; + } + } + + /* make sure that lowercase m's maintain their symmetry */ + + /* In general, lowercase m's have six vertical edges if they are sans */ + /* serif, or twelve if they are avec serif. This implementation is */ + /* based on that assumption, and seems to work very well with most */ + /* faces. However, if for a certain face this assumption is not */ + /* true, the m is just rendered like before. In addition, any stem */ + /* correction will only be applied to symmetrical glyphs (even if the */ + /* glyph is not an m), so the potential for unwanted distortion is */ + /* relatively low. */ + + /* We don't handle horizontal edges since we can't easily assure that */ + /* the third (lowest) stem aligns with the base line; it might end up */ + /* one pixel higher or lower. */ + + n_edges = edge_limit - edges; + if ( dim == AF_DIMENSION_HORZ && ( n_edges == 6 || n_edges == 12 ) ) + { + AF_Edge edge1, edge2, edge3; + FT_Pos dist1, dist2, span, delta; + + + if ( n_edges == 6 ) + { + edge1 = edges; + edge2 = edges + 2; + edge3 = edges + 4; + } + else + { + edge1 = edges + 1; + edge2 = edges + 5; + edge3 = edges + 9; + } + + dist1 = edge2->opos - edge1->opos; + dist2 = edge3->opos - edge2->opos; + + span = dist1 - dist2; + if ( span < 0 ) + span = -span; + + if ( span < 8 ) + { + delta = edge3->pos - ( 2 * edge2->pos - edge1->pos ); + edge3->pos -= delta; + if ( edge3->link ) + edge3->link->pos -= delta; + + /* move the serifs along with the stem */ + if ( n_edges == 12 ) + { + ( edges + 8 )->pos -= delta; + ( edges + 11 )->pos -= delta; + } + + edge3->flags |= AF_EDGE_DONE; + if ( edge3->link ) + edge3->link->flags |= AF_EDGE_DONE; + } + } + + if ( has_serifs || !anchor ) + { + /* now hint the remaining edges (serifs and single) in order + * to complete our processing + */ + for ( edge = edges; edge < edge_limit; edge++ ) + { + if ( edge->flags & AF_EDGE_DONE ) + continue; + + if ( edge->serif ) + af_latin_align_serif_edge( hints, edge->serif, edge ); + else if ( !anchor ) + { + edge->pos = FT_PIX_ROUND( edge->opos ); + anchor = edge; + } + else + edge->pos = anchor->pos + + FT_PIX_ROUND( edge->opos - anchor->opos ); + + edge->flags |= AF_EDGE_DONE; + + if ( edge > edges && edge->pos < edge[-1].pos ) + edge->pos = edge[-1].pos; + + if ( edge + 1 < edge_limit && + edge[1].flags & AF_EDGE_DONE && + edge->pos > edge[1].pos ) + edge->pos = edge[1].pos; + } + } + } + + + static FT_Error + af_latin_hints_apply( AF_GlyphHints hints, + FT_Outline* outline, + AF_LatinMetrics metrics ) + { + AF_Dimension dim; + + FT_UNUSED( metrics ); + + for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) + { + if ( (dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL(hints)) || + (dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL(hints)) ) + { + af_latin_hint_edges( hints, dim ); + af_glyph_hints_align_edge_points( hints, dim ); + af_glyph_hints_align_strong_points( hints, dim ); + af_glyph_hints_align_weak_points( hints, dim ); + } + } + af_glyph_hints_save( hints, outline ); + + return 0; + } + + /***************************************************************************/ + /***************************************************************************/ + /***** *****/ + /***** L A T I N S C R I P T C L A S S *****/ + /***** *****/ + /***************************************************************************/ + /***************************************************************************/ + + static const AF_Script_UniRangeRec af_latin_uniranges[] = + { + { 32, 127 }, /* XXX: TODO: Add new Unicode ranges here !! */ + { 160, 255 }, + { 0, 0 } + }; + + FT_LOCAL_DEF( const AF_ScriptClassRec ) af_latin_script_class = + { + AF_SCRIPT_LATIN, + af_latin_uniranges, + + sizeof( AF_LatinMetricsRec ), + (AF_Script_InitMetricsFunc) af_latin_metrics_init, + (AF_Script_ScaleMetricsFunc) af_latin_metrics_scale, + (AF_Script_DoneMetricsFunc) NULL, + + (AF_Script_InitHintsFunc) af_latin_hints_init, + (AF_Script_ApplyHintsFunc) af_latin_hints_apply + }; + diff --git a/src/libs/freetype2/autofit/aflatin.h b/src/libs/freetype2/autofit/aflatin.h new file mode 100644 index 0000000000..a52e421011 --- /dev/null +++ b/src/libs/freetype2/autofit/aflatin.h @@ -0,0 +1,168 @@ +#ifndef __AFLATIN_H__ +#define __AFLATIN_H__ + +#include "afhints.h" + +FT_BEGIN_HEADER + + /* + * the latin-specific script class + * + */ + FT_LOCAL( const AF_ScriptClassRec ) af_latin_script_class; + + /***************************************************************************/ + /***************************************************************************/ + /***** *****/ + /***** L A T I N G L O B A L M E T R I C S *****/ + /***** *****/ + /***************************************************************************/ + /***************************************************************************/ + + /* + * the following declarations could be embedded in the file "aflatin.c" + * they've been made semi-public to allow alternate script hinters to + * re-use some of them + */ + + /* + * Latin (global) metrics management + * + */ + + enum + { + AF_LATIN_BLUE_CAPITAL_TOP, + AF_LATIN_BLUE_CAPITAL_BOTTOM, + AF_LATIN_BLUE_SMALL_F_TOP, + AF_LATIN_BLUE_SMALL_TOP, + AF_LATIN_BLUE_SMALL_BOTTOM, + AF_LATIN_BLUE_SMALL_MINOR, + + AF_LATIN_BLUE_MAX + }; + +#define AF_LATIN_IS_TOP_BLUE( b ) ( (b) == AF_LATIN_BLUE_CAPITAL_TOP || \ + (b) == AF_LATIN_BLUE_SMALL_F_TOP || \ + (b) == AF_LATIN_BLUE_SMALL_TOP ) + +#define AF_LATIN_MAX_WIDTHS 16 +#define AF_LATIN_MAX_BLUES AF_LATIN_BLUE_MAX + + enum + { + AF_LATIN_BLUE_ACTIVE = (1 << 0), + AF_LATIN_BLUE_TOP = (1 << 1), + + AF_LATIN_BLUE_FLAG_MAX + }; + + + typedef struct AF_LatinBlueRec_ + { + AF_WidthRec ref; + AF_WidthRec shoot; + FT_UInt flags; + + } AF_LatinBlueRec, *AF_LatinBlue; + + + typedef struct AF_LatinAxisRec_ + { + FT_Fixed scale; + FT_Pos delta; + + FT_UInt width_count; + AF_WidthRec widths[ AF_LATIN_MAX_WIDTHS ]; + FT_Pos edge_distance_threshold; + + /* ignored for horizontal metrics */ + FT_Bool control_overshoot; + FT_UInt blue_count; + AF_LatinBlueRec blues[ AF_LATIN_BLUE_MAX ]; + + FT_Fixed org_scale; + FT_Pos org_delta; + + } AF_LatinAxisRec, *AF_LatinAxis; + + + typedef struct AF_LatinMetricsRec_ + { + AF_ScriptMetricsRec root; + FT_UInt units_per_em; + AF_LatinAxisRec axis[ AF_DIMENSION_MAX ]; + + } AF_LatinMetricsRec, *AF_LatinMetrics; + + + + FT_LOCAL( FT_Error ) + af_latin_metrics_init( AF_LatinMetrics metrics, + FT_Face face ); + + FT_LOCAL( void ) + af_latin_metrics_scale( AF_LatinMetrics metrics, + AF_Scaler scaler ); + + + + /***************************************************************************/ + /***************************************************************************/ + /***** *****/ + /***** L A T I N G L Y P H A N A L Y S I S *****/ + /***** *****/ + /***************************************************************************/ + /***************************************************************************/ + + enum + { + AF_LATIN_HINTS_HORZ_SNAP = (1 << 0), /* enable stem width snapping */ + AF_LATIN_HINTS_VERT_SNAP = (1 << 1), /* enable stem height snapping */ + AF_LATIN_HINTS_STEM_ADJUST = (1 << 2), /* enable stem width/height adjustment */ + AF_LATIN_HINTS_MONO = (1 << 3) /* indicate monochrome rendering */ + }; + +#define AF_LATIN_HINTS_DO_HORZ_SNAP(h) \ + AF_HINTS_TEST_OTHER(h,AF_LATIN_HINTS_HORZ_SNAP) + +#define AF_LATIN_HINTS_DO_VERT_SNAP(h) \ + AF_HINTS_TEST_OTHER(h,AF_LATIN_HINTS_VERT_SNAP) + +#define AF_LATIN_HINTS_DO_STEM_ADJUST(h) \ + AF_HINTS_TEST_OTHER(h,AF_LATIN_HINTS_STEM_ADJUST) + +#define AF_LATIN_HINTS_DO_MONO(h) \ + AF_HINTS_TEST_OTHER(h,AF_LATIN_HINTS_MONO) + + + /* this shouldn't normally be exported. However, other scripts might + * like to use this function as-is + */ + FT_LOCAL( void ) + af_latin_hints_compute_segments( AF_GlyphHints hints, + AF_Dimension dim ); + + /* this shouldn't normally be exported. However, other scripts might + * want to use this function as-is + */ + FT_LOCAL( void ) + af_latin_hints_link_segments( AF_GlyphHints hints, + AF_Dimension dim ); + + /* this shouldn't normally be exported. However, other scripts might + * want to use this function as-is + */ + FT_LOCAL( void ) + af_latin_hints_compute_edges( AF_GlyphHints hints, + AF_Dimension dim ); + + FT_LOCAL( void ) + af_latin_hints_detect_features( AF_GlyphHints hints, + AF_Dimension dim ); + +/* */ + +FT_END_HEADER + +#endif /* __AFLATIN_H__ */ diff --git a/src/libs/freetype2/autofit/afloader.c b/src/libs/freetype2/autofit/afloader.c new file mode 100644 index 0000000000..ed422384e7 --- /dev/null +++ b/src/libs/freetype2/autofit/afloader.c @@ -0,0 +1,441 @@ +#include "afloader.h" +#include "afhints.h" +#include "afglobal.h" +#include "aflatin.h" + + FT_LOCAL_DEF( FT_Error ) + af_loader_init( AF_Loader loader, + FT_Memory memory ) + { + FT_Error error; + + FT_ZERO( loader ); + + af_glyph_hints_init( &loader->hints, memory ); + + error = FT_GlyphLoader_New( memory, &loader->gloader ); + if ( !error ) + { + error = FT_GlyphLoader_CreateExtra( loader->gloader ); + if ( error ) + { + FT_GlyphLoader_Done( loader->gloader ); + loader->gloader = NULL; + } + } + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + af_loader_reset( AF_Loader loader, + FT_Face face ) + { + FT_Error error = 0; + + loader->face = face; + loader->globals = (AF_FaceGlobals) face->autohint.data; + + FT_GlyphLoader_Rewind( loader->gloader ); + + if ( loader->globals == NULL ) + { + error = af_face_globals_new( face, &loader->globals ); + if ( !error ) + { + face->autohint.data = (FT_Pointer) loader->globals; + face->autohint.finalizer = (FT_Generic_Finalizer) af_face_globals_free; + } + } + return error; + } + + + FT_LOCAL_DEF( void ) + af_loader_done( AF_Loader loader ) + { + loader->face = NULL; + loader->globals = NULL; + + FT_GlyphLoader_Done( loader->gloader ); + loader->gloader = NULL; + } + + + static FT_Error + af_loader_load_g( AF_Loader loader, + AF_Scaler scaler, + FT_UInt glyph_index, + FT_Int32 load_flags, + FT_UInt depth ) + { + FT_Error error = 0; + FT_Face face = loader->face; + FT_GlyphLoader gloader = loader->gloader; + AF_ScriptMetrics metrics = loader->metrics; + AF_GlyphHints hints = &loader->hints; + FT_GlyphSlot slot = face->glyph; + FT_Slot_Internal internal = slot->internal; + + error = FT_Load_Glyph( face, glyph_index, load_flags ); + if ( error ) + goto Exit; + + loader->transformed = internal->glyph_transformed; + if ( loader->transformed ) + { + FT_Matrix inverse; + + loader->trans_matrix = internal->glyph_matrix; + loader->trans_delta = internal->glyph_delta; + + inverse = loader->trans_matrix; + FT_Matrix_Invert( &inverse ); + FT_Vector_Transform( &loader->trans_delta, &inverse ); + } + + /* set linear metrics */ + slot->linearHoriAdvance = slot->metrics.horiAdvance; + slot->linearVertAdvance = slot->metrics.vertAdvance; + + switch ( slot->format ) + { + case FT_GLYPH_FORMAT_OUTLINE: + /* translate the loaded glyph when an internal transform + * is needed + */ + if ( loader->transformed ) + { + FT_Vector* point = slot->outline.points; + FT_Vector* limit = point + slot->outline.n_points; + + for ( ; point < limit; point++ ) + { + point->x += loader->trans_delta.x; + point->y += loader->trans_delta.y; + } + } + + /* copy the outline points in the loader's current */ + /* extra points which is used to keep original glyph coordinates */ + error = FT_GlyphLoader_CheckPoints( gloader, + slot->outline.n_points + 4, + slot->outline.n_contours ); + if ( error ) + goto Exit; + + FT_ARRAY_COPY( gloader->current.outline.points, + slot->outline.points, + slot->outline.n_points ); + + FT_ARRAY_COPY( gloader->current.extra_points, + slot->outline.points, + slot->outline.n_points ); + + FT_ARRAY_COPY( gloader->current.outline.contours, + slot->outline.contours, + slot->outline.n_contours ); + + FT_ARRAY_COPY( gloader->current.outline.tags, + slot->outline.tags, + slot->outline.n_points ); + + gloader->current.outline.n_points = slot->outline.n_points; + gloader->current.outline.n_contours = slot->outline.n_contours; + + /* compute original horizontal phantom points (and ignore */ + /* vertical ones) */ + loader->pp1.x = hints->x_delta; + loader->pp1.y = hints->y_delta; + loader->pp2.x = FT_MulFix( slot->metrics.horiAdvance, + hints->x_scale ) + hints->x_delta; + loader->pp2.y = hints->y_delta; + + /* be sure to check for spacing glyphs */ + if ( slot->outline.n_points == 0 ) + goto Hint_Metrics; + + /* now load the slot image into the auto-outline and run the */ + /* automatic hinting process */ + error = metrics->clazz->script_hints_init( hints, + &gloader->current.outline, + metrics ); + if ( error ) + goto Exit; + + /* apply the hints */ + metrics->clazz->script_hints_apply( hints, + &gloader->current.outline, + metrics ); + /* we now need to hint the metrics according to the change in */ + /* width/positioning that occured during the hinting process */ + { + FT_Pos old_advance, old_rsb, old_lsb, new_lsb; + AF_AxisHints axis = &hints->axis[ AF_DIMENSION_HORZ ]; + AF_Edge edge1 = axis->edges; /* leftmost edge */ + AF_Edge edge2 = edge1 + axis->num_edges - 1; /* rightmost edge */ + + + old_advance = loader->pp2.x; + old_rsb = old_advance - edge2->opos; + old_lsb = edge1->opos; + new_lsb = edge1->pos; + + loader->pp1.x = FT_PIX_ROUND( new_lsb - old_lsb ); + loader->pp2.x = FT_PIX_ROUND( edge2->pos + old_rsb ); + +#if 0 + /* try to fix certain bad advance computations */ + if ( loader->pp2.x + loader->pp1.x == edge2->pos && old_rsb > 4 ) + loader->pp2.x += 64; +#endif + } + + /* good, we simply add the glyph to our loader's base */ + FT_GlyphLoader_Add( gloader ); + break; + + case FT_GLYPH_FORMAT_COMPOSITE: + { + FT_UInt nn, num_subglyphs = slot->num_subglyphs; + FT_UInt num_base_subgs, start_point; + FT_SubGlyph subglyph; + + + start_point = gloader->base.outline.n_points; + + /* first of all, copy the subglyph descriptors in the glyph loader */ + error = FT_GlyphLoader_CheckSubGlyphs( gloader, num_subglyphs ); + if ( error ) + goto Exit; + + FT_ARRAY_COPY( gloader->current.subglyphs, + slot->subglyphs, + num_subglyphs ); + + gloader->current.num_subglyphs = num_subglyphs; + num_base_subgs = gloader->base.num_subglyphs; + + /* now, read each subglyph independently */ + for ( nn = 0; nn < num_subglyphs; nn++ ) + { + FT_Vector pp1, pp2; + FT_Pos x, y; + FT_UInt num_points, num_new_points, num_base_points; + + + /* gloader.current.subglyphs can change during glyph loading due */ + /* to re-allocation -- we must recompute the current subglyph on */ + /* each iteration */ + subglyph = gloader->base.subglyphs + num_base_subgs + nn; + + pp1 = loader->pp1; + pp2 = loader->pp2; + + num_base_points = gloader->base.outline.n_points; + + error = af_loader_load_g( loader, scaler, subglyph->index, + load_flags, depth + 1 ); + if ( error ) + goto Exit; + + /* recompute subglyph pointer */ + subglyph = gloader->base.subglyphs + num_base_subgs + nn; + + if ( subglyph->flags & FT_SUBGLYPH_FLAG_USE_MY_METRICS ) + { + pp1 = loader->pp1; + pp2 = loader->pp2; + } + else + { + loader->pp1 = pp1; + loader->pp2 = pp2; + } + + num_points = gloader->base.outline.n_points; + num_new_points = num_points - num_base_points; + + /* now perform the transform required for this subglyph */ + + if ( subglyph->flags & ( FT_SUBGLYPH_FLAG_SCALE | + FT_SUBGLYPH_FLAG_XY_SCALE | + FT_SUBGLYPH_FLAG_2X2 ) ) + { + FT_Vector* cur = gloader->base.outline.points + + num_base_points; + FT_Vector* org = gloader->base.extra_points + + num_base_points; + FT_Vector* limit = cur + num_new_points; + + + for ( ; cur < limit; cur++, org++ ) + { + FT_Vector_Transform( cur, &subglyph->transform ); + FT_Vector_Transform( org, &subglyph->transform ); + } + } + + /* apply offset */ + + if ( !( subglyph->flags & FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES ) ) + { + FT_Int k = subglyph->arg1; + FT_UInt l = subglyph->arg2; + FT_Vector* p1; + FT_Vector* p2; + + + if ( start_point + k >= num_base_points || + l >= (FT_UInt)num_new_points ) + { + error = FT_Err_Invalid_Composite; + goto Exit; + } + + l += num_base_points; + + /* for now, only use the current point coordinates; */ + /* we may consider another approach in the near future */ + p1 = gloader->base.outline.points + start_point + k; + p2 = gloader->base.outline.points + start_point + l; + + x = p1->x - p2->x; + y = p1->y - p2->y; + } + else + { + x = FT_MulFix( subglyph->arg1, hints->x_scale ) + hints->x_delta; + y = FT_MulFix( subglyph->arg2, hints->y_scale ) + hints->y_delta; + + x = FT_PIX_ROUND(x); + y = FT_PIX_ROUND(y); + } + + { + FT_Outline dummy = gloader->base.outline; + + + dummy.points += num_base_points; + dummy.n_points = (short)num_new_points; + + FT_Outline_Translate( &dummy, x, y ); + } + } + } + break; + + default: + /* we don't support other formats (yet?) */ + error = FT_Err_Unimplemented_Feature; + } + + Hint_Metrics: + if ( depth == 0 ) + { + FT_BBox bbox; + + + /* transform the hinted outline if needed */ + if ( loader->transformed ) + FT_Outline_Transform( &gloader->base.outline, &loader->trans_matrix ); + + /* we must translate our final outline by -pp1.x and compute */ + /* the new metrics */ + if ( loader->pp1.x ) + FT_Outline_Translate( &gloader->base.outline, -loader->pp1.x, 0 ); + + FT_Outline_Get_CBox( &gloader->base.outline, &bbox ); + + bbox.xMin = FT_PIX_FLOOR( bbox.xMin ); + bbox.yMin = FT_PIX_FLOOR( bbox.yMin ); + bbox.xMax = FT_PIX_CEIL( bbox.xMax ); + bbox.yMax = FT_PIX_CEIL( bbox.yMax ); + + slot->metrics.width = bbox.xMax - bbox.xMin; + slot->metrics.height = bbox.yMax - bbox.yMin; + slot->metrics.horiBearingX = bbox.xMin; + slot->metrics.horiBearingY = bbox.yMax; + + /* for mono-width fonts (like Andale, Courier, etc.) we need */ + /* to keep the original rounded advance width */ +#if 0 + if ( !FT_IS_FIXED_WIDTH( slot->face ) ) + slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; + else + slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, + x_scale ); +#else + slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; +#endif + + slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance ); + + /* now copy outline into glyph slot */ + FT_GlyphLoader_Rewind( internal->loader ); + error = FT_GlyphLoader_CopyPoints( internal->loader, gloader ); + if ( error ) + goto Exit; + + slot->outline = internal->loader->base.outline; + slot->format = FT_GLYPH_FORMAT_OUTLINE; + } + +#ifdef DEBUG_HINTER + af_debug_hinter = hinter; +#endif + + Exit: + return error; + } + + + + + FT_LOCAL_DEF( FT_Error ) + af_loader_load_glyph( AF_Loader loader, + FT_Face face, + FT_UInt gindex, + FT_UInt32 load_flags ) + { + FT_Error error; + FT_Size size = face->size; + AF_ScalerRec scaler; + + if ( !size ) + return FT_Err_Invalid_Argument; + + FT_ZERO( &scaler ); + + scaler.face = face; + scaler.x_scale = size->metrics.x_scale; + scaler.x_delta = 0; /* XXX: TODO: add support for sub-pixel hinting */ + scaler.y_scale = size->metrics.y_scale; + scaler.y_delta = 0; /* XXX: TODO: add support for sub-pixel hinting */ + + scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags ); + scaler.flags = 0; /* XXX: fix this */ + + error = af_loader_reset( loader, face ); + if ( !error ) + { + AF_ScriptMetrics metrics; + + error = af_face_globals_get_metrics( loader->globals, gindex, &metrics ); + if ( !error ) + { + loader->metrics = metrics; + + metrics->scaler = scaler; + + if ( metrics->clazz->script_metrics_scale ) + metrics->clazz->script_metrics_scale( metrics, &scaler ); + + load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM; + load_flags &= ~FT_LOAD_RENDER; + + error = af_loader_load_g( loader, &scaler, gindex, load_flags, 0 ); + } + } + return error; + } diff --git a/src/libs/freetype2/autofit/afloader.h b/src/libs/freetype2/autofit/afloader.h new file mode 100644 index 0000000000..12361560a5 --- /dev/null +++ b/src/libs/freetype2/autofit/afloader.h @@ -0,0 +1,50 @@ +#ifndef __AF_LOADER_H__ +#define __AF_LOADER_H__ + +#include "afhints.h" +#include "afglobal.h" + +FT_BEGIN_HEADER + + typedef struct AF_LoaderRec_ + { + FT_Face face; /* current face */ + AF_FaceGlobals globals; /* current face globals */ + FT_GlyphLoader gloader; /* glyph loader */ + AF_GlyphHintsRec hints; + AF_ScriptMetrics metrics; + FT_Bool transformed; + FT_Matrix trans_matrix; + FT_Vector trans_delta; + FT_Vector pp1; + FT_Vector pp2; + /* we don't handle vertical phantom points */ + + } AF_LoaderRec, *AF_Loader; + + + FT_LOCAL( FT_Error ) + af_loader_init( AF_Loader loader, + FT_Memory memory ); + + + FT_LOCAL( FT_Error ) + af_loader_reset( AF_Loader loader, + FT_Face face ); + + + FT_LOCAL( void ) + af_loader_done( AF_Loader loader ); + + + FT_LOCAL( FT_Error ) + af_loader_load_glyph( AF_Loader loader, + FT_Face face, + FT_UInt gindex, + FT_UInt32 load_flags ); + +/* */ + +FT_END_HEADER + +#endif /* __AF_LOADER_H__ */ diff --git a/src/libs/freetype2/autofit/afmodule.c b/src/libs/freetype2/autofit/afmodule.c new file mode 100644 index 0000000000..f266a7afe8 --- /dev/null +++ b/src/libs/freetype2/autofit/afmodule.c @@ -0,0 +1,70 @@ +#include "afmodule.h" +#include "afloader.h" +#include FT_INTERNAL_OBJECTS_H + + typedef struct FT_AutofitterRec_ + { + FT_ModuleRec root; + AF_LoaderRec loader[1]; + + } FT_AutofitterRec, *FT_Autofitter; + + + FT_CALLBACK_DEF( FT_Error ) + af_autofitter_init( FT_Autofitter module ) + { + return af_loader_init( module->loader, module->root.library->memory ); + } + + + FT_CALLBACK_DEF( void ) + af_autofitter_done( FT_Autofitter module ) + { + af_loader_done( module->loader ); + } + + + FT_CALLBACK_DEF( FT_Error ) + af_autofitter_load_glyph( FT_Autofitter module, + FT_GlyphSlot slot, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + FT_UNUSED(size); + + return af_loader_load_glyph( module->loader, slot->face, + glyph_index, load_flags ); + } + + + + FT_CALLBACK_TABLE_DEF + const FT_AutoHinter_ServiceRec af_autofitter_service = + { + NULL, + NULL, + NULL, + (FT_AutoHinter_GlyphLoadFunc) af_autofitter_load_glyph + }; + + + FT_CALLBACK_TABLE_DEF + const FT_Module_Class autofit_module_class = + { + FT_MODULE_HINTER, + sizeof ( FT_AutofitterRec ), + + "autofitter", + 0x10000L, /* version 1.0 of the autofitter */ + 0x20000L, /* requires FreeType 2.0 or above */ + + (const void*) &af_autofitter_service, + + (FT_Module_Constructor) af_autofitter_init, + (FT_Module_Destructor) af_autofitter_done, + (FT_Module_Requester) 0 + }; + + +/* END */ diff --git a/src/libs/freetype2/autofit/afmodule.h b/src/libs/freetype2/autofit/afmodule.h new file mode 100644 index 0000000000..b898cb375f --- /dev/null +++ b/src/libs/freetype2/autofit/afmodule.h @@ -0,0 +1,16 @@ +#ifndef __AFMODULE_H__ +#define __AFMODULE_H__ + +#include <ft2build.h> +#include FT_MODULE_H + + +FT_BEGIN_HEADER + + FT_CALLBACK_TABLE + const FT_Module_Class autofit_module_class; + + +FT_END_HEADER + +#endif /* __AFMODULE_H__ */ diff --git a/src/libs/freetype2/autofit/aftypes.h b/src/libs/freetype2/autofit/aftypes.h new file mode 100644 index 0000000000..abd2ff5fa8 --- /dev/null +++ b/src/libs/freetype2/autofit/aftypes.h @@ -0,0 +1,268 @@ +#ifndef __AFTYPES_H__ +#define __AFTYPES_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_OUTLINE_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H + +FT_BEGIN_HEADER + + /**************************************************************************/ + /**************************************************************************/ + /***** *****/ + /***** D E B U G G I N G *****/ + /***** *****/ + /**************************************************************************/ + /**************************************************************************/ + +#define xxAF_DEBUG + +#ifdef AF_DEBUG + +# include <stdio.h> +# define AF_LOG( x ) printf x + +#else + +# define AF_LOG( x ) do ; while ( 0 ) /* nothing */ + +#endif /* AF_DEBUG */ + + /**************************************************************************/ + /**************************************************************************/ + /***** *****/ + /***** U T I L I T Y *****/ + /***** *****/ + /**************************************************************************/ + /**************************************************************************/ + + typedef struct AF_WidthRec_ + { + FT_Pos org; /* original position/width in font units */ + FT_Pos cur; /* current/scaled position/width in device sub-pixels */ + FT_Pos fit; /* current/fitted position/width in device sub-pixels */ + + } AF_WidthRec, *AF_Width; + + + FT_LOCAL( void ) + af_sort_pos( FT_UInt count, + FT_Pos* table ); + + FT_LOCAL( void ) + af_sort_widths( FT_UInt count, + AF_Width widths ); + + + /**************************************************************************/ + /**************************************************************************/ + /***** *****/ + /***** A N G L E T Y P E S *****/ + /***** *****/ + /**************************************************************************/ + /**************************************************************************/ + + /* + * Angle type. The auto-fitter doesn't need a very high angular accuracy, + * and this allows us to speed up some computations considerably with a + * light Cordic algorithm (see afangles.c) + * + */ + + typedef FT_Int AF_Angle; + +#define AF_ANGLE_PI 128 +#define AF_ANGLE_2PI (AF_ANGLE_PI*2) +#define AF_ANGLE_PI2 (AF_ANGLE_PI/2) +#define AF_ANGLE_PI4 (AF_ANGLE_PI/4) + + /* + * compute the angle of a given 2-D vector + * + */ + FT_LOCAL( AF_Angle ) + af_angle_atan( FT_Pos dx, + FT_Pos dy ); + + + /* + * computes "angle2 - angle1", the result is always within + * the range [ -AF_ANGLE_PI .. AF_ANGLE_PI-1 ] + * + */ + FT_LOCAL( AF_Angle ) + af_angle_diff( AF_Angle angle1, + AF_Angle angle2 ); + + + /**************************************************************************/ + /**************************************************************************/ + /***** *****/ + /***** O U T L I N E S *****/ + /***** *****/ + /**************************************************************************/ + /**************************************************************************/ + + /* opaque handle to glyph-specific hints. see "afhints.h" for more + * details + */ + typedef struct AF_GlyphHintsRec_* AF_GlyphHints; + + /* this structure is used to model an input glyph outline to + * the auto-hinter. The latter will set the "hints" field + * depending on the glyph's script + */ + typedef struct AF_OutlineRec_ + { + FT_Face face; + FT_Outline outline; + FT_UInt outline_resolution; + + FT_Int advance; + FT_UInt metrics_resolution; + + AF_GlyphHints hints; + + } AF_OutlineRec; + + + /**************************************************************************/ + /**************************************************************************/ + /***** *****/ + /***** S C A L E R S *****/ + /***** *****/ + /**************************************************************************/ + /**************************************************************************/ + + /* + * A scaler models the target pixel device that will receive the + * auto-hinted glyph image + * + */ + + typedef enum + { + AF_SCALER_FLAG_NO_HORIZONTAL = 1, /* disable horizontal hinting */ + AF_SCALER_FLAG_NO_VERTICAL = 2, /* disable vertical hinting */ + AF_SCALER_FLAG_NO_ADVANCE = 4 /* disable advance hinting */ + + } AF_ScalerFlags; + + + typedef struct AF_ScalerRec_ + { + FT_Face face; /* source font face */ + FT_Fixed x_scale; /* from font units to 1/64th device pixels */ + FT_Fixed y_scale; /* from font units to 1/64th device pixels */ + FT_Pos x_delta; /* in 1/64th device pixels */ + FT_Pos y_delta; /* in 1/64th device pixels */ + FT_Render_Mode render_mode; /* monochrome, anti-aliased, LCD, etc.. */ + FT_UInt32 flags; /* additionnal control flags, see above */ + + } AF_ScalerRec, *AF_Scaler; + + + + /**************************************************************************/ + /**************************************************************************/ + /***** *****/ + /***** S C R I P T S *****/ + /***** *****/ + /**************************************************************************/ + /**************************************************************************/ + + /* + * the list of know scripts. Each different script correspond to the + * following information: + * + * - a set of Unicode ranges to test weither the face supports the + * script + * + * - a specific global analyzer that will compute global metrics + * specific to the script. + * + * - a specific glyph analyzer that will compute segments and + * edges for each glyph covered by the script + * + * - a specific grid-fitting algorithm that will distort the + * scaled glyph outline according to the results of the glyph + * analyzer + * + * note that a given analyzer and/or grid-fitting algorithm can be + * used by more than one script + */ + typedef enum + { + AF_SCRIPT_NONE = 0, + AF_SCRIPT_LATIN = 1, + /* add new scripts here. don't forget to update the list in "afglobal.c" */ + + AF_SCRIPT_MAX /* do not remove */ + + } AF_Script; + + + + typedef struct AF_ScriptClassRec_ const* AF_ScriptClass; + + typedef struct AF_ScriptMetricsRec_ + { + AF_ScriptClass clazz; + AF_ScalerRec scaler; + + } AF_ScriptMetricsRec, *AF_ScriptMetrics; + + + /* this function parses a FT_Face to compute global metrics for + * a specific script + */ + typedef FT_Error (*AF_Script_InitMetricsFunc)( AF_ScriptMetrics metrics, + FT_Face face ); + + typedef void (*AF_Script_ScaleMetricsFunc)( AF_ScriptMetrics metrics, + AF_Scaler scaler ); + + typedef void (*AF_Script_DoneMetricsFunc)( AF_ScriptMetrics metrics ); + + + typedef FT_Error (*AF_Script_InitHintsFunc)( AF_GlyphHints hints, + FT_Outline* outline, + AF_ScriptMetrics metrics ); + + typedef void (*AF_Script_ApplyHintsFunc)( AF_GlyphHints hints, + FT_Outline* outline, + AF_ScriptMetrics metrics ); + + + typedef struct AF_Script_UniRangeRec_ + { + FT_UInt32 first; + FT_UInt32 last; + + } AF_Script_UniRangeRec; + + typedef const AF_Script_UniRangeRec * AF_Script_UniRange; + + typedef struct AF_ScriptClassRec_ + { + AF_Script script; + AF_Script_UniRange script_uni_ranges; /* last must be { 0, 0 } */ + + FT_UInt script_metrics_size; + AF_Script_InitMetricsFunc script_metrics_init; + AF_Script_ScaleMetricsFunc script_metrics_scale; + AF_Script_DoneMetricsFunc script_metrics_done; + + AF_Script_InitHintsFunc script_hints_init; + AF_Script_ApplyHintsFunc script_hints_apply; + + } AF_ScriptClassRec; + + +/* */ + +FT_END_HEADER + +#endif /* __AFTYPES_H__ */ diff --git a/src/libs/freetype2/autofit/autofit.c b/src/libs/freetype2/autofit/autofit.c new file mode 100644 index 0000000000..c258e0d7aa --- /dev/null +++ b/src/libs/freetype2/autofit/autofit.c @@ -0,0 +1,9 @@ +#define FT_MAKE_OPTION_SINGLE_OBJECT +#include <ft2build.h> +#include "afangles.c" +#include "afglobal.c" +#include "afhints.c" +#include "afdummy.c" +#include "aflatin.c" +#include "afloader.c" +#include "afmodule.c" diff --git a/src/libs/freetype2/autohint/CatharonLicense.txt b/src/libs/freetype2/autohint/CatharonLicense.txt index d0d38ccf42..789c8c9fec 100644 --- a/src/libs/freetype2/autohint/CatharonLicense.txt +++ b/src/libs/freetype2/autohint/CatharonLicense.txt @@ -120,4 +120,4 @@ Legal Terms Packages, you indicate that you understand and accept all the terms of this license. ---- end of license.txt --- +--- end of license.txt --- diff --git a/src/libs/freetype2/autohint/ahangles.c b/src/libs/freetype2/autohint/ahangles.c index 647334108a..ef5a88ee66 100644 --- a/src/libs/freetype2/autohint/ahangles.c +++ b/src/libs/freetype2/autohint/ahangles.c @@ -144,4 +144,4 @@ return delta; } -/* END */ +/* END */ diff --git a/src/libs/freetype2/autohint/ahangles.h b/src/libs/freetype2/autohint/ahangles.h index 0105e393f2..f46bfaad78 100644 --- a/src/libs/freetype2/autohint/ahangles.h +++ b/src/libs/freetype2/autohint/ahangles.h @@ -61,4 +61,4 @@ FT_END_HEADER #endif /* __AHANGLES_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/autohint/aherrors.h b/src/libs/freetype2/autohint/aherrors.h index c3951dc2fc..bce6107d39 100644 --- a/src/libs/freetype2/autohint/aherrors.h +++ b/src/libs/freetype2/autohint/aherrors.h @@ -37,4 +37,4 @@ #endif /* __AHERRORS_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/autohint/ahglobal.c b/src/libs/freetype2/autohint/ahglobal.c index 0184d37d24..e157014b57 100644 --- a/src/libs/freetype2/autohint/ahglobal.c +++ b/src/libs/freetype2/autohint/ahglobal.c @@ -4,7 +4,7 @@ /* */ /* Routines used to compute global metrics automatically (body). */ /* */ -/* Copyright 2000-2001, 2002 Catharon Productions Inc. */ +/* Copyright 2000-2001, 2002, 2003, 2004 Catharon Productions Inc. */ /* Author: David Turner */ /* */ /* This file is part of the Catharon Typography Project and shall only */ @@ -27,8 +27,10 @@ #define MAX_TEST_CHARACTERS 12 + /* cf. AH_BLUE_XXX constants in ahtypes.h */ + static - const char* blue_chars[AH_BLUE_MAX] = + const char* const blue_chars[AH_BLUE_MAX] = { "THEZOCQS", "HEZLOCUS", @@ -93,8 +95,8 @@ goto Exit; /* we compute the blues simply by loading each character from the */ - /* 'blue_chars[blues]' string, then compute its top-most and */ - /* bottom-most points */ + /* `blue_chars[blues]' string, then compute its top-most or */ + /* bottom-most points (depending on `AH_IS_TOP_BLUE') */ AH_LOG(( "blue zones computation\n" )); AH_LOG(( "------------------------------------------------\n" )); @@ -103,6 +105,7 @@ { const char* p = blue_chars[blue]; const char* limit = p + MAX_TEST_CHARACTERS; + FT_Pos *blue_ref, *blue_shoot; @@ -235,8 +238,8 @@ AH_LOG(( "\n" )); /* we have computed the contents of the `rounds' and `flats' tables, */ - /* now determine the reference and overshoot position of the blue; */ - /* we simply take the median value after a simple short */ + /* now determine the reference and overshoot position of the blue -- */ + /* we simply take the median value after a simple sort */ sort_values( num_rounds, rounds ); sort_values( num_flats, flats ); @@ -312,7 +315,7 @@ /* stem height of the "-", but it wasn't too good. Moreover, we now */ /* have a single character that gives us standard width and height. */ { - FT_UInt glyph_index; + FT_UInt glyph_index; glyph_index = FT_Get_Char_Index( hinter->face, 'o' ); @@ -323,7 +326,8 @@ if ( error ) goto Exit; - error = ah_outline_load( hinter->glyph, 0x10000L, 0x10000L, hinter->face ); + error = ah_outline_load( hinter->glyph, 0x10000L, 0x10000L, + hinter->face ); if ( error ) goto Exit; @@ -375,7 +379,7 @@ } /* Now, compute the edge distance threshold as a fraction of the */ - /* smallest width in the font. Set it in `hinter.glyph' too! */ + /* smallest width in the font. Set it in `hinter->glyph' too! */ if ( edge_distance_threshold == 32000 ) edge_distance_threshold = 50; @@ -395,4 +399,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/autohint/ahglobal.h b/src/libs/freetype2/autohint/ahglobal.h index 9de961e7c0..5a9bcf8352 100644 --- a/src/libs/freetype2/autohint/ahglobal.h +++ b/src/libs/freetype2/autohint/ahglobal.h @@ -5,7 +5,7 @@ /* Routines used to compute global metrics automatically */ /* (specification). */ /* */ -/* Copyright 2000-2001, 2002 Catharon Productions Inc. */ +/* Copyright 2000-2001, 2002, 2003 Catharon Productions Inc. */ /* Author: David Turner */ /* */ /* This file is part of the Catharon Typography Project and shall only */ @@ -34,13 +34,16 @@ FT_BEGIN_HEADER #ifdef FT_CONFIG_CHESTER_SMALL_F -# define AH_IS_TOP_BLUE( b ) ( (b) == AH_BLUE_CAPITAL_TOP || (b) == AH_BLUE_SMALL_F_TOP || (b) == AH_BLUE_SMALL_TOP ) +#define AH_IS_TOP_BLUE( b ) ( (b) == AH_BLUE_CAPITAL_TOP || \ + (b) == AH_BLUE_SMALL_F_TOP || \ + (b) == AH_BLUE_SMALL_TOP ) -#else /* !CHESTER_SMALL_F */ +#else /* !FT_CONFIG_CHESTER_SMALL_F */ -# define AH_IS_TOP_BLUE( b ) ( (b) == AH_BLUE_CAPITAL_TOP || (b) == AH_BLUE_SMALL_TOP ) +#define AH_IS_TOP_BLUE( b ) ( (b) == AH_BLUE_CAPITAL_TOP || \ + (b) == AH_BLUE_SMALL_TOP ) -#endif /* !CHESTER_SMALL_F */ +#endif /* !FT_CONFIG_CHESTER_SMALL_F */ /* compute global metrics automatically */ @@ -53,4 +56,4 @@ FT_END_HEADER #endif /* __AHGLOBAL_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/autohint/ahglyph.c b/src/libs/freetype2/autohint/ahglyph.c index 68f762bc04..2a0390be44 100644 --- a/src/libs/freetype2/autohint/ahglyph.c +++ b/src/libs/freetype2/autohint/ahglyph.c @@ -5,7 +5,7 @@ /* Routines used to load and analyze a given glyph before hinting */ /* (body). */ /* */ -/* Copyright 2000-2001, 2002 Catharon Productions Inc. */ +/* Copyright 2000-2001, 2002, 2003, 2004 Catharon Productions Inc. */ /* Author: David Turner */ /* */ /* This file is part of the Catharon Typography Project and shall only */ @@ -120,8 +120,8 @@ : ( seg->dir == AH_DIR_RIGHT ? "right" : "none" ) ) ), - seg->link ? (seg->link-segments) : -1, - seg->serif ? (seg->serif-segments) : -1, + seg->link ? ( seg->link - segments ) : -1, + seg->serif ? ( seg->serif - segments ) : -1, (int)seg->num_linked, seg->first - points, seg->last - points ); @@ -135,18 +135,20 @@ #endif /* AH_DEBUG */ - /* compute the direction value of a given vector.. */ + /* compute the direction value of a given vector */ static AH_Direction ah_compute_direction( FT_Pos dx, FT_Pos dy ) { AH_Direction dir; - FT_Pos ax = ABS( dx ); - FT_Pos ay = ABS( dy ); + FT_Pos ax = FT_ABS( dx ); + FT_Pos ay = FT_ABS( dy ); dir = AH_DIR_NONE; + /* atan(1/12) == 4.7 degrees */ + /* test for vertical direction */ if ( ax * 12 < ay ) { @@ -163,10 +165,10 @@ /* this function is used by ah_get_orientation (see below) to test */ - /* the fill direction of a given bbox extrema */ + /* the fill direction of given bbox extremum */ static FT_Int - ah_test_extrema( FT_Outline* outline, - FT_Int n ) + ah_test_extremum( FT_Outline* outline, + FT_Int n ) { FT_Vector *prev, *cur, *next; FT_Pos product; @@ -175,7 +177,9 @@ /* we need to compute the `previous' and `next' point */ - /* for these extrema */ + /* for this extremum; we check whether the extremum */ + /* is start or end of a contour and providing */ + /* appropriate values if so */ cur = outline->points + n; prev = cur - 1; next = cur + 1; @@ -183,7 +187,7 @@ first = 0; for ( c = 0; c < outline->n_contours; c++ ) { - last = outline->contours[c]; + last = outline->contours[c]; if ( n == first ) prev = outline->points + last; @@ -194,6 +198,10 @@ first = last + 1; } + /* compute the vectorial product -- since we know that the angle */ + /* is <= 180 degrees (otherwise it wouldn't be an extremum) we */ + /* can determine the filling orientation if the product is */ + /* either positive or negative */ product = FT_MulDiv( cur->x - prev->x, /* in.x */ next->y - cur->y, /* out.y */ 0x40 ) @@ -218,7 +226,7 @@ /* We do this by computing bounding box points, and computing their */ /* curvature. */ /* */ - /* The function returns either 1 or -1. */ + /* The function returns either 1 or 2. */ /* */ static FT_Int ah_get_orientation( FT_Outline* outline ) @@ -272,20 +280,20 @@ } } - /* test orientation of the xmin */ - n = ah_test_extrema( outline, indices_xMin ); + /* test orientation of the extrema */ + n = ah_test_extremum( outline, indices_xMin ); if ( n ) goto Exit; - n = ah_test_extrema( outline, indices_yMin ); + n = ah_test_extremum( outline, indices_yMin ); if ( n ) goto Exit; - n = ah_test_extrema( outline, indices_xMax ); + n = ah_test_extremum( outline, indices_xMax ); if ( n ) goto Exit; - n = ah_test_extrema( outline, indices_yMax ); + n = ah_test_extremum( outline, indices_yMax ); if ( !n ) n = 1; @@ -306,14 +314,14 @@ ah_outline_new( FT_Memory memory, AH_Outline* aoutline ) { - FT_Error error; - AH_Outline outline; + FT_Error error; + AH_Outline outline; if ( !FT_NEW( outline ) ) { outline->memory = memory; - *aoutline = outline; + *aoutline = outline; } return error; @@ -410,7 +418,7 @@ /* first of all, reallocate the contours array if necessary */ if ( num_contours > outline->max_contours ) { - FT_Int new_contours = ( num_contours + 3 ) & -4; + FT_Int new_contours = FT_PAD_CEIL( num_contours, 4 ); if ( FT_RENEW_ARRAY( outline->contours, @@ -427,7 +435,7 @@ /* */ if ( num_points + 2 > outline->max_points ) { - FT_Int news = ( num_points + 2 + 7 ) & -8; + FT_Int news = FT_PAD_CEIL( num_points + 2, 8 ); FT_Int max = outline->max_points; @@ -452,7 +460,7 @@ /* We can't rely on the value of `FT_Outline.flags' to know the fill */ /* direction used for a glyph, given that some fonts are broken (e.g. */ - /* the Arphic ones). We thus recompute it each time we need to. */ + /* the Arphic ones). We thus recompute it each time we need to. */ /* */ outline->vert_major_dir = AH_DIR_UP; outline->horz_major_dir = AH_DIR_LEFT; @@ -479,7 +487,7 @@ /* compute coordinates */ { - FT_Vector* vec = source->points; + FT_Vector* vec = source->points; for ( point = points; point < point_limit; vec++, point++ ) @@ -503,9 +511,11 @@ switch ( FT_CURVE_TAG( *tag ) ) { case FT_CURVE_TAG_CONIC: - point->flags = AH_FLAG_CONIC; break; + point->flags = AH_FLAG_CONIC; + break; case FT_CURVE_TAG_CUBIC: - point->flags = AH_FLAG_CUBIC; break; + point->flags = AH_FLAG_CUBIC; + break; default: ; } @@ -585,7 +595,7 @@ point->out_dir = ah_compute_direction( ovec.x, ovec.y ); #ifndef AH_OPTION_NO_WEAK_INTERPOLATION - if ( point->flags & (AH_FLAG_CONIC | AH_FLAG_CUBIC) ) + if ( point->flags & ( AH_FLAG_CONIC | AH_FLAG_CUBIC ) ) { Is_Weak_Point: point->flags |= AH_FLAG_WEAK_INTERPOLATION; @@ -631,48 +641,70 @@ AH_Point point_limit = point + outline->num_points; - for ( ; point < point_limit; point++ ) + switch ( source ) { - FT_Pos u, v; - - - switch ( source ) + case AH_UV_FXY: + for ( ; point < point_limit; point++ ) { - case AH_UV_FXY: - u = point->fx; - v = point->fy; - break; - case AH_UV_FYX: - u = point->fy; - v = point->fx; - break; - case AH_UV_OXY: - u = point->ox; - v = point->oy; - break; - case AH_UV_OYX: - u = point->oy; - v = point->ox; - break; - case AH_UV_YX: - u = point->y; - v = point->x; - break; - case AH_UV_OX: - u = point->x; - v = point->ox; - break; - case AH_UV_OY: - u = point->y; - v = point->oy; - break; - default: - u = point->x; - v = point->y; - break; + point->u = point->fx; + point->v = point->fy; + } + break; + + case AH_UV_FYX: + for ( ; point < point_limit; point++ ) + { + point->u = point->fy; + point->v = point->fx; + } + break; + + case AH_UV_OXY: + for ( ; point < point_limit; point++ ) + { + point->u = point->ox; + point->v = point->oy; + } + break; + + case AH_UV_OYX: + for ( ; point < point_limit; point++ ) + { + point->u = point->oy; + point->v = point->ox; + } + break; + + case AH_UV_YX: + for ( ; point < point_limit; point++ ) + { + point->u = point->y; + point->v = point->x; + } + break; + + case AH_UV_OX: + for ( ; point < point_limit; point++ ) + { + point->u = point->x; + point->v = point->ox; + } + break; + + case AH_UV_OY: + for ( ; point < point_limit; point++ ) + { + point->u = point->y; + point->v = point->oy; + } + break; + + default: + for ( ; point < point_limit; point++ ) + { + point->u = point->x; + point->v = point->y; } - point->u = u; - point->v = v; } } @@ -681,8 +713,8 @@ static void ah_outline_compute_inflections( AH_Outline outline ) { - AH_Point* contour = outline->contours; - AH_Point* contour_limit = contour + outline->num_contours; + AH_Point* contour = outline->contours; + AH_Point* contour_limit = contour + outline->num_contours; /* load original coordinates in (u,v) */ @@ -692,10 +724,10 @@ for ( ; contour < contour_limit; contour++ ) { FT_Vector vec; - AH_Point point = contour[0]; - AH_Point first = point; - AH_Point start = point; - AH_Point end = point; + AH_Point point = contour[0]; + AH_Point first = point; + AH_Point start = point; + AH_Point end = point; AH_Point before; AH_Point after; AH_Angle angle_in, angle_seg, angle_out; @@ -769,7 +801,6 @@ { /* diff_in and diff_out have different signs, we have */ /* inflection points here... */ - do { start->flags |= AH_FLAG_INFLECTION; @@ -829,10 +860,10 @@ /* do each contour separately */ for ( ; contour < contour_limit; contour++ ) { - AH_Point point = contour[0]; - AH_Point last = point->prev; - int on_edge = 0; - FT_Pos min_pos = +32000; /* minimum segment pos != min_coord */ + AH_Point point = contour[0]; + AH_Point last = point->prev; + int on_edge = 0; + FT_Pos min_pos = 32000; /* minimum segment pos != min_coord */ FT_Pos max_pos = -32000; /* maximum segment pos != max_coord */ FT_Bool passed; @@ -850,11 +881,11 @@ } #endif - if ( point == last ) /* skip singletons -- just in case? */ + if ( point == last ) /* skip singletons -- just in case */ continue; - if ( ABS( last->out_dir ) == major_dir && - ABS( point->out_dir ) == major_dir ) + if ( FT_ABS( last->out_dir ) == major_dir && + FT_ABS( point->out_dir ) == major_dir ) { /* we are already on an edge, try to locate its start */ last = point; @@ -862,7 +893,7 @@ for (;;) { point = point->prev; - if ( ABS( point->out_dir ) != major_dir ) + if ( FT_ABS( point->out_dir ) != major_dir ) { point = point->next; break; @@ -927,7 +958,7 @@ passed = 1; } - if ( !on_edge && ABS( point->out_dir ) == major_dir ) + if ( !on_edge && FT_ABS( point->out_dir ) == major_dir ) { /* this is the start of a new segment! */ segment_dir = point->out_dir; @@ -941,6 +972,8 @@ segment->first = point; segment->last = point; segment->contour = contour; + segment->score = 32000; + segment->link = NULL; on_edge = 1; #ifdef AH_HINT_METRICS @@ -963,11 +996,11 @@ /* we do this by inserting fake segments when needed */ if ( dimension == 0 ) { - AH_Point point = outline->points; - AH_Point point_limit = point + outline->num_points; + AH_Point point = outline->points; + AH_Point point_limit = point + outline->num_points; - FT_Pos min_pos = 32000; - FT_Pos max_pos = -32000; + FT_Pos min_pos = 32000; + FT_Pos max_pos = -32000; min_point = 0; @@ -1002,6 +1035,8 @@ segment->first = min_point; segment->last = min_point; segment->pos = min_pos; + segment->score = 32000; + segment->link = NULL; num_segments++; segment++; @@ -1018,6 +1053,8 @@ segment->first = max_point; segment->last = max_point; segment->pos = max_pos; + segment->score = 32000; + segment->link = NULL; num_segments++; segment++; @@ -1030,6 +1067,7 @@ segments = outline->vert_segments; major_dir = AH_DIR_UP; p_num_segments = &outline->num_vsegments; + ah_setup_uv( outline, AH_UV_FXY ); } } @@ -1038,22 +1076,22 @@ FT_LOCAL_DEF( void ) ah_outline_link_segments( AH_Outline outline ) { - AH_Segment segments; - AH_Segment segment_limit; - int dimension; + AH_Segment segments; + AH_Segment segment_limit; + AH_Direction major_dir; + int dimension; - ah_setup_uv( outline, AH_UV_FYX ); - segments = outline->horz_segments; segment_limit = segments + outline->num_hsegments; + major_dir = outline->horz_major_dir; for ( dimension = 1; dimension >= 0; dimension-- ) { AH_Segment seg1; AH_Segment seg2; - +#if 0 /* now compare each segment to the others */ for ( seg1 = segments; seg1 < segment_limit; seg1++ ) { @@ -1070,7 +1108,7 @@ if ( best_segment ) best_score = seg1->score; else - best_score = 32000; + best_score = +32000; for ( seg2 = segments; seg2 < segment_limit; seg2++ ) if ( seg1 != seg2 && seg1->dir + seg2->dir == 0 ) @@ -1125,28 +1163,86 @@ { seg1->link = best_segment; seg1->score = best_score; - best_segment->num_linked++; } + } +#endif /* 0 */ - } /* edges 1 */ +#if 1 + /* the following code does the same, but much faster! */ + + /* now compare each segment to the others */ + for ( seg1 = segments; seg1 < segment_limit; seg1++ ) + { + /* the fake segments are introduced to hint the metrics -- */ + /* we must never link them to anything */ + if ( seg1->first == seg1->last || seg1->dir != major_dir ) + continue; + + for ( seg2 = segments; seg2 < segment_limit; seg2++ ) + if ( seg2 != seg1 && seg1->dir + seg2->dir == 0 ) + { + FT_Pos pos1 = seg1->pos; + FT_Pos pos2 = seg2->pos; + FT_Pos dist = pos2 - pos1; + + + if ( dist < 0 ) + continue; + + { + FT_Pos min = seg1->min_coord; + FT_Pos max = seg1->max_coord; + FT_Pos len, score; + + + if ( min < seg2->min_coord ) + min = seg2->min_coord; + + if ( max > seg2->max_coord ) + max = seg2->max_coord; + + len = max - min; + if ( len >= 8 ) + { + score = dist + 3000 / len; + + if ( score < seg1->score ) + { + seg1->score = score; + seg1->link = seg2; + } + + if ( score < seg2->score ) + { + seg2->score = score; + seg2->link = seg1; + } + } + } + } + } +#endif /* 1 */ /* now, compute the `serif' segments */ for ( seg1 = segments; seg1 < segment_limit; seg1++ ) { seg2 = seg1->link; - if ( seg2 && seg2->link != seg1 ) + if ( seg2 ) { - seg1->link = 0; - seg1->serif = seg2->link; + seg2->num_linked++; + if ( seg2->link != seg1 ) + { + seg1->link = 0; + seg1->serif = seg2->link; + } } } - ah_setup_uv( outline, AH_UV_FXY ); - segments = outline->vert_segments; segment_limit = segments + outline->num_vsegments; + major_dir = outline->vert_major_dir; } } @@ -1199,6 +1295,9 @@ if ( edge_distance_threshold > 64 / 4 ) edge_distance_threshold = 64 / 4; + edge_distance_threshold = FT_DivFix( edge_distance_threshold, + scale ); + edge_limit = edges; for ( seg = segments; seg < segment_limit; seg++ ) { @@ -1215,7 +1314,6 @@ if ( dist < 0 ) dist = -dist; - dist = FT_MulFix( dist, scale ); if ( dist < edge_distance_threshold ) { found = edge; @@ -1253,7 +1351,6 @@ edge->last = seg; } } - *p_num_edges = (FT_Int)( edge_limit - edges ); @@ -1264,13 +1361,19 @@ /* */ /* - edge's main direction */ /* - stem edge, serif edge or both (which defaults to stem then) */ - /* - rounded edge, straigth or both (which defaults to straight) */ + /* - rounded edge, straight or both (which defaults to straight) */ /* - link for edge */ /* */ /*********************************************************************/ /* first of all, set the `edge' field in each segment -- this is */ /* required in order to compute edge links */ + + /* Note that I've tried to remove this loop, setting + * the "edge" field of each segment directly in the + * code above. For some reason, it slows down execution + * speed -- on a Sun. + */ for ( edge = edges; edge < edge_limit; edge++ ) { seg = edge->first; @@ -1358,12 +1461,12 @@ } else edge->link = edge2; -#else /* !CHESTER_SERIF */ +#else /* !FT_CONFIG_CHESTER_SERIF */ if ( is_serif ) edge->serif = edge2; else edge->link = edge2; -#endif +#endif /* !FT_CONFIG_CHESTER_SERIF */ } seg = seg->edge_next; @@ -1383,10 +1486,10 @@ edge->dir = up_dir; else if ( ups < downs ) - edge->dir = - up_dir; + edge->dir = -up_dir; else if ( ups == downs ) - edge->dir = 0; /* both up and down !! */ + edge->dir = 0; /* both up and down! */ /* gets rid of serifs if link is set */ /* XXX: This gets rid of many unpleasant artefacts! */ @@ -1459,7 +1562,7 @@ ref = globals->blue_refs[blue]; shoot = globals->blue_shoots[blue]; - dist = ref-shoot; + dist = ref - shoot; if ( dist < 0 ) dist = -dist; @@ -1477,7 +1580,7 @@ return; } - /* compute for each horizontal edge, which blue zone is closer */ + /* for each horizontal edge search the blue zone which is closest */ for ( ; edge < edge_limit; edge++ ) { AH_Blue blue; @@ -1493,7 +1596,7 @@ best_dist = 64 / 2; #else if ( best_dist > 64 / 4 ) - best_dist = 64 / 4; + best_dist = 64 / 4; #endif for ( blue = AH_BLUE_CAPITAL_TOP; blue < AH_BLUE_MAX; blue++ ) @@ -1507,6 +1610,7 @@ FT_Bool is_major_dir = FT_BOOL( edge->dir == outline->horz_major_dir ); + if ( !blue_active[blue] ) continue; @@ -1569,7 +1673,7 @@ /* ah_outline_scale_blue_edges */ /* */ /* <Description> */ - /* This functions must be called before hinting in order to re-adjust */ + /* This function must be called before hinting in order to re-adjust */ /* the contents of the detected edges (basically change the `blue */ /* edge' pointer from `design units' to `scaled ones'). */ /* */ @@ -1592,4 +1696,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/autohint/ahglyph.h b/src/libs/freetype2/autohint/ahglyph.h index c0f2abd1b4..b346cbe8b6 100644 --- a/src/libs/freetype2/autohint/ahglyph.h +++ b/src/libs/freetype2/autohint/ahglyph.h @@ -92,4 +92,4 @@ FT_END_HEADER #endif /* __AHGLYPH_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/autohint/ahhint.c b/src/libs/freetype2/autohint/ahhint.c index 3cd37b0b88..69ac954705 100644 --- a/src/libs/freetype2/autohint/ahhint.c +++ b/src/libs/freetype2/autohint/ahhint.c @@ -4,7 +4,7 @@ /* */ /* Glyph hinter (body). */ /* */ -/* Copyright 2000-2001, 2002 Catharon Productions Inc. */ +/* Copyright 2000-2001, 2002, 2003, 2004 Catharon Productions Inc. */ /* Author: David Turner */ /* */ /* This file is part of the Catharon Typography Project and shall only */ @@ -27,11 +27,12 @@ #include FT_OUTLINE_H -#define FACE_GLOBALS( face ) ((AH_Face_Globals)(face)->autohint.data) +#define FACE_GLOBALS( face ) ( (AH_Face_Globals)(face)->autohint.data ) #define AH_USE_IUP #define OPTIM_STEM_SNAP + /*************************************************************************/ /*************************************************************************/ /**** ****/ @@ -70,7 +71,7 @@ } } - scaled = (reference+32) & -64; + scaled = FT_PIX_ROUND( reference ); if ( width >= reference ) { @@ -88,7 +89,9 @@ /* compute the snapped width of a given stem */ + #ifdef FT_CONFIG_CHESTER_SERIF + static FT_Pos ah_compute_stem_width( AH_Hinter hinter, int vertical, @@ -114,7 +117,7 @@ else if ( ( vertical && !hinter->do_vert_snapping ) || ( !vertical && !hinter->do_horz_snapping ) ) { - /* smooth hinting process, very lightly quantize the stem width */ + /* smooth hinting process: very lightly quantize the stem width */ /* */ /* leave the widths of serifs alone */ @@ -148,8 +151,8 @@ if ( dist < 3 * 64 ) { - delta = ( dist & 63 ); - dist &= -64; + delta = dist & 63; + dist &= -64; if ( delta < 10 ) dist += delta; @@ -164,12 +167,12 @@ dist += delta; } else - dist = ( dist + 32 ) & -64; + dist = ( dist + 32 ) & ~63; } } else { - /* strong hinting process, snap the stem width to integer pixels */ + /* strong hinting process: snap the stem width to integer pixels */ /* */ if ( vertical ) { @@ -178,13 +181,13 @@ /* in the case of vertical hinting, always round */ /* the stem heights to integer pixels */ if ( dist >= 64 ) - dist = ( dist + 16 ) & -64; + dist = ( dist + 16 ) & ~63; else dist = 64; } else { - dist = ah_snap_width( globals->widths, globals->num_widths, dist ); + dist = ah_snap_width( globals->widths, globals->num_widths, dist ); if ( hinter->flags & AH_HINTER_MONOCHROME ) { @@ -193,7 +196,7 @@ if ( dist < 64 ) dist = 64; else - dist = ( dist + 32 ) & -64; + dist = ( dist + 32 ) & ~63; } else { @@ -204,10 +207,10 @@ dist = ( dist + 64 ) >> 1; else if ( dist < 128 ) - dist = ( dist + 22 ) & -64; + dist = ( dist + 22 ) & ~63; else - /* XXX: round otherwise, prevent color fringes in LCD mode */ - dist = ( dist + 32 ) & -64; + /* XXX: round otherwise to prevent color fringes in LCD mode */ + dist = ( dist + 32 ) & ~63; } } } @@ -218,7 +221,9 @@ return dist; } -#else /* !CHESTER_SERIF */ + +#else /* !FT_CONFIG_CHESTER_SERIF */ + static FT_Pos ah_compute_stem_width( AH_Hinter hinter, int vertical, @@ -242,7 +247,7 @@ else if ( ( vertical && !hinter->do_vert_snapping ) || ( !vertical && !hinter->do_horz_snapping ) ) { - /* smooth hinting process, very lightly quantize the stem width */ + /* smooth hinting process: very lightly quantize the stem width */ /* */ if ( dist < 64 ) dist = 64; @@ -263,8 +268,8 @@ if ( dist < 3 * 64 ) { - delta = ( dist & 63 ); - dist &= -64; + delta = dist & 63; + dist &= -64; if ( delta < 10 ) dist += delta; @@ -279,12 +284,12 @@ dist += delta; } else - dist = ( dist + 32 ) & -64; + dist = ( dist + 32 ) & ~63; } } else { - /* strong hinting process, snap the stem width to integer pixels */ + /* strong hinting process: snap the stem width to integer pixels */ /* */ if ( vertical ) { @@ -293,13 +298,13 @@ /* in the case of vertical hinting, always round */ /* the stem heights to integer pixels */ if ( dist >= 64 ) - dist = ( dist + 16 ) & -64; + dist = ( dist + 16 ) & ~63; else dist = 64; } else { - dist = ah_snap_width( globals->widths, globals->num_widths, dist ); + dist = ah_snap_width( globals->widths, globals->num_widths, dist ); if ( hinter->flags & AH_HINTER_MONOCHROME ) { @@ -308,7 +313,7 @@ if ( dist < 64 ) dist = 64; else - dist = ( dist + 32 ) & -64; + dist = ( dist + 32 ) & ~63; } else { @@ -319,10 +324,10 @@ dist = ( dist + 64 ) >> 1; else if ( dist < 128 ) - dist = ( dist + 22 ) & -64; + dist = ( dist + 22 ) & ~63; else - /* XXX: round otherwise, prevent color fringes in LCD mode */ - dist = ( dist + 32 ) & -64; + /* XXX: round otherwise to prevent color fringes in LCD mode */ + dist = ( dist + 32 ) & ~63; } } } @@ -332,7 +337,8 @@ return dist; } -#endif /* !CHESTER_SERIF */ + +#endif /* !FT_CONFIG_CHESTER_SERIF */ /* align one stem edge relative to the previous stem edge */ @@ -345,17 +351,23 @@ FT_Pos dist = stem_edge->opos - base_edge->opos; #ifdef FT_CONFIG_CHESTER_SERIF + FT_Pos fitted_width = ah_compute_stem_width( hinter, vertical, dist, base_edge->flags, stem_edge->flags ); + stem_edge->pos = base_edge->pos + fitted_width; + #else + stem_edge->pos = base_edge->pos + ah_compute_stem_width( hinter, vertical, dist ); + #endif + } @@ -371,6 +383,7 @@ FT_UNUSED( hinter ); FT_UNUSED( vertical ); + dist = serif->opos - base->opos; if ( dist < 0 ) { @@ -378,15 +391,16 @@ sign = -1; } - /* do not touch serifs widths !! */ #if 0 + /* do not touch serifs widths! */ if ( base->flags & AH_EDGE_DONE ) { if ( dist >= 64 ) - dist = (dist+8) & -64; + dist = ( dist + 8 ) & ~63; else if ( dist <= 32 && !vertical ) dist = ( dist + 33 ) >> 1; + else dist = 0; } @@ -407,14 +421,14 @@ /*************************************************************************/ - /* Another alternative edge hinting algorithm */ - static void - ah_hint_edges_3( AH_Hinter hinter ) + FT_LOCAL_DEF( void ) + ah_hinter_hint_edges( AH_Hinter hinter ) { AH_Edge edges; AH_Edge edge_limit; AH_Outline outline = hinter->glyph; FT_Int dimension; + FT_Int n_edges; edges = outline->horz_edges; @@ -454,7 +468,7 @@ { edge1 = edge; } - else if (edge2 && edge2->blue_edge) + else if ( edge2 && edge2->blue_edge ) { blue = edge2->blue_edge; edge1 = edge2; @@ -478,8 +492,8 @@ } } - /* now, we will align all stem edges, trying to maintain the */ - /* relative order of stems in the glyph.. */ + /* now we will align all stem edges, trying to maintain the */ + /* relative order of stems in the glyph */ for ( edge = edges; edge < edge_limit; edge++ ) { AH_EdgeRec* edge2; @@ -496,12 +510,11 @@ continue; } - /* now, align the stem */ + /* now align the stem */ - /* this should not happen, but it's better to be safe. */ + /* this should not happen, but it's better to be safe */ if ( edge2->blue_edge || edge2 < edge ) { - ah_align_linked_edge( hinter, edge2, edge, dimension ); edge->flags |= AH_EDGE_DONE; continue; @@ -509,15 +522,18 @@ if ( !anchor ) { + #ifdef FT_CONFIG_CHESTER_STEM - FT_Pos org_len, org_center, cur_len; - FT_Pos cur_pos1, error1, error2, u_off, d_off; - org_len = edge2->opos - edge->opos; - cur_len = ah_compute_stem_width( hinter, dimension, org_len, - edge->flags, edge2->flags ); + FT_Pos org_len, org_center, cur_len; + FT_Pos cur_pos1, error1, error2, u_off, d_off; - if (cur_len <= 64 ) + + org_len = edge2->opos - edge->opos; + cur_len = ah_compute_stem_width( hinter, dimension, org_len, + edge->flags, edge2->flags ); + + if ( cur_len <= 64 ) u_off = d_off = 32; else { @@ -529,7 +545,7 @@ { org_center = edge->opos + ( org_len >> 1 ); - cur_pos1 = ( org_center + 32 ) & -64; + cur_pos1 = FT_PIX_ROUND( org_center ); error1 = org_center - ( cur_pos1 - u_off ); if ( error1 < 0 ) @@ -549,46 +565,56 @@ } else - edge->pos = ( edge->opos + 32 ) & -64; + edge->pos = FT_PIX_ROUND( edge->opos ); + anchor = edge; + + edge->flags |= AH_EDGE_DONE; + + ah_align_linked_edge( hinter, edge, edge2, dimension ); + +#else /* !FT_CONFIG_CHESTER_STEM */ + + edge->pos = FT_PIX_ROUND( edge->opos ); anchor = edge; edge->flags |= AH_EDGE_DONE; ah_align_linked_edge( hinter, edge, edge2, dimension ); -#else /* !CHESTER_STEM */ - edge->pos = ( edge->opos + 32 ) & -64; - anchor = edge; - edge->flags |= AH_EDGE_DONE; +#endif /* !FT_CONFIG_CHESTER_STEM */ - ah_align_linked_edge( hinter, edge, edge2, dimension ); -#endif /* !CHESTER_STEM */ } else { - FT_Pos org_pos, org_len, org_center, cur_len; - FT_Pos cur_pos1, cur_pos2, delta1, delta2; + FT_Pos org_pos, org_len, org_center, cur_len; + FT_Pos cur_pos1, cur_pos2, delta1, delta2; - org_pos = anchor->pos + (edge->opos - anchor->opos); + org_pos = anchor->pos + ( edge->opos - anchor->opos ); org_len = edge2->opos - edge->opos; org_center = org_pos + ( org_len >> 1 ); #ifdef FT_CONFIG_CHESTER_SERIF - cur_len = ah_compute_stem_width( hinter, dimension, org_len, - edge->flags, edge2->flags ); -#else /* !CHESTER_SERIF */ - cur_len = ah_compute_stem_width( hinter, dimension, org_len ); -#endif /* !CHESTER_SERIF */ + + cur_len = ah_compute_stem_width( hinter, dimension, org_len, + edge->flags, edge2->flags ); + + +#else /* !FT_CONFIG_CHESTER_SERIF */ + + cur_len = ah_compute_stem_width( hinter, dimension, org_len ); + +#endif /* !FT_CONFIG_CHESTER_SERIF */ #ifdef FT_CONFIG_CHESTER_STEM + if ( cur_len < 96 ) { FT_Pos u_off, d_off; - cur_pos1 = ( org_center + 32 ) & -64; + cur_pos1 = FT_PIX_ROUND( org_center ); if (cur_len <= 64 ) u_off = d_off = 32; @@ -598,11 +624,11 @@ d_off = 26; } - delta1 = org_center - (cur_pos1 - u_off); + delta1 = org_center - ( cur_pos1 - u_off ); if ( delta1 < 0 ) delta1 = -delta1; - delta2 = org_center - (cur_pos1 + d_off); + delta2 = org_center - ( cur_pos1 + d_off ); if ( delta2 < 0 ) delta2 = -delta2; @@ -616,20 +642,19 @@ } else { - - org_pos = anchor->pos + (edge->opos - anchor->opos); + org_pos = anchor->pos + ( edge->opos - anchor->opos ); org_len = edge2->opos - edge->opos; org_center = org_pos + ( org_len >> 1 ); cur_len = ah_compute_stem_width( hinter, dimension, org_len, edge->flags, edge2->flags ); - cur_pos1 = ( org_pos + 32 ) & -64; + cur_pos1 = FT_PIX_ROUND( org_pos ); delta1 = ( cur_pos1 + ( cur_len >> 1 ) - org_center ); if ( delta1 < 0 ) delta1 = -delta1; - cur_pos2 = ( ( org_pos + org_len + 32 ) & -64 ) - cur_len; + cur_pos2 = FT_PIX_ROUND( org_pos + org_len ) - cur_len; delta2 = ( cur_pos2 + ( cur_len >> 1 ) - org_center ); if ( delta2 < 0 ) delta2 = -delta2; @@ -638,14 +663,14 @@ edge2->pos = edge->pos + cur_len; } -#else /* !CHESTER_STEM */ +#else /* !FT_CONFIG_CHESTER_STEM */ - cur_pos1 = ( org_pos + 32 ) & -64; + cur_pos1 = FT_PIX_ROUND( org_pos ); delta1 = ( cur_pos1 + ( cur_len >> 1 ) - org_center ); if ( delta1 < 0 ) delta1 = -delta1; - cur_pos2 = ( ( org_pos + org_len + 32 ) & -64 ) - cur_len; + cur_pos2 = FT_PIX_ROUND( org_pos + org_len ) - cur_len; delta2 = ( cur_pos2 + ( cur_len >> 1 ) - org_center ); if ( delta2 < 0 ) delta2 = -delta2; @@ -653,7 +678,7 @@ edge->pos = ( delta1 <= delta2 ) ? cur_pos1 : cur_pos2; edge2->pos = edge->pos + cur_len; -#endif /* !CHESTER_STEM */ +#endif /* !FT_CONFIG_CHESTER_STEM */ edge->flags |= AH_EDGE_DONE; edge2->flags |= AH_EDGE_DONE; @@ -663,11 +688,73 @@ } } + /* make sure that lowercase m's maintain their symmetry */ + + /* In general, lowercase m's have six vertical edges if they are sans */ + /* serif, or twelve if they are avec serif. This implementation is */ + /* based on that assumption, and seems to work very well with most */ + /* faces. However, if for a certain face this assumption is not */ + /* true, the m is just rendered like before. In addition, any stem */ + /* correction will only be applied to symmetrical glyphs (even if the */ + /* glyph is not an m), so the potential for unwanted distortion is */ + /* relatively low. */ + + /* We don't handle horizontal edges since we can't easily assure that */ + /* the third (lowest) stem aligns with the base line; it might end up */ + /* one pixel higher or lower. */ + + n_edges = (FT_Int)( edge_limit - edges ); + if ( !dimension && ( n_edges == 6 || n_edges == 12 ) ) + { + AH_EdgeRec *edge1, *edge2, *edge3; + FT_Pos dist1, dist2, span, delta; + + + if ( n_edges == 6 ) + { + edge1 = edges; + edge2 = edges + 2; + edge3 = edges + 4; + } + else + { + edge1 = edges + 1; + edge2 = edges + 5; + edge3 = edges + 9; + } + + dist1 = edge2->opos - edge1->opos; + dist2 = edge3->opos - edge2->opos; + + span = dist1 - dist2; + if ( span < 0 ) + span = -span; + + if ( span < 8 ) + { + delta = edge3->pos - ( 2 * edge2->pos - edge1->pos ); + edge3->pos -= delta; + if ( edge3->link ) + edge3->link->pos -= delta; + + /* move the serifs along with the stem */ + if ( n_edges == 12 ) + { + ( edges + 8 )->pos -= delta; + ( edges + 11 )->pos -= delta; + } + + edge3->flags |= AH_EDGE_DONE; + if ( edge3->link ) + edge3->link->flags |= AH_EDGE_DONE; + } + } + if ( !has_serifs ) goto Next_Dimension; - /* now, hint the remaining edges (serifs and single) in order */ - /* to complete our processing */ + /* now hint the remaining edges (serifs and single) in order */ + /* to complete our processing */ for ( edge = edges; edge < edge_limit; edge++ ) { if ( edge->flags & AH_EDGE_DONE ) @@ -677,12 +764,12 @@ ah_align_serif_edge( hinter, edge->serif, edge, dimension ); else if ( !anchor ) { - edge->pos = ( edge->opos + 32 ) & -64; + edge->pos = FT_PIX_ROUND( edge->opos ); anchor = edge; } else edge->pos = anchor->pos + - ( ( edge->opos-anchor->opos + 32 ) & -64 ); + FT_PIX_ROUND( edge->opos - anchor->opos ); edge->flags |= AH_EDGE_DONE; @@ -702,18 +789,6 @@ } - FT_LOCAL_DEF( void ) - ah_hinter_hint_edges( AH_Hinter hinter ) - { - /* AH_Interpolate_Blue_Edges( hinter ); -- doesn't seem to help */ - /* reduce the problem of the disappearing eye in the `e' of Times... */ - /* also, creates some artifacts near the blue zones? */ - { - ah_hint_edges_3( hinter ); - } - } - - /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ @@ -785,6 +860,7 @@ /* hint the strong points -- this is equivalent to the TrueType `IP' */ + /* hinting instruction */ static void ah_hinter_align_strong_points( AH_Hinter hinter ) { @@ -850,7 +926,7 @@ goto Store_Point; } - /* is the point after the last edge ? */ + /* is the point after the last edge? */ edge = edge_limit - 1; delta = u - edge->fpos; if ( delta >= 0 ) @@ -859,6 +935,51 @@ goto Store_Point; } +#if 1 + { + FT_UInt min, max, mid; + FT_Pos fpos; + + + /* find enclosing edges */ + min = 0; + max = (FT_UInt)( edge_limit - edges ); + + while ( min < max ) + { + mid = ( max + min ) >> 1; + edge = edges + mid; + fpos = edge->fpos; + + if ( u < fpos ) + max = mid; + else if ( u > fpos ) + min = mid + 1; + else + { + /* we are on the edge */ + u = edge->pos; + goto Store_Point; + } + } + + { + AH_Edge before = edges + min - 1; + AH_Edge after = edges + min + 0; + + + /* assert( before && after && before != after ) */ + if ( before->scale == 0 ) + before->scale = FT_DivFix( after->pos - before->pos, + after->fpos - before->fpos ); + + u = before->pos + FT_MulFix( fu - before->fpos, + before->scale ); + } + } + +#else /* !0 */ + /* otherwise, interpolate the point in between */ { AH_Edge before = 0; @@ -889,12 +1010,16 @@ after = edge; } - /* assert( before && after && before != after ) */ - u = before->pos + FT_MulDiv( fu - before->fpos, - after->pos - before->pos, - after->fpos - before->fpos ); + if ( before->scale == 0 ) + before->scale = FT_DivFix( after->pos - before->pos, + after->fpos - before->fpos ); + + u = before->pos + FT_MulFix( fu - before->fpos, + before->scale ); } +#endif /* !0 */ + Store_Point: /* save the point position */ @@ -1001,6 +1126,7 @@ /* interpolate weak points -- this is equivalent to the TrueType `IUP' */ + /* hinting instruction */ static void ah_hinter_align_weak_points( AH_Hinter hinter ) { @@ -1141,8 +1267,8 @@ { FT_Int n; AH_Face_Globals globals = hinter->globals; - AH_Globals design = &globals->design; - AH_Globals scaled = &globals->scaled; + AH_Globals design = &globals->design; + AH_Globals scaled = &globals->scaled; /* copy content */ @@ -1173,15 +1299,16 @@ if ( delta2 < 32 ) delta2 = 0; else if ( delta2 < 64 ) - delta2 = 32 + ( ( ( delta2 - 32 ) + 16 ) & -32 ); + delta2 = 32 + ( ( ( delta2 - 32 ) + 16 ) & ~31 ); else - delta2 = ( delta2 + 32 ) & -64; + delta2 = FT_PIX_ROUND( delta2 ); if ( delta < 0 ) delta2 = -delta2; scaled->blue_refs[n] = - ( FT_MulFix( design->blue_refs[n], y_scale ) + 32 ) & -64; + FT_PIX_ROUND( FT_MulFix( design->blue_refs[n], y_scale ) ); + scaled->blue_shoots[n] = scaled->blue_refs[n] + delta2; } @@ -1211,7 +1338,7 @@ ah_outline_done( hinter->glyph ); /* note: the `globals' pointer is _not_ owned by the hinter */ - /* but by the current face object, we don't need to */ + /* but by the current face object; we don't need to */ /* release it */ hinter->globals = 0; hinter->face = 0; @@ -1360,26 +1487,26 @@ } } - /* copy the outline points in the loader's current */ - /* extra points, which is used to keep original glyph coordinates */ - error = ah_loader_check_points( gloader, slot->outline.n_points + 2, + /* copy the outline points in the loader's current */ + /* extra points which is used to keep original glyph coordinates */ + error = ah_loader_check_points( gloader, slot->outline.n_points + 4, slot->outline.n_contours ); if ( error ) goto Exit; - FT_MEM_COPY( gloader->current.extra_points, slot->outline.points, - slot->outline.n_points * sizeof ( FT_Vector ) ); + FT_ARRAY_COPY( gloader->current.extra_points, slot->outline.points, + slot->outline.n_points ); - FT_MEM_COPY( gloader->current.outline.contours, slot->outline.contours, - slot->outline.n_contours * sizeof ( short ) ); + FT_ARRAY_COPY( gloader->current.outline.contours, slot->outline.contours, + slot->outline.n_contours ); - FT_MEM_COPY( gloader->current.outline.tags, slot->outline.tags, - slot->outline.n_points * sizeof ( char ) ); + FT_ARRAY_COPY( gloader->current.outline.tags, slot->outline.tags, + slot->outline.n_points ); gloader->current.outline.n_points = slot->outline.n_points; gloader->current.outline.n_contours = slot->outline.n_contours; - /* compute original phantom points */ + /* compute original horizontal phantom points, ignoring vertical ones */ hinter->pp1.x = 0; hinter->pp1.y = 0; hinter->pp2.x = FT_MulFix( slot->metrics.horiAdvance, x_scale ); @@ -1389,8 +1516,8 @@ if ( slot->outline.n_points == 0 ) goto Hint_Metrics; - /* now, load the slot image into the auto-outline, and run the */ - /* automatic hinting process */ + /* now load the slot image into the auto-outline and run the */ + /* automatic hinting process */ error = ah_outline_load( outline, x_scale, y_scale, face ); if ( error ) goto Exit; @@ -1413,6 +1540,7 @@ /* we now need to hint the metrics according to the change in */ /* width/positioning that occured during the hinting process */ + if ( outline->num_vedges > 0 ) { FT_Pos old_advance, old_rsb, old_lsb, new_lsb; AH_Edge edge1 = outline->vert_edges; /* leftmost edge */ @@ -1425,8 +1553,8 @@ old_lsb = edge1->opos; new_lsb = edge1->pos; - hinter->pp1.x = ( ( new_lsb - old_lsb ) + 32 ) & -64; - hinter->pp2.x = ( ( edge2->pos + old_rsb ) + 32 ) & -64; + hinter->pp1.x = FT_PIX_ROUND( new_lsb - old_lsb ); + hinter->pp2.x = FT_PIX_ROUND( edge2->pos + old_rsb ); #if 0 /* try to fix certain bad advance computations */ @@ -1435,6 +1563,12 @@ #endif } + else + { + hinter->pp1.x = ( hinter->pp1.x + 32 ) & -64; + hinter->pp2.x = ( hinter->pp2.x + 32 ) & -64; + } + /* good, we simply add the glyph to our loader's base */ ah_loader_add( gloader ); break; @@ -1446,15 +1580,15 @@ FT_SubGlyph subglyph; - start_point = gloader->base.outline.n_points; + start_point = gloader->base.outline.n_points; /* first of all, copy the subglyph descriptors in the glyph loader */ error = ah_loader_check_subglyphs( gloader, num_subglyphs ); if ( error ) goto Exit; - FT_MEM_COPY( gloader->current.subglyphs, slot->subglyphs, - num_subglyphs * sizeof ( FT_SubGlyph ) ); + FT_ARRAY_COPY( gloader->current.subglyphs, slot->subglyphs, + num_subglyphs ); gloader->current.num_subglyphs = num_subglyphs; num_base_subgs = gloader->base.num_subglyphs; @@ -1529,8 +1663,8 @@ FT_Vector* p2; - if ( start_point + k >= num_base_points || - l >= (FT_UInt)num_new_points ) + if ( start_point + k >= num_base_points || + l >= (FT_UInt)num_new_points ) { error = AH_Err_Invalid_Composite; goto Exit; @@ -1538,7 +1672,7 @@ l += num_base_points; - /* for now, only use the current point coordinates */ + /* for now, only use the current point coordinates; */ /* we may consider another approach in the near future */ p1 = gloader->base.outline.points + start_point + k; p2 = gloader->base.outline.points + start_point + l; @@ -1551,8 +1685,8 @@ x = FT_MulFix( subglyph->arg1, x_scale ); y = FT_MulFix( subglyph->arg2, y_scale ); - x = ( x + 32 ) & -64; - y = ( y + 32 ) & -64; + x = FT_PIX_ROUND(x); + y = FT_PIX_ROUND(y); } { @@ -1583,31 +1717,31 @@ if ( hinter->transformed ) FT_Outline_Transform( &gloader->base.outline, &hinter->trans_matrix ); - /* we must translate our final outline by -pp1.x, and compute */ - /* the new metrics */ + /* we must translate our final outline by -pp1.x and compute */ + /* the new metrics */ if ( hinter->pp1.x ) FT_Outline_Translate( &gloader->base.outline, -hinter->pp1.x, 0 ); FT_Outline_Get_CBox( &gloader->base.outline, &bbox ); - bbox.xMin &= -64; - bbox.yMin &= -64; - bbox.xMax = ( bbox.xMax + 63 ) & -64; - bbox.yMax = ( bbox.yMax + 63 ) & -64; + bbox.xMin = FT_PIX_FLOOR( bbox.xMin ); + bbox.yMin = FT_PIX_FLOOR( bbox.yMin ); + bbox.xMax = FT_PIX_CEIL( bbox.xMax ); + bbox.yMax = FT_PIX_CEIL( bbox.yMax ); slot->metrics.width = bbox.xMax - bbox.xMin; slot->metrics.height = bbox.yMax - bbox.yMin; slot->metrics.horiBearingX = bbox.xMin; slot->metrics.horiBearingY = bbox.yMax; - /* for mono-width fonts (like Andale, Courier, etc.), we need */ - /* to keep the original rounded advance width */ + /* for mono-width fonts (like Andale, Courier, etc.) we need */ + /* to keep the original rounded advance width */ if ( !FT_IS_FIXED_WIDTH( slot->face ) ) slot->metrics.horiAdvance = hinter->pp2.x - hinter->pp1.x; else slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, x_scale ); - slot->metrics.horiAdvance = ( slot->metrics.horiAdvance + 32 ) & -64; + slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance ); /* now copy outline into glyph slot */ ah_loader_rewind( slot->internal->loader ); @@ -1641,7 +1775,7 @@ FT_Fixed x_scale = size->metrics.x_scale; FT_Fixed y_scale = size->metrics.y_scale; AH_Face_Globals face_globals = FACE_GLOBALS( face ); - FT_Render_Mode hint_mode = FT_LOAD_TARGET_MODE(load_flags); + FT_Render_Mode hint_mode = FT_LOAD_TARGET_MODE( load_flags ); /* first of all, we need to check that we're using the correct face and */ @@ -1662,19 +1796,22 @@ } #ifdef FT_CONFIG_CHESTER_BLUE_SCALE + /* try to optimize the y_scale so that the top of non-capital letters * is aligned on a pixel boundary whenever possible */ { AH_Globals design = &face_globals->design; - FT_Pos shoot = design->blue_shoots[ AH_BLUE_SMALL_TOP ]; + FT_Pos shoot = design->blue_shoots[AH_BLUE_SMALL_TOP]; - /* the value of 'shoot' will be -1000 if the font doesn't have */ - /* small latin letters; we simply check the sign here... */ + + /* the value of 'shoot' will be -1000 if the font doesn't have */ + /* small latin letters; we simply check the sign here... */ if ( shoot > 0 ) { FT_Pos scaled = FT_MulFix( shoot, y_scale ); - FT_Pos fitted = ( scaled + 32 ) & -64; + FT_Pos fitted = FT_PIX_ROUND( scaled ); + if ( scaled != fitted ) { @@ -1685,10 +1822,11 @@ /* adust x_scale */ if ( fitted < scaled ) - x_scale -= x_scale/50; /* x_scale*0.98 with integers */ + x_scale -= x_scale / 50; /* x_scale*0.98 with integers */ } } } + #endif /* FT_CONFIG_CHESTER_BLUE_SCALE */ /* now, we must check the current character pixel size to see if we */ @@ -1720,12 +1858,9 @@ hinter->do_stem_adjust = FT_BOOL( hint_mode != FT_RENDER_MODE_LIGHT ); -#if 1 - load_flags = FT_LOAD_NO_SCALE - | FT_LOAD_IGNORE_TRANSFORM ; -#else - load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_RECURSE; -#endif + load_flags |= FT_LOAD_NO_SCALE + | FT_LOAD_IGNORE_TRANSFORM; + load_flags &= ~FT_LOAD_RENDER; error = ah_hinter_load( hinter, glyph_index, load_flags, 0 ); @@ -1783,4 +1918,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/autohint/ahhint.h b/src/libs/freetype2/autohint/ahhint.h index a0c015dab7..2c352d0c99 100644 --- a/src/libs/freetype2/autohint/ahhint.h +++ b/src/libs/freetype2/autohint/ahhint.h @@ -72,4 +72,4 @@ FT_END_HEADER #endif /* __AHHINT_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/autohint/ahloader.h b/src/libs/freetype2/autohint/ahloader.h index e4cb73c8db..c8e42ef225 100644 --- a/src/libs/freetype2/autohint/ahloader.h +++ b/src/libs/freetype2/autohint/ahloader.h @@ -58,4 +58,4 @@ FT_END_HEADER #endif /* __AHLOADER_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/autohint/ahmodule.c b/src/libs/freetype2/autohint/ahmodule.c index 0004fa259d..8fce31d618 100644 --- a/src/libs/freetype2/autohint/ahmodule.c +++ b/src/libs/freetype2/autohint/ahmodule.c @@ -4,7 +4,7 @@ /* */ /* Auto-hinting module implementation (declaration). */ /* */ -/* Copyright 2000-2001, 2002 Catharon Productions Inc. */ +/* Copyright 2000-2001, 2002, 2003 Catharon Productions Inc. */ /* Author: David Turner */ /* */ /* This file is part of the Catharon Typography Project and shall only */ @@ -119,7 +119,7 @@ FT_CALLBACK_TABLE_DEF const FT_Module_Class autohint_module_class = { - ft_module_hinter, + FT_MODULE_HINTER, sizeof ( FT_AutoHinterRec ), "autohinter", @@ -134,4 +134,4 @@ }; -/* END */ +/* END */ diff --git a/src/libs/freetype2/autohint/ahmodule.h b/src/libs/freetype2/autohint/ahmodule.h index 627763af8c..43b1dbe983 100644 --- a/src/libs/freetype2/autohint/ahmodule.h +++ b/src/libs/freetype2/autohint/ahmodule.h @@ -39,4 +39,4 @@ FT_END_HEADER #endif /* __AHMODULE_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/autohint/ahoptim.c b/src/libs/freetype2/autohint/ahoptim.c deleted file mode 100644 index 323289ba80..0000000000 --- a/src/libs/freetype2/autohint/ahoptim.c +++ /dev/null @@ -1,882 +0,0 @@ -/***************************************************************************/ -/* */ -/* ahoptim.c */ -/* */ -/* FreeType auto hinting outline optimization (body). */ -/* */ -/* Copyright 2000-2001, 2002 Catharon Productions Inc. */ -/* Author: David Turner */ -/* */ -/* This file is part of the Catharon Typography Project and shall only */ -/* be used, modified, and distributed under the terms of the Catharon */ -/* Open Source License that should come with this file under the name */ -/* `CatharonLicense.txt'. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/* Note that this license is compatible with the FreeType license. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This module is in charge of optimising the outlines produced by the */ - /* auto-hinter in direct mode. This is required at small pixel sizes in */ - /* order to ensure coherent spacing, among other things.. */ - /* */ - /* The technique used in this module is a simplified simulated */ - /* annealing. */ - /* */ - /*************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_OBJECTS_H /* for FT_ALLOC_ARRAY() and FT_FREE() */ -#include "ahoptim.h" - - - /* define this macro to use brute force optimization -- this is slow, */ - /* but a good way to perfect the distortion function `by hand' through */ - /* tweaking */ -#define AH_BRUTE_FORCE - - -#define xxxAH_DEBUG_OPTIM - - -#undef LOG -#ifdef AH_DEBUG_OPTIM - -#define LOG( x ) optim_log ## x - -#else - -#define LOG( x ) - -#endif /* AH_DEBUG_OPTIM */ - - -#ifdef AH_DEBUG_OPTIM - -#include <stdarg.h> -#include <stdlib.h> - -#define FLOAT( x ) ( (float)( (x) / 64.0 ) ) - - - static void - optim_log( const char* fmt, ... ) - { - va_list ap; - - - va_start( ap, fmt ); - vprintf( fmt, ap ); - va_end( ap ); - } - - - static void - AH_Dump_Stems( AH_Optimizer* optimizer ) - { - int n; - AH_Stem* stem; - - - stem = optimizer->stems; - for ( n = 0; n < optimizer->num_stems; n++, stem++ ) - { - LOG(( " %c%2d [%.1f:%.1f]={%.1f:%.1f}=" - "<%1.f..%1.f> force=%.1f speed=%.1f\n", - optimizer->vertical ? 'V' : 'H', n, - FLOAT( stem->edge1->opos ), FLOAT( stem->edge2->opos ), - FLOAT( stem->edge1->pos ), FLOAT( stem->edge2->pos ), - FLOAT( stem->min_pos ), FLOAT( stem->max_pos ), - FLOAT( stem->force ), FLOAT( stem->velocity ) )); - } - } - - - static void - AH_Dump_Stems2( AH_Optimizer* optimizer ) - { - int n; - AH_Stem* stem; - - - stem = optimizer->stems; - for ( n = 0; n < optimizer->num_stems; n++, stem++ ) - { - LOG(( " %c%2d [%.1f]=<%1.f..%1.f> force=%.1f speed=%.1f\n", - optimizer->vertical ? 'V' : 'H', n, - FLOAT( stem->pos ), - FLOAT( stem->min_pos ), FLOAT( stem->max_pos ), - FLOAT( stem->force ), FLOAT( stem->velocity ) )); - } - } - - - static void - AH_Dump_Springs( AH_Optimizer* optimizer ) - { - int n; - AH_Spring* spring; - AH_Stem* stems; - - - spring = optimizer->springs; - stems = optimizer->stems; - LOG(( "%cSprings ", optimizer->vertical ? 'V' : 'H' )); - - for ( n = 0; n < optimizer->num_springs; n++, spring++ ) - { - LOG(( " [%d-%d:%.1f:%1.f:%.1f]", - spring->stem1 - stems, spring->stem2 - stems, - FLOAT( spring->owidth ), - FLOAT( spring->stem2->pos - - ( spring->stem1->pos + spring->stem1->width ) ), - FLOAT( spring->tension ) )); - } - - LOG(( "\n" )); - } - -#endif /* AH_DEBUG_OPTIM */ - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** COMPUTE STEMS AND SPRINGS IN AN OUTLINE ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - static int - valid_stem_segments( AH_Segment seg1, - AH_Segment seg2 ) - { - return seg1->serif == 0 && - seg2 && - seg2->link == seg1 && - seg1->pos < seg2->pos && - seg1->min_coord <= seg2->max_coord && - seg2->min_coord <= seg1->max_coord; - } - - - /* compute all stems in an outline */ - static int - optim_compute_stems( AH_Optimizer* optimizer ) - { - AH_Outline outline = optimizer->outline; - FT_Fixed scale; - FT_Memory memory = optimizer->memory; - FT_Error error = 0; - FT_Int dimension; - AH_Edge edges; - AH_Edge edge_limit; - AH_Stem** p_stems; - FT_Int* p_num_stems; - - - edges = outline->horz_edges; - edge_limit = edges + outline->num_hedges; - scale = outline->y_scale; - - p_stems = &optimizer->horz_stems; - p_num_stems = &optimizer->num_hstems; - - for ( dimension = 1; dimension >= 0; dimension-- ) - { - AH_Stem* stems = 0; - FT_Int num_stems = 0; - AH_Edge edge; - - - /* first of all, count the number of stems in this direction */ - for ( edge = edges; edge < edge_limit; edge++ ) - { - AH_Segment seg = edge->first; - - - do - { - if (valid_stem_segments( seg, seg->link ) ) - num_stems++; - - seg = seg->edge_next; - - } while ( seg != edge->first ); - } - - /* now allocate the stems and build their table */ - if ( num_stems > 0 ) - { - AH_Stem* stem; - - - if ( FT_NEW_ARRAY( stems, num_stems ) ) - goto Exit; - - stem = stems; - for ( edge = edges; edge < edge_limit; edge++ ) - { - AH_Segment seg = edge->first; - AH_Segment seg2; - - - do - { - seg2 = seg->link; - if ( valid_stem_segments( seg, seg2 ) ) - { - AH_Edge edge1 = seg->edge; - AH_Edge edge2 = seg2->edge; - - - stem->edge1 = edge1; - stem->edge2 = edge2; - stem->opos = edge1->opos; - stem->pos = edge1->pos; - stem->owidth = edge2->opos - edge1->opos; - stem->width = edge2->pos - edge1->pos; - - /* compute min_coord and max_coord */ - { - FT_Pos min_coord = seg->min_coord; - FT_Pos max_coord = seg->max_coord; - - - if ( seg2->min_coord > min_coord ) - min_coord = seg2->min_coord; - - if ( seg2->max_coord < max_coord ) - max_coord = seg2->max_coord; - - stem->min_coord = min_coord; - stem->max_coord = max_coord; - } - - /* compute minimum and maximum positions for stem -- */ - /* note that the left-most/bottom-most stem has always */ - /* a fixed position */ - if ( stem == stems || edge1->blue_edge || edge2->blue_edge ) - { - /* this stem cannot move; it is snapped to a blue edge */ - stem->min_pos = stem->pos; - stem->max_pos = stem->pos; - } - else - { - /* this edge can move; compute its min and max positions */ - FT_Pos pos1 = stem->opos; - FT_Pos pos2 = pos1 + stem->owidth - stem->width; - FT_Pos min1 = pos1 & -64; - FT_Pos min2 = pos2 & -64; - - - stem->min_pos = min1; - stem->max_pos = min1 + 64; - if ( min2 < min1 ) - stem->min_pos = min2; - else - stem->max_pos = min2 + 64; - - /* XXX: just to see what it does */ - stem->max_pos += 64; - - /* just for the case where direct hinting did some */ - /* incredible things (e.g. blue edge shifts) */ - if ( stem->min_pos > stem->pos ) - stem->min_pos = stem->pos; - - if ( stem->max_pos < stem->pos ) - stem->max_pos = stem->pos; - } - - stem->velocity = 0; - stem->force = 0; - - stem++; - } - seg = seg->edge_next; - - } while ( seg != edge->first ); - } - } - - *p_stems = stems; - *p_num_stems = num_stems; - - edges = outline->vert_edges; - edge_limit = edges + outline->num_vedges; - scale = outline->x_scale; - - p_stems = &optimizer->vert_stems; - p_num_stems = &optimizer->num_vstems; - } - - Exit: - -#ifdef AH_DEBUG_OPTIM - AH_Dump_Stems( optimizer ); -#endif - - return error; - } - - - /* returns the spring area between two stems, 0 if none */ - static FT_Pos - stem_spring_area( AH_Stem* stem1, - AH_Stem* stem2 ) - { - FT_Pos area1 = stem1->max_coord - stem1->min_coord; - FT_Pos area2 = stem2->max_coord - stem2->min_coord; - FT_Pos min = stem1->min_coord; - FT_Pos max = stem1->max_coord; - FT_Pos area; - - - /* order stems */ - if ( stem2->opos <= stem1->opos + stem1->owidth ) - return 0; - - if ( min < stem2->min_coord ) - min = stem2->min_coord; - - if ( max < stem2->max_coord ) - max = stem2->max_coord; - - area = ( max-min ); - if ( 2 * area < area1 && 2 * area < area2 ) - area = 0; - - return area; - } - - - /* compute all springs in an outline */ - static int - optim_compute_springs( AH_Optimizer* optimizer ) - { - /* basically, a spring exists between two stems if most of their */ - /* surface is aligned */ - FT_Memory memory = optimizer->memory; - - AH_Stem* stems; - AH_Stem* stem_limit; - AH_Stem* stem; - int dimension; - int error = 0; - - FT_Int* p_num_springs; - AH_Spring** p_springs; - - - stems = optimizer->horz_stems; - stem_limit = stems + optimizer->num_hstems; - - p_springs = &optimizer->horz_springs; - p_num_springs = &optimizer->num_hsprings; - - for ( dimension = 1; dimension >= 0; dimension-- ) - { - FT_Int num_springs = 0; - AH_Spring* springs = 0; - - - /* first of all, count stem springs */ - for ( stem = stems; stem + 1 < stem_limit; stem++ ) - { - AH_Stem* stem2; - - - for ( stem2 = stem+1; stem2 < stem_limit; stem2++ ) - if ( stem_spring_area( stem, stem2 ) ) - num_springs++; - } - - /* then allocate and build the springs table */ - if ( num_springs > 0 ) - { - AH_Spring* spring; - - - /* allocate table of springs */ - if ( FT_NEW_ARRAY( springs, num_springs ) ) - goto Exit; - - /* fill the springs table */ - spring = springs; - for ( stem = stems; stem+1 < stem_limit; stem++ ) - { - AH_Stem* stem2; - FT_Pos area; - - - for ( stem2 = stem + 1; stem2 < stem_limit; stem2++ ) - { - area = stem_spring_area( stem, stem2 ); - if ( area ) - { - /* add a new spring here */ - spring->stem1 = stem; - spring->stem2 = stem2; - spring->owidth = stem2->opos - ( stem->opos + stem->owidth ); - spring->tension = 0; - - spring++; - } - } - } - } - *p_num_springs = num_springs; - *p_springs = springs; - - stems = optimizer->vert_stems; - stem_limit = stems + optimizer->num_vstems; - - p_springs = &optimizer->vert_springs; - p_num_springs = &optimizer->num_vsprings; - } - - Exit: - -#ifdef AH_DEBUG_OPTIM - AH_Dump_Springs( optimizer ); -#endif - - return error; - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** OPTIMIZE THROUGH MY STRANGE SIMULATED ANNEALING ALGO ;-) ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - -#ifndef AH_BRUTE_FORCE - - /* compute all spring tensions */ - static void - optim_compute_tensions( AH_Optimizer* optimizer ) - { - AH_Spring* spring = optimizer->springs; - AH_Spring* limit = spring + optimizer->num_springs; - - - for ( ; spring < limit; spring++ ) - { - AH_Stem* stem1 = spring->stem1; - AH_Stem* stem2 = spring->stem2; - FT_Int status; - - FT_Pos width; - FT_Pos tension; - FT_Pos sign; - - - /* compute the tension; it simply is -K*(new_width-old_width) */ - width = stem2->pos - ( stem1->pos + stem1->width ); - tension = width - spring->owidth; - - sign = 1; - if ( tension < 0 ) - { - sign = -1; - tension = -tension; - } - - if ( width <= 0 ) - tension = 32000; - else - tension = ( tension << 10 ) / width; - - tension = -sign * FT_MulFix( tension, optimizer->tension_scale ); - spring->tension = tension; - - /* now, distribute tension among the englobing stems, if they */ - /* are able to move */ - status = 0; - if ( stem1->pos <= stem1->min_pos ) - status |= 1; - if ( stem2->pos >= stem2->max_pos ) - status |= 2; - - if ( !status ) - tension /= 2; - - if ( ( status & 1 ) == 0 ) - stem1->force -= tension; - - if ( ( status & 2 ) == 0 ) - stem2->force += tension; - } - } - - - /* compute all stem movements -- returns 0 if nothing moved */ - static int - optim_compute_stem_movements( AH_Optimizer* optimizer ) - { - AH_Stem* stems = optimizer->stems; - AH_Stem* limit = stems + optimizer->num_stems; - AH_Stem* stem = stems; - int moved = 0; - - - /* set initial forces to velocity */ - for ( stem = stems; stem < limit; stem++ ) - { - stem->force = stem->velocity; - stem->velocity /= 2; /* XXX: Heuristics */ - } - - /* compute the sum of forces applied on each stem */ - optim_compute_tensions( optimizer ); - -#ifdef AH_DEBUG_OPTIM - AH_Dump_Springs( optimizer ); - AH_Dump_Stems2( optimizer ); -#endif - - /* now, see whether something can move */ - for ( stem = stems; stem < limit; stem++ ) - { - if ( stem->force > optimizer->tension_threshold ) - { - /* there is enough tension to move the stem to the right */ - if ( stem->pos < stem->max_pos ) - { - stem->pos += 64; - stem->velocity = stem->force / 2; - moved = 1; - } - else - stem->velocity = 0; - } - else if ( stem->force < optimizer->tension_threshold ) - { - /* there is enough tension to move the stem to the left */ - if ( stem->pos > stem->min_pos ) - { - stem->pos -= 64; - stem->velocity = stem->force / 2; - moved = 1; - } - else - stem->velocity = 0; - } - } - - /* return 0 if nothing moved */ - return moved; - } - -#endif /* AH_BRUTE_FORCE */ - - - /* compute current global distortion from springs */ - static FT_Pos - optim_compute_distortion( AH_Optimizer* optimizer ) - { - AH_Spring* spring = optimizer->springs; - AH_Spring* limit = spring + optimizer->num_springs; - FT_Pos distortion = 0; - - - for ( ; spring < limit; spring++ ) - { - AH_Stem* stem1 = spring->stem1; - AH_Stem* stem2 = spring->stem2; - FT_Pos width; - - width = stem2->pos - ( stem1->pos + stem1->width ); - width -= spring->owidth; - if ( width < 0 ) - width = -width; - - distortion += width; - } - - return distortion; - } - - - /* record stems configuration in `best of' history */ - static void - optim_record_configuration( AH_Optimizer* optimizer ) - { - FT_Pos distortion; - AH_Configuration* configs = optimizer->configs; - AH_Configuration* limit = configs + optimizer->num_configs; - AH_Configuration* config; - - - distortion = optim_compute_distortion( optimizer ); - LOG(( "config distortion = %.1f ", FLOAT( distortion * 64 ) )); - - /* check that we really need to add this configuration to our */ - /* sorted history */ - if ( limit > configs && limit[-1].distortion < distortion ) - { - LOG(( "ejected\n" )); - return; - } - - /* add new configuration at the end of the table */ - { - int n; - - - config = limit; - if ( optimizer->num_configs < AH_MAX_CONFIGS ) - optimizer->num_configs++; - else - config--; - - config->distortion = distortion; - - for ( n = 0; n < optimizer->num_stems; n++ ) - config->positions[n] = optimizer->stems[n].pos; - } - - /* move the current configuration towards the front of the list */ - /* when necessary -- yes this is slow bubble sort ;-) */ - while ( config > configs && config[0].distortion < config[-1].distortion ) - { - AH_Configuration temp; - - - config--; - temp = config[0]; - config[0] = config[1]; - config[1] = temp; - } - LOG(( "recorded!\n" )); - } - - -#ifdef AH_BRUTE_FORCE - - /* optimize outline in a single direction */ - static void - optim_compute( AH_Optimizer* optimizer ) - { - int n; - FT_Bool moved; - - AH_Stem* stem = optimizer->stems; - AH_Stem* limit = stem + optimizer->num_stems; - - - /* empty, exit */ - if ( stem >= limit ) - return; - - optimizer->num_configs = 0; - - stem = optimizer->stems; - for ( ; stem < limit; stem++ ) - stem->pos = stem->min_pos; - - do - { - /* record current configuration */ - optim_record_configuration( optimizer ); - - /* now change configuration */ - moved = 0; - for ( stem = optimizer->stems; stem < limit; stem++ ) - { - if ( stem->pos < stem->max_pos ) - { - stem->pos += 64; - moved = 1; - break; - } - - stem->pos = stem->min_pos; - } - } while ( moved ); - - /* now, set the best stem positions */ - for ( n = 0; n < optimizer->num_stems; n++ ) - { - AH_Stem* stem = optimizer->stems + n; - FT_Pos pos = optimizer->configs[0].positions[n]; - - - stem->edge1->pos = pos; - stem->edge2->pos = pos + stem->width; - - stem->edge1->flags |= AH_EDGE_DONE; - stem->edge2->flags |= AH_EDGE_DONE; - } - } - -#else /* AH_BRUTE_FORCE */ - - /* optimize outline in a single direction */ - static void - optim_compute( AH_Optimizer* optimizer ) - { - int n, counter, counter2; - - - optimizer->num_configs = 0; - optimizer->tension_scale = 0x80000L; - optimizer->tension_threshold = 64; - - /* record initial configuration threshold */ - optim_record_configuration( optimizer ); - - counter = 0; - for ( counter2 = optimizer->num_stems*8; counter2 >= 0; counter2-- ) - { - if ( counter == 0 ) - counter = 2 * optimizer->num_stems; - - if ( !optim_compute_stem_movements( optimizer ) ) - break; - - optim_record_configuration( optimizer ); - - counter--; - if ( counter == 0 ) - optimizer->tension_scale /= 2; - } - - /* now, set the best stem positions */ - for ( n = 0; n < optimizer->num_stems; n++ ) - { - AH_Stem* stem = optimizer->stems + n; - FT_Pos pos = optimizer->configs[0].positions[n]; - - - stem->edge1->pos = pos; - stem->edge2->pos = pos + stem->width; - - stem->edge1->flags |= AH_EDGE_DONE; - stem->edge2->flags |= AH_EDGE_DONE; - } - } - -#endif /* AH_BRUTE_FORCE */ - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** HIGH-LEVEL OPTIMIZER API ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /* releases the optimization data */ - void - AH_Optimizer_Done( AH_Optimizer* optimizer ) - { - if ( optimizer ) - { - FT_Memory memory = optimizer->memory; - - - FT_FREE( optimizer->horz_stems ); - FT_FREE( optimizer->vert_stems ); - FT_FREE( optimizer->horz_springs ); - FT_FREE( optimizer->vert_springs ); - FT_FREE( optimizer->positions ); - } - } - - - /* loads the outline into the optimizer */ - int - AH_Optimizer_Init( AH_Optimizer* optimizer, - AH_Outline outline, - FT_Memory memory ) - { - FT_Error error; - - - FT_MEM_ZERO( optimizer, sizeof ( *optimizer ) ); - optimizer->outline = outline; - optimizer->memory = memory; - - LOG(( "initializing new optimizer\n" )); - /* compute stems and springs */ - error = optim_compute_stems ( optimizer ) || - optim_compute_springs( optimizer ); - if ( error ) - goto Fail; - - /* allocate stem positions history and configurations */ - { - int n, max_stems; - - - max_stems = optimizer->num_hstems; - if ( max_stems < optimizer->num_vstems ) - max_stems = optimizer->num_vstems; - - if ( FT_NEW_ARRAY( optimizer->positions, max_stems * AH_MAX_CONFIGS ) ) - goto Fail; - - optimizer->num_configs = 0; - for ( n = 0; n < AH_MAX_CONFIGS; n++ ) - optimizer->configs[n].positions = optimizer->positions + - n * max_stems; - } - - return error; - - Fail: - AH_Optimizer_Done( optimizer ); - return error; - } - - - /* compute optimal outline */ - void - AH_Optimizer_Compute( AH_Optimizer* optimizer ) - { - optimizer->num_stems = optimizer->num_hstems; - optimizer->stems = optimizer->horz_stems; - optimizer->num_springs = optimizer->num_hsprings; - optimizer->springs = optimizer->horz_springs; - - if ( optimizer->num_springs > 0 ) - { - LOG(( "horizontal optimization ------------------------\n" )); - optim_compute( optimizer ); - } - - optimizer->num_stems = optimizer->num_vstems; - optimizer->stems = optimizer->vert_stems; - optimizer->num_springs = optimizer->num_vsprings; - optimizer->springs = optimizer->vert_springs; - - if ( optimizer->num_springs ) - { - LOG(( "vertical optimization --------------------------\n" )); - optim_compute( optimizer ); - } - } - - -/* END */ diff --git a/src/libs/freetype2/autohint/ahoptim.h b/src/libs/freetype2/autohint/ahoptim.h deleted file mode 100644 index 49cd528c58..0000000000 --- a/src/libs/freetype2/autohint/ahoptim.h +++ /dev/null @@ -1,137 +0,0 @@ -/***************************************************************************/ -/* */ -/* ahoptim.h */ -/* */ -/* FreeType auto hinting outline optimization (declaration). */ -/* */ -/* Copyright 2000-2001 Catharon Productions Inc. */ -/* Author: David Turner */ -/* */ -/* This file is part of the Catharon Typography Project and shall only */ -/* be used, modified, and distributed under the terms of the Catharon */ -/* Open Source License that should come with this file under the name */ -/* `CatharonLicense.txt'. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/* Note that this license is compatible with the FreeType license. */ -/* */ -/***************************************************************************/ - - -#ifndef __AHOPTIM_H__ -#define __AHOPTIM_H__ - - -#include <ft2build.h> -#include "ahtypes.h" - - -FT_BEGIN_HEADER - - - /* the maximal number of stem configurations to record */ - /* during optimization */ -#define AH_MAX_CONFIGS 8 - - - typedef struct AH_Stem_ - { - FT_Pos pos; /* current position */ - FT_Pos velocity; /* current velocity */ - FT_Pos force; /* sum of current forces */ - FT_Pos width; /* normalized width */ - - FT_Pos min_pos; /* minimum grid position */ - FT_Pos max_pos; /* maximum grid position */ - - AH_Edge edge1; /* left/bottom edge */ - AH_Edge edge2; /* right/top edge */ - - FT_Pos opos; /* original position */ - FT_Pos owidth; /* original width */ - - FT_Pos min_coord; /* minimum coordinate */ - FT_Pos max_coord; /* maximum coordinate */ - - } AH_Stem; - - - /* A spring between two stems */ - typedef struct AH_Spring_ - { - AH_Stem* stem1; - AH_Stem* stem2; - FT_Pos owidth; /* original width */ - FT_Pos tension; /* current tension */ - - } AH_Spring; - - - /* A configuration records the position of each stem at a given time */ - /* as well as the associated distortion */ - typedef struct AH_Configuration_ - { - FT_Pos* positions; - FT_Long distortion; - - } AH_Configuration; - - - typedef struct AH_Optimizer_ - { - FT_Memory memory; - AH_Outline outline; - - FT_Int num_hstems; - AH_Stem* horz_stems; - - FT_Int num_vstems; - AH_Stem* vert_stems; - - FT_Int num_hsprings; - FT_Int num_vsprings; - AH_Spring* horz_springs; - AH_Spring* vert_springs; - - FT_Int num_configs; - AH_Configuration configs[AH_MAX_CONFIGS]; - FT_Pos* positions; - - /* during each pass, use these instead */ - FT_Int num_stems; - AH_Stem* stems; - - FT_Int num_springs; - AH_Spring* springs; - FT_Bool vertical; - - FT_Fixed tension_scale; - FT_Pos tension_threshold; - - } AH_Optimizer; - - - /* loads the outline into the optimizer */ - int - AH_Optimizer_Init( AH_Optimizer* optimizer, - AH_Outline outline, - FT_Memory memory ); - - - /* compute optimal outline */ - void - AH_Optimizer_Compute( AH_Optimizer* optimizer ); - - - /* release the optimization data */ - void - AH_Optimizer_Done( AH_Optimizer* optimizer ); - - -FT_END_HEADER - -#endif /* __AHOPTIM_H__ */ - - -/* END */ diff --git a/src/libs/freetype2/autohint/ahtypes.h b/src/libs/freetype2/autohint/ahtypes.h index 04d7484ab6..f2cedd2887 100644 --- a/src/libs/freetype2/autohint/ahtypes.h +++ b/src/libs/freetype2/autohint/ahtypes.h @@ -5,7 +5,7 @@ /* General types and definitions for the auto-hint module */ /* (specification only). */ /* */ -/* Copyright 2000-2001, 2002 Catharon Productions Inc. */ +/* Copyright 2000-2001, 2002, 2003, 2004 Catharon Productions Inc. */ /* Author: David Turner */ /* */ /* This file is part of the Catharon Typography Project and shall only */ @@ -76,16 +76,6 @@ FT_BEGIN_HEADER #undef AH_OPTION_NO_WEAK_INTERPOLATION - /*************************************************************************/ - /* */ - /* If this option is defined, only weak interpolation will be used to */ - /* place the points between edges. Otherwise, `strong' points are */ - /* detected and later hinted through strong interpolation to correct */ - /* some unpleasant artefacts. */ - /* */ -#undef AH_OPTION_NO_STRONG_INTERPOLATION - - /*************************************************************************/ /* */ /* Undefine this macro if you don't want to hint the metrics. There is */ @@ -121,7 +111,7 @@ FT_BEGIN_HEADER /*************************************************************************/ - /* see agangles.h */ + /* see ahangles.h */ typedef FT_Int AH_Angle; @@ -201,10 +191,6 @@ FT_BEGIN_HEADER /* */ /* out_dir :: The direction of the outwards vector (point->next). */ /* */ - /* in_angle :: The angle of the inwards vector. */ - /* */ - /* out_angle :: The angle of the outwards vector. */ - /* */ /* next :: The next point in same contour. */ /* */ /* prev :: The previous point in same contour. */ @@ -220,9 +206,6 @@ FT_BEGIN_HEADER AH_Direction in_dir; /* direction of inwards vector */ AH_Direction out_dir; /* direction of outwards vector */ - AH_Angle in_angle; - AH_Angle out_angle; - AH_Point next; /* next point in contour */ AH_Point prev; /* previous point in contour */ @@ -244,16 +227,9 @@ FT_BEGIN_HEADER /* */ /* dir :: The segment direction. */ /* */ - /* first :: The first point in the segment. */ + /* min_coord :: The minimum coordinate of the segment. */ /* */ - /* last :: The last point in the segment. */ - /* */ - /* contour :: A pointer to the first point of the segment's */ - /* contour. */ - /* */ - /* pos :: The segment position in font units. */ - /* */ - /* size :: The segment size. */ + /* max_coord :: The maximum coordinate of the segment. */ /* */ /* edge :: The edge of the current segment. */ /* */ @@ -267,15 +243,17 @@ FT_BEGIN_HEADER /* */ /* score :: Used to score the segment when selecting them. */ /* */ + /* first :: The first point in the segment. */ + /* */ + /* last :: The last point in the segment. */ + /* */ + /* contour :: A pointer to the first point of the segment's */ + /* contour. */ + /* */ typedef struct AH_SegmentRec_ { AH_Edge_Flags flags; AH_Direction dir; - - AH_Point first; /* first point in edge segment */ - AH_Point last; /* last point in edge segment */ - AH_Point* contour; /* ptr to first point of segment's contour */ - FT_Pos pos; /* position of segment */ FT_Pos min_coord; /* minimum coordinate of segment */ FT_Pos max_coord; /* maximum coordinate of segment */ @@ -288,6 +266,10 @@ FT_BEGIN_HEADER FT_Pos num_linked; /* number of linked segments */ FT_Pos score; + AH_Point first; /* first point in edge segment */ + AH_Point last; /* last point in edge segment */ + AH_Point* contour; /* ptr to first point of segment's contour */ + } AH_SegmentRec; @@ -302,50 +284,55 @@ FT_BEGIN_HEADER /* located on it. */ /* */ /* <Fields> */ - /* flags :: The segment edge flags (straight, rounded, etc.). */ - /* */ - /* dir :: The main segment direction on this edge. */ - /* */ - /* first :: The first edge segment. */ - /* */ - /* last :: The last edge segment. */ - /* */ /* fpos :: The original edge position in font units. */ /* */ /* opos :: The original scaled edge position. */ /* */ /* pos :: The hinted edge position. */ /* */ + /* flags :: The segment edge flags (straight, rounded, etc.). */ + /* */ + /* dir :: The main segment direction on this edge. */ + /* */ + /* scale :: Scaling factor between original and hinted edge */ + /* positions. */ + /* */ + /* blue_edge :: Indicate the blue zone edge this edge is related to. */ + /* Only set for some of the horizontal edges in a latin */ + /* font. */ + /* */ /* link :: The linked edge. */ /* */ /* serif :: The serif edge. */ /* */ - /* num_paired :: The number of other edges that pair to this one. */ + /* num_linked :: The number of other edges that pair to this one. */ /* */ /* score :: Used to score the edge when selecting them. */ /* */ - /* blue_edge :: Indicate the blue zone edge this edge is related to. */ - /* Only set for some of the horizontal edges in a Latin */ - /* font. */ + /* first :: The first edge segment. */ + /* */ + /* last :: The last edge segment. */ /* */ typedef struct AH_EdgeRec_ { - AH_Edge_Flags flags; - AH_Direction dir; - - AH_Segment first; - AH_Segment last; - FT_Pos fpos; FT_Pos opos; FT_Pos pos; + AH_Edge_Flags flags; + AH_Direction dir; + FT_Fixed scale; + FT_Pos* blue_edge; + AH_Edge link; AH_Edge serif; FT_Int num_linked; FT_Int score; - FT_Pos* blue_edge; + + AH_Segment first; + AH_Segment last; + } AH_EdgeRec; @@ -368,7 +355,7 @@ FT_BEGIN_HEADER FT_Int max_contours; FT_Int num_contours; - AH_Point * contours; + AH_Point* contours; FT_Int num_hedges; AH_Edge horz_edges; @@ -387,24 +374,24 @@ FT_BEGIN_HEADER #ifdef FT_CONFIG_CHESTER_SMALL_F -# define AH_BLUE_CAPITAL_TOP 0 /* THEZOCQS */ -# define AH_BLUE_CAPITAL_BOTTOM ( AH_BLUE_CAPITAL_TOP + 1 ) /* HEZLOCUS */ -# define AH_BLUE_SMALL_F_TOP ( AH_BLUE_CAPITAL_BOTTOM + 1 ) /* fijkdbh */ -# define AH_BLUE_SMALL_TOP ( AH_BLUE_SMALL_F_TOP + 1 ) /* xzroesc */ -# define AH_BLUE_SMALL_BOTTOM ( AH_BLUE_SMALL_TOP + 1 ) /* xzroesc */ -# define AH_BLUE_SMALL_MINOR ( AH_BLUE_SMALL_BOTTOM + 1 ) /* pqgjy */ -# define AH_BLUE_MAX ( AH_BLUE_SMALL_MINOR + 1 ) +#define AH_BLUE_CAPITAL_TOP 0 /* THEZOCQS */ +#define AH_BLUE_CAPITAL_BOTTOM ( AH_BLUE_CAPITAL_TOP + 1 ) /* HEZLOCUS */ +#define AH_BLUE_SMALL_F_TOP ( AH_BLUE_CAPITAL_BOTTOM + 1 ) /* fijkdbh */ +#define AH_BLUE_SMALL_TOP ( AH_BLUE_SMALL_F_TOP + 1 ) /* xzroesc */ +#define AH_BLUE_SMALL_BOTTOM ( AH_BLUE_SMALL_TOP + 1 ) /* xzroesc */ +#define AH_BLUE_SMALL_MINOR ( AH_BLUE_SMALL_BOTTOM + 1 ) /* pqgjy */ +#define AH_BLUE_MAX ( AH_BLUE_SMALL_MINOR + 1 ) -#else /* !CHESTER_SMALL_F */ +#else /* !FT_CONFIG_CHESTER_SMALL_F */ -# define AH_BLUE_CAPITAL_TOP 0 /* THEZOCQS */ -# define AH_BLUE_CAPITAL_BOTTOM ( AH_BLUE_CAPITAL_TOP + 1 ) /* HEZLOCUS */ -# define AH_BLUE_SMALL_TOP ( AH_BLUE_CAPITAL_BOTTOM + 1) /* xzroesc */ -# define AH_BLUE_SMALL_BOTTOM ( AH_BLUE_SMALL_TOP + 1 ) /* xzroesc */ -# define AH_BLUE_SMALL_MINOR ( AH_BLUE_SMALL_BOTTOM + 1 ) /* pqgjy */ -# define AH_BLUE_MAX ( AH_BLUE_SMALL_MINOR + 1 ) +#define AH_BLUE_CAPITAL_TOP 0 /* THEZOCQS */ +#define AH_BLUE_CAPITAL_BOTTOM ( AH_BLUE_CAPITAL_TOP + 1 ) /* HEZLOCUS */ +#define AH_BLUE_SMALL_TOP ( AH_BLUE_CAPITAL_BOTTOM + 1 ) /* xzroesc */ +#define AH_BLUE_SMALL_BOTTOM ( AH_BLUE_SMALL_TOP + 1 ) /* xzroesc */ +#define AH_BLUE_SMALL_MINOR ( AH_BLUE_SMALL_BOTTOM + 1 ) /* pqgjy */ +#define AH_BLUE_MAX ( AH_BLUE_SMALL_MINOR + 1 ) -#endif /* !CHESTER_SMALL_F */ +#endif /* !FT_CONFIG_CHESTER_SMALL_F */ typedef FT_Int AH_Blue; @@ -429,6 +416,9 @@ FT_BEGIN_HEADER /* */ /* num_heights :: The number of heights. */ /* */ + /* stds :: A two-element array giving the default stem width */ + /* and height. */ + /* */ /* widths :: Snap widths, including standard one. */ /* */ /* heights :: Snap height, including standard one. */ @@ -474,6 +464,9 @@ FT_BEGIN_HEADER /* */ /* y_scale :: The current vertical scale. */ /* */ + /* control_overshoot :: */ + /* Currently unused. */ + /* */ typedef struct AH_Face_GlobalsRec_ { FT_Face face; @@ -486,39 +479,40 @@ FT_BEGIN_HEADER } AH_Face_GlobalsRec, *AH_Face_Globals; - typedef struct AH_HinterRec + typedef struct AH_HinterRec_ { - FT_Memory memory; - AH_Hinter_Flags flags; + FT_Memory memory; + AH_Hinter_Flags flags; - FT_Int algorithm; - FT_Face face; + FT_Int algorithm; + FT_Face face; - AH_Face_Globals globals; + AH_Face_Globals globals; - AH_Outline glyph; + AH_Outline glyph; - AH_Loader loader; - FT_Vector pp1; - FT_Vector pp2; + AH_Loader loader; + FT_Vector pp1; /* horizontal phantom points */ + FT_Vector pp2; + /* we ignore vertical phantom points */ - FT_Bool transformed; - FT_Vector trans_delta; - FT_Matrix trans_matrix; + FT_Bool transformed; + FT_Vector trans_delta; + FT_Matrix trans_matrix; - FT_Bool do_horz_hints; /* disable X hinting */ - FT_Bool do_vert_hints; /* disable Y hinting */ - FT_Bool do_horz_snapping; /* disable X stem size snapping */ - FT_Bool do_vert_snapping; /* disable Y stem size snapping */ - FT_Bool do_stem_adjust; /* disable light stem snapping */ + FT_Bool do_horz_hints; /* disable X hinting */ + FT_Bool do_vert_hints; /* disable Y hinting */ + FT_Bool do_horz_snapping; /* disable X stem size snapping */ + FT_Bool do_vert_snapping; /* disable Y stem size snapping */ + FT_Bool do_stem_adjust; /* disable light stem snapping */ } AH_HinterRec, *AH_Hinter; -#ifdef DEBUG_HINTER - extern AH_Hinter ah_debug_hinter; - extern FT_Bool ah_debug_disable_horz; - extern FT_Bool ah_debug_disable_vert; +#ifdef DEBUG_HINTER + extern AH_Hinter ah_debug_hinter; + extern FT_Bool ah_debug_disable_horz; + extern FT_Bool ah_debug_disable_vert; #else #define ah_debug_disable_horz 0 #define ah_debug_disable_vert 0 @@ -530,4 +524,4 @@ FT_END_HEADER #endif /* __AHTYPES_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/autohint/autohint.c b/src/libs/freetype2/autohint/autohint.c index 44a44797cb..3783a82d96 100644 --- a/src/libs/freetype2/autohint/autohint.c +++ b/src/libs/freetype2/autohint/autohint.c @@ -29,4 +29,4 @@ #include "ahmodule.c" -/* END */ +/* END */ diff --git a/src/libs/freetype2/autohint/mather.py b/src/libs/freetype2/autohint/mather.py index abae0a224a..8ad8b55359 100644 --- a/src/libs/freetype2/autohint/mather.py +++ b/src/libs/freetype2/autohint/mather.py @@ -75,4 +75,4 @@ print_arctan( 8 ) print -# END +# END diff --git a/src/libs/freetype2/autohint/module.mk b/src/libs/freetype2/autohint/module.mk index 930dfcbfb0..edc9f4e1af 100644 --- a/src/libs/freetype2/autohint/module.mk +++ b/src/libs/freetype2/autohint/module.mk @@ -22,4 +22,4 @@ add_autohint_module: $(OPEN_DRIVER)autohint_module_class$(CLOSE_DRIVER) $(ECHO_DRIVER)autohint $(ECHO_DRIVER_DESC)automatic hinting module$(ECHO_DRIVER_DONE) -# EOF +# EOF diff --git a/src/libs/freetype2/autohint/rules.mk b/src/libs/freetype2/autohint/rules.mk index 2cbf6c1710..ee264e8622 100644 --- a/src/libs/freetype2/autohint/rules.mk +++ b/src/libs/freetype2/autohint/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2000, 2001 Catharon Productions Inc. +# Copyright 2000, 2001, 2002, 2003 Catharon Productions Inc. # Author: David Turner # # This file is part of the Catharon Typography Project and shall only @@ -18,29 +18,28 @@ # AUTO driver directory # -AUTO_DIR := $(SRC_)autohint -AUTO_DIR_ := $(AUTO_DIR)$(SEP) +AUTO_DIR := $(SRC_DIR)/autohint # compilation flags for the driver # -AUTO_COMPILE := $(FT_COMPILE) $I$(AUTO_DIR) +AUTO_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(AUTO_DIR)) # AUTO driver sources (i.e., C files) # -AUTO_DRV_SRC := $(AUTO_DIR_)ahangles.c \ - $(AUTO_DIR_)ahglobal.c \ - $(AUTO_DIR_)ahglyph.c \ - $(AUTO_DIR_)ahhint.c \ - $(AUTO_DIR_)ahmodule.c +AUTO_DRV_SRC := $(AUTO_DIR)/ahangles.c \ + $(AUTO_DIR)/ahglobal.c \ + $(AUTO_DIR)/ahglyph.c \ + $(AUTO_DIR)/ahhint.c \ + $(AUTO_DIR)/ahmodule.c # AUTO driver headers # AUTO_DRV_H := $(AUTO_DRV_SRC:%c=%h) \ - $(AUTO_DIR_)ahloader.h \ - $(AUTO_DIR_)ahtypes.h \ - $(AUTO_DIR_)aherrors.h + $(AUTO_DIR)/ahloader.h \ + $(AUTO_DIR)/ahtypes.h \ + $(AUTO_DIR)/aherrors.h # AUTO driver object(s) @@ -48,25 +47,25 @@ AUTO_DRV_H := $(AUTO_DRV_SRC:%c=%h) \ # AUTO_DRV_OBJ_M is used during `multi' builds. # AUTO_DRV_OBJ_S is used during `single' builds. # -AUTO_DRV_OBJ_M := $(AUTO_DRV_SRC:$(AUTO_DIR_)%.c=$(OBJ_)%.$O) -AUTO_DRV_OBJ_S := $(OBJ_)autohint.$O +AUTO_DRV_OBJ_M := $(AUTO_DRV_SRC:$(AUTO_DIR)/%.c=$(OBJ_DIR)/%.$O) +AUTO_DRV_OBJ_S := $(OBJ_DIR)/autohint.$O # AUTO driver source file for single build # -AUTO_DRV_SRC_S := $(AUTO_DIR_)autohint.c +AUTO_DRV_SRC_S := $(AUTO_DIR)/autohint.c # AUTO driver - single object # $(AUTO_DRV_OBJ_S): $(AUTO_DRV_SRC_S) $(AUTO_DRV_SRC) \ $(FREETYPE_H) $(AUTO_DRV_H) - $(AUTO_COMPILE) $T$@ $(AUTO_DRV_SRC_S) + $(AUTO_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(AUTO_DRV_SRC_S)) # AUTO driver - multiple objects # -$(OBJ_)%.$O: $(AUTO_DIR_)%.c $(FREETYPE_H) $(AUTO_DRV_H) - $(AUTO_COMPILE) $T$@ $< +$(OBJ_DIR)/%.$O: $(AUTO_DIR)/%.c $(FREETYPE_H) $(AUTO_DRV_H) + $(AUTO_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) # update main driver object lists @@ -75,4 +74,4 @@ DRV_OBJS_S += $(AUTO_DRV_OBJ_S) DRV_OBJS_M += $(AUTO_DRV_OBJ_M) -# EOF +# EOF diff --git a/src/libs/freetype2/base/Jamfile b/src/libs/freetype2/base/Jamfile index 51b300b768..345444ba10 100644 --- a/src/libs/freetype2/base/Jamfile +++ b/src/libs/freetype2/base/Jamfile @@ -11,7 +11,7 @@ UseFreeTypeHeaders ; if $(FT2_MULTI) { _sources = ftutil ftdbgmem ftstream ftcalc fttrigon ftgloadr ftoutln - ftobjs ftnames ; + ftobjs ftnames ftrfork ; } else { @@ -24,9 +24,8 @@ UseFreeTypeHeaders ; # Add the optional/replaceable files. # FT2_Library $(FT2_LIB) : ftsystem.c ftinit.c ftglyph.c ftmm.c ftbdf.c - ftbbox.c ftdebug.c ftxf86.c fttype1.c ftpfr.c - ftstroker.c ftwinfnt.c - ; + ftbbox.c ftdebug.c ftxf86.c fttype1.c ftpfr.c + ftstroke.c ftwinfnt.c ; # Add Macintosh-specific file to the library when necessary. # @@ -35,4 +34,5 @@ if $(MAC) FT2_Library $(FT2_LIB) : ftmac.c ; } -# end of src/base Jamfile +# end of src/base Jamfile + diff --git a/src/libs/freetype2/base/descrip.mms b/src/libs/freetype2/base/descrip.mms index 5926830d0f..73bad4d738 100644 --- a/src/libs/freetype2/base/descrip.mms +++ b/src/libs/freetype2/base/descrip.mms @@ -3,7 +3,7 @@ # -# Copyright 2001 by +# Copyright 2001, 2003, 2004 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -15,9 +15,9 @@ CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.builds.vms],[--.include],[--.src.base]) -OBJS=ftbase.obj,ftinit.obj,ftglyph.obj,ftdebug.obj,ftbdf.obj,ftmm.obj,fttype1.obj,ftxf86.obj,ftpfr.obj,ftstroker.obj,ftwinfnt.obj +OBJS=ftbase.obj,ftinit.obj,ftglyph.obj,ftdebug.obj,ftbdf.obj,ftmm.obj,fttype1.obj,ftxf86.obj,ftpfr.obj,ftstroke.obj,ftwinfnt.obj,ftbbox.obj all : $(OBJS) library [--.lib]freetype.olb $(OBJS) -# EOF +# EOF diff --git a/src/libs/freetype2/base/ftapi.c b/src/libs/freetype2/base/ftapi.c index c6a9d522be..1ef3005e28 100644 --- a/src/libs/freetype2/base/ftapi.c +++ b/src/libs/freetype2/base/ftapi.c @@ -118,4 +118,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/base/ftbase.c b/src/libs/freetype2/base/ftbase.c index 4f564fcace..7d5a7fd8e8 100644 --- a/src/libs/freetype2/base/ftbase.c +++ b/src/libs/freetype2/base/ftbase.c @@ -4,7 +4,7 @@ /* */ /* Single object library component (body only). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -29,6 +29,10 @@ #include "ftgloadr.c" #include "ftobjs.c" #include "ftnames.c" +#include "ftrfork.c" +#if defined( __APPLE__ ) && !defined ( DARWIN_NO_CARBON ) +#include "ftmac.c" +#endif -/* END */ +/* END */ diff --git a/src/libs/freetype2/base/ftbbox.c b/src/libs/freetype2/base/ftbbox.c index 3f15848d1a..f71c9f0dbf 100644 --- a/src/libs/freetype2/base/ftbbox.c +++ b/src/libs/freetype2/base/ftbbox.c @@ -98,9 +98,9 @@ static void BBox_Conic_Check( FT_Pos y1, FT_Pos y2, - FT_Pos y3, - FT_Pos* min, - FT_Pos* max ) + FT_Pos y3, + FT_Pos* min, + FT_Pos* max ) { if ( y1 <= y3 ) { @@ -650,4 +650,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/base/ftbdf.c b/src/libs/freetype2/base/ftbdf.c index 8557ef7343..d2f133db77 100644 --- a/src/libs/freetype2/base/ftbdf.c +++ b/src/libs/freetype2/base/ftbdf.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing BDF-specific strings (body). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,24 +17,8 @@ #include <ft2build.h> -#include FT_INTERNAL_BDF_TYPES_H #include FT_INTERNAL_OBJECTS_H - - static FT_Bool - test_font_type( FT_Face face, const char* name ) - { - if ( face && face->driver ) - { - FT_Module driver = (FT_Module)face->driver; - - if ( driver->clazz && driver->clazz->module_name ) - { - if ( ft_strcmp( driver->clazz->module_name, name ) == 0 ) - return 1; - } - } - return 0; - } +#include FT_SERVICE_BDF_H FT_EXPORT_DEF( FT_Error ) @@ -49,14 +33,15 @@ error = FT_Err_Invalid_Argument; - if ( test_font_type( face, "bdf" ) ) + if ( face ) { - BDF_Public_Face bdf_face = (BDF_Public_Face)face; + FT_Service_BDF service; - encoding = (const char*) bdf_face->charset_encoding; - registry = (const char*) bdf_face->charset_registry; - error = 0; + FT_FACE_FIND_SERVICE( face, service, BDF ); + + if ( service && service->get_charset_id ) + error = service->get_charset_id( face, &encoding, ®istry ); } if ( acharset_encoding ) @@ -74,23 +59,26 @@ const char* prop_name, BDF_PropertyRec *aproperty ) { - FT_Error error; + FT_Error error; + error = FT_Err_Invalid_Argument; aproperty->type = BDF_PROPERTY_TYPE_NONE; - if ( face != NULL && face->driver != NULL ) + if ( face ) { - FT_Driver driver = face->driver; - BDF_GetPropertyFunc func; + FT_Service_BDF service; - func = (BDF_GetPropertyFunc) driver->root.clazz->get_interface( - FT_MODULE( driver ), "get_bdf_property" ); - if ( func ) - error = func( face, prop_name, aproperty ); + + FT_FACE_FIND_SERVICE( face, service, BDF ); + + if ( service && service->get_property ) + error = service->get_property( face, prop_name, aproperty ); } - return error; + + return error; } -/* END */ + +/* END */ diff --git a/src/libs/freetype2/base/ftcalc.c b/src/libs/freetype2/base/ftcalc.c index b964a7e969..f169642e0b 100644 --- a/src/libs/freetype2/base/ftcalc.c +++ b/src/libs/freetype2/base/ftcalc.c @@ -4,7 +4,7 @@ /* */ /* Arithmetic computations (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -74,8 +74,8 @@ FT_EXPORT_DEF( FT_Fixed ) FT_RoundFix( FT_Fixed a ) { - return ( a >= 0 ) ? ( a + 0x8000L ) & -0x10000L - : -((-a + 0x8000L ) & -0x10000L ); + return ( a >= 0 ) ? ( a + 0x8000L ) & ~0xFFFFL + : -((-a + 0x8000L ) & ~0xFFFFL ); } @@ -84,8 +84,8 @@ FT_EXPORT_DEF( FT_Fixed ) FT_CeilFix( FT_Fixed a ) { - return ( a >= 0 ) ? ( a + 0xFFFFL ) & -0x10000L - : -((-a + 0xFFFFL ) & -0x10000L ); + return ( a >= 0 ) ? ( a + 0xFFFFL ) & ~0xFFFFL + : -((-a + 0xFFFFL ) & ~0xFFFFL ); } @@ -94,8 +94,8 @@ FT_EXPORT_DEF( FT_Fixed ) FT_FloorFix( FT_Fixed a ) { - return ( a >= 0 ) ? a & -0x10000L - : -((-a) & -0x10000L ); + return ( a >= 0 ) ? a & ~0xFFFFL + : -((-a) & ~0xFFFFL ); } @@ -155,6 +155,33 @@ } +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + + /* documentation is in ftcalc.h */ + + FT_BASE_DEF( FT_Long ) + FT_MulDiv_No_Round( FT_Long a, + FT_Long b, + FT_Long c ) + { + FT_Int s; + FT_Long d; + + + s = 1; + if ( a < 0 ) { a = -a; s = -1; } + if ( b < 0 ) { b = -b; s = -s; } + if ( c < 0 ) { c = -c; s = -s; } + + d = (FT_Long)( c > 0 ? (FT_Int64)a * b / c + : 0x7FFFFFFFL ); + + return ( s > 0 ) ? d : -d; + } + +#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ + + /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_Long ) @@ -168,7 +195,7 @@ if ( a < 0 ) { a = -a; s = -1; } if ( b < 0 ) { b = -b; s = -s; } - c = (FT_Long)( ( (FT_Int64)a * b + 0x8000 ) >> 16 ); + c = (FT_Long)( ( (FT_Int64)a * b + 0x8000L ) >> 16 ); return ( s > 0 ) ? c : -c ; } @@ -298,14 +325,13 @@ if ( a == 0 || b == c ) return a; - s = a; a = ABS( a ); - s ^= b; b = ABS( b ); - s ^= c; c = ABS( c ); + s = a; a = FT_ABS( a ); + s ^= b; b = FT_ABS( b ); + s ^= c; c = FT_ABS( c ); if ( a <= 46340L && b <= 46340L && c <= 176095L && c > 0 ) - { a = ( a * b + ( c >> 1 ) ) / c; - } + else if ( c > 0 ) { FT_Int64 temp, temp2; @@ -325,6 +351,43 @@ } +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + + FT_BASE_DEF( FT_Long ) + FT_MulDiv_No_Round( FT_Long a, + FT_Long b, + FT_Long c ) + { + long s; + + + if ( a == 0 || b == c ) + return a; + + s = a; a = FT_ABS( a ); + s ^= b; b = FT_ABS( b ); + s ^= c; c = FT_ABS( c ); + + if ( a <= 46340L && b <= 46340L && c > 0 ) + a = a * b / c; + + else if ( c > 0 ) + { + FT_Int64 temp; + + + ft_multo64( a, b, &temp ); + a = ft_div64by32( temp.hi, temp.lo, c ); + } + else + a = 0x7FFFFFFFL; + + return ( s < 0 ? -a : a ); + } + +#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ + + /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_Long ) @@ -338,23 +401,23 @@ if ( a == 0 || b == 0x10000L ) return a; - s = a; a = ABS(a); - s ^= b; b = ABS(b); + s = a; a = FT_ABS(a); + s ^= b; b = FT_ABS(b); ua = (FT_ULong)a; ub = (FT_ULong)b; if ( ua <= 2048 && ub <= 1048576L ) { - ua = ( ua * ub + 0x8000 ) >> 16; + ua = ( ua * ub + 0x8000L ) >> 16; } else { - FT_ULong al = ua & 0xFFFF; + FT_ULong al = ua & 0xFFFFL; ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) + - ( ( al * ( ub & 0xFFFF ) + 0x8000 ) >> 16 ); + ( ( al * ( ub & 0xFFFFL ) + 0x8000L ) >> 16 ); } return ( s < 0 ? -(FT_Long)ua : (FT_Long)ua ); @@ -371,8 +434,8 @@ FT_UInt32 q; - s = a; a = ABS(a); - s ^= b; b = ABS(b); + s = a; a = FT_ABS(a); + s ^= b; b = FT_ABS(b); if ( b == 0 ) { @@ -411,8 +474,8 @@ FT_Int32 s; - s = x; x = ABS( x ); - s ^= y; y = ABS( y ); + s = x; x = FT_ABS( x ); + s ^= y; y = FT_ABS( y ); ft_multo64( x, y, z ); @@ -445,7 +508,7 @@ x->lo = (FT_UInt32)-(FT_Int32)x->lo; x->hi = ~x->hi + !x->lo; } - s ^= y; y = ABS( y ); + s ^= y; y = FT_ABS( y ); /* Shortcut */ if ( x->hi == 0 ) @@ -499,7 +562,7 @@ x->lo = (FT_UInt32)-(FT_Int32)x->lo; x->hi = ~x->hi + !x->lo; } - s ^= y; y = ABS( y ); + s ^= y; y = FT_ABS( y ); /* Shortcut */ if ( x->hi == 0 ) @@ -558,4 +621,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/base/ftdbgmem.c b/src/libs/freetype2/base/ftdbgmem.c index 1cf4798252..152220c605 100644 --- a/src/libs/freetype2/base/ftdbgmem.c +++ b/src/libs/freetype2/base/ftdbgmem.c @@ -4,7 +4,7 @@ /* */ /* Memory debugger (body). */ /* */ -/* Copyright 2001, 2002 by */ +/* Copyright 2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -604,7 +604,7 @@ p = getenv( "FT2_ALLOC_TOTAL_MAX" ); if ( p != NULL ) { - FT_Long total_max = atol(p); + FT_Long total_max = ft_atol(p); if ( total_max > 0 ) { @@ -616,7 +616,7 @@ p = getenv( "FT2_ALLOC_COUNT_MAX" ); if ( p != NULL ) { - FT_Long total_count = atol(p); + FT_Long total_count = ft_atol(p); if ( total_count > 0 ) { @@ -715,4 +715,4 @@ #endif /* !FT_DEBUG_MEMORY */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/base/ftdebug.c b/src/libs/freetype2/base/ftdebug.c index 8bad5d5f8e..a6c18412b8 100644 --- a/src/libs/freetype2/base/ftdebug.c +++ b/src/libs/freetype2/base/ftdebug.c @@ -4,7 +4,7 @@ /* */ /* Debugging and logging component (body). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2001, 2002, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -82,8 +82,9 @@ /* array of trace levels, initialized to 0 */ int ft_trace_levels[trace_count]; + /* define array of trace toggle names */ -#define FT_TRACE_DEF(x) #x , +#define FT_TRACE_DEF( x ) #x , static const char* ft_trace_toggles[trace_count + 1] = { @@ -94,19 +95,43 @@ #undef FT_TRACE_DEF + /* documentation is in ftdebug.h */ + + FT_EXPORT_DEF( FT_Int ) + FT_Trace_Get_Count( void ) + { + return trace_count; + } + + + /* documentation is in ftdebug.h */ + + FT_EXPORT_DEF( const char * ) + FT_Trace_Get_Name( FT_Int idx ) + { + int max = FT_Trace_Get_Count(); + + + if ( idx < max ) + return ft_trace_toggles[idx]; + else + return NULL; + } + + /*************************************************************************/ /* */ /* Initialize the tracing sub-system. This is done by retrieving the */ - /* value of the "FT2_DEBUG" environment variable. It must be a list of */ - /* toggles, separated by spaces, `;' or `,'. Example: */ + /* value of the `FT2_DEBUG' environment variable. It must be a list of */ + /* toggles, separated by spaces, `;', or `,'. Example: */ /* */ - /* "any:3 memory:6 stream:5" */ + /* export FT2_DEBUG="any:3 memory:6 stream:5" */ /* */ - /* This will request that all levels be set to 3, except the trace level */ - /* for the memory and stream components which are set to 6 and 5, */ + /* This requests that all levels be set to 3, except the trace level for */ + /* the memory and stream components which are set to 6 and 5, */ /* respectively. */ /* */ - /* See the file <freetype/internal/fttrace.h> for details of the */ + /* See the file <include/freetype/internal/fttrace.h> for details of the */ /* available toggle names. */ /* */ /* The level must be between 0 and 6; 0 means quiet (except for serious */ @@ -117,6 +142,7 @@ { const char* ft2_debug = getenv( "FT2_DEBUG" ); + if ( ft2_debug ) { const char* p = ft2_debug; @@ -133,10 +159,10 @@ q = p; while ( *p && *p != ':' ) p++; - + if ( *p == ':' && p > q ) { - FT_Int n, i, len = (FT_Int)(p - q); + FT_Int n, i, len = (FT_Int)( p - q ); FT_Int level = -1, found = -1; @@ -171,7 +197,7 @@ { if ( found == trace_any ) { - /* special case for "any" */ + /* special case for `any' */ for ( n = 0; n < trace_count; n++ ) ft_trace_levels[n] = level; } @@ -183,15 +209,34 @@ } } + #else /* !FT_DEBUG_LEVEL_TRACE */ + FT_BASE_DEF( void ) ft_debug_init( void ) { /* nothing */ } + + FT_EXPORT_DEF( FT_Int ) + FT_Trace_Get_Count( void ) + { + return 0; + } + + + FT_EXPORT_DEF( const char * ) + FT_Trace_Get_Name( FT_Int idx ) + { + FT_UNUSED( idx ); + + return NULL; + } + + #endif /* !FT_DEBUG_LEVEL_TRACE */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/base/ftgloadr.c b/src/libs/freetype2/base/ftgloadr.c index ecee77f4a7..0308f713c8 100644 --- a/src/libs/freetype2/base/ftgloadr.c +++ b/src/libs/freetype2/base/ftgloadr.c @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph loader (body). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,6 +19,7 @@ #include <ft2build.h> #include FT_INTERNAL_GLYPH_LOADER_H #include FT_INTERNAL_MEMORY_H +#include FT_INTERNAL_OBJECTS_H #undef FT_COMPONENT #define FT_COMPONENT trace_gloader @@ -205,7 +206,7 @@ if ( new_max > old_max ) { - new_max = ( new_max + 7 ) & -8; + new_max = FT_PAD_CEIL( new_max, 8 ); if ( FT_RENEW_ARRAY( base->points, old_max, new_max ) || FT_RENEW_ARRAY( base->tags, old_max, new_max ) ) @@ -225,7 +226,7 @@ n_contours; if ( new_max > old_max ) { - new_max = ( new_max + 3 ) & -4; + new_max = FT_PAD_CEIL( new_max, 4 ); if ( FT_RENEW_ARRAY( base->contours, old_max, new_max ) ) goto Exit; @@ -261,7 +262,7 @@ old_max = loader->max_subglyphs; if ( new_max > old_max ) { - new_max = ( new_max + 1 ) & -2; + new_max = FT_PAD_CEIL( new_max, 2 ); if ( FT_RENEW_ARRAY( base->subglyphs, old_max, new_max ) ) goto Exit; @@ -336,17 +337,17 @@ FT_Outline* in = &source->base.outline; - FT_MEM_COPY( out->points, in->points, - num_points * sizeof ( FT_Vector ) ); - FT_MEM_COPY( out->tags, in->tags, - num_points * sizeof ( char ) ); - FT_MEM_COPY( out->contours, in->contours, - num_contours * sizeof ( short ) ); + FT_ARRAY_COPY( out->points, in->points, + num_points ); + FT_ARRAY_COPY( out->tags, in->tags, + num_points ); + FT_ARRAY_COPY( out->contours, in->contours, + num_contours ); /* do we need to copy the extra points? */ if ( target->use_extra && source->use_extra ) - FT_MEM_COPY( target->base.extra_points, source->base.extra_points, - num_points * sizeof ( FT_Vector ) ); + FT_ARRAY_COPY( target->base.extra_points, source->base.extra_points, + num_points ); out->n_points = (short)num_points; out->n_contours = (short)num_contours; @@ -358,4 +359,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/base/ftglyph.c b/src/libs/freetype2/base/ftglyph.c index 4615fe0de4..c6c458cc16 100644 --- a/src/libs/freetype2/base/ftglyph.c +++ b/src/libs/freetype2/base/ftglyph.c @@ -4,7 +4,7 @@ /* */ /* FreeType convenience functions to handle glyphs (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -57,7 +57,7 @@ FT_EXPORT_DEF( void ) FT_Matrix_Multiply( const FT_Matrix* a, - FT_Matrix* b ) + FT_Matrix *b ) { FT_Fixed xx, xy, yx, yy; @@ -158,8 +158,8 @@ glyph->left = slot->bitmap_left; glyph->top = slot->bitmap_top; - if ( slot->flags & FT_GLYPH_OWN_BITMAP ) - slot->flags &= ~FT_GLYPH_OWN_BITMAP; + if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) + slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; else { /* copy the bitmap into a new buffer */ @@ -206,6 +206,7 @@ } + FT_CALLBACK_TABLE_DEF const FT_Glyph_Class ft_bitmap_glyph_class = { sizeof( FT_BitmapGlyphRec ), @@ -253,14 +254,11 @@ goto Exit; /* copy it */ - FT_MEM_COPY( target->points, source->points, - source->n_points * sizeof ( FT_Vector ) ); + FT_ARRAY_COPY( target->points, source->points, source->n_points ); - FT_MEM_COPY( target->tags, source->tags, - source->n_points * sizeof ( FT_Byte ) ); + FT_ARRAY_COPY( target->tags, source->tags, source->n_points ); - FT_MEM_COPY( target->contours, source->contours, - source->n_contours * sizeof ( FT_Short ) ); + FT_ARRAY_COPY( target->contours, source->contours, source->n_contours ); /* copy all flags, except the `FT_OUTLINE_OWNER' one */ target->flags = source->flags | FT_OUTLINE_OWNER; @@ -327,6 +325,7 @@ } + FT_CALLBACK_TABLE_DEF const FT_Glyph_Class ft_outline_glyph_class = { sizeof( FT_OutlineGlyphRec ), @@ -421,7 +420,7 @@ FT_Get_Glyph( FT_GlyphSlot slot, FT_Glyph *aglyph ) { - FT_Library library = slot->library; + FT_Library library; FT_Error error; FT_Glyph glyph; @@ -431,6 +430,8 @@ if ( !slot ) return FT_Err_Invalid_Slot_Handle; + library = slot->library; + if ( !aglyph ) return FT_Err_Invalid_Argument; @@ -541,16 +542,18 @@ clazz->glyph_bbox( glyph, acbox ); /* perform grid fitting if needed */ - if ( bbox_mode & ft_glyph_bbox_gridfit ) + if ( bbox_mode == FT_GLYPH_BBOX_GRIDFIT || + bbox_mode == FT_GLYPH_BBOX_PIXELS ) { - acbox->xMin &= -64; - acbox->yMin &= -64; - acbox->xMax = ( acbox->xMax + 63 ) & -64; - acbox->yMax = ( acbox->yMax + 63 ) & -64; + acbox->xMin = FT_PIX_FLOOR( acbox->xMin ); + acbox->yMin = FT_PIX_FLOOR( acbox->yMin ); + acbox->xMax = FT_PIX_CEIL( acbox->xMax ); + acbox->yMax = FT_PIX_CEIL( acbox->yMax ); } /* convert to integer pixels if needed */ - if ( bbox_mode & ft_glyph_bbox_truncate ) + if ( bbox_mode == FT_GLYPH_BBOX_TRUNCATE || + bbox_mode == FT_GLYPH_BBOX_PIXELS ) { acbox->xMin >>= 6; acbox->yMin >>= 6; @@ -571,12 +574,13 @@ FT_Vector* origin, FT_Bool destroy ) { - FT_GlyphSlotRec dummy; - FT_Error error = FT_Err_Ok; - FT_Glyph glyph; - FT_BitmapGlyph bitmap = NULL; + FT_GlyphSlotRec dummy; + FT_GlyphSlot_InternalRec dummy_internal; + FT_Error error = FT_Err_Ok; + FT_Glyph glyph; + FT_BitmapGlyph bitmap = NULL; - const FT_Glyph_Class* clazz; + const FT_Glyph_Class* clazz; /* check argument */ @@ -592,7 +596,7 @@ clazz = glyph->clazz; - /* when called with a bitmap glyph, do nothing and return succesfully */ + /* when called with a bitmap glyph, do nothing and return successfully */ if ( clazz == &ft_bitmap_glyph_class ) goto Exit; @@ -600,8 +604,10 @@ goto Bad; FT_MEM_ZERO( &dummy, sizeof ( dummy ) ); - dummy.library = glyph->library; - dummy.format = clazz->glyph_format; + FT_MEM_ZERO( &dummy_internal, sizeof ( dummy_internal ) ); + dummy.internal = &dummy_internal; + dummy.library = glyph->library; + dummy.format = clazz->glyph_format; /* create result bitmap glyph */ error = ft_new_glyph( glyph->library, &ft_bitmap_glyph_class, @@ -609,7 +615,7 @@ if ( error ) goto Exit; -#if 0 +#if 1 /* if `origin' is set, translate the glyph image */ if ( origin ) FT_Glyph_Transform( glyph, 0, origin ); @@ -622,7 +628,7 @@ if ( !error ) error = FT_Render_Glyph_Internal( glyph->library, &dummy, render_mode ); -#if 0 +#if 1 if ( !destroy && origin ) { FT_Vector v; @@ -681,4 +687,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/base/fthash.c b/src/libs/freetype2/base/fthash.c index 7108098201..c42b1dcf4b 100644 --- a/src/libs/freetype2/base/fthash.c +++ b/src/libs/freetype2/base/fthash.c @@ -243,4 +243,4 @@ } Exit: return error; - } + } diff --git a/src/libs/freetype2/base/ftinit.c b/src/libs/freetype2/base/ftinit.c index 12b1234dbf..79ba9f0bd2 100644 --- a/src/libs/freetype2/base/ftinit.c +++ b/src/libs/freetype2/base/ftinit.c @@ -158,4 +158,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/base/ftlist.c b/src/libs/freetype2/base/ftlist.c index 110746528f..52687b361d 100644 --- a/src/libs/freetype2/base/ftlist.c +++ b/src/libs/freetype2/base/ftlist.c @@ -214,4 +214,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/base/ftmac.c b/src/libs/freetype2/base/ftmac.c index 59fabcd478..c714753827 100644 --- a/src/libs/freetype2/base/ftmac.c +++ b/src/libs/freetype2/base/ftmac.c @@ -4,7 +4,7 @@ /* */ /* Mac FOND support. Written by just@letterror.com. */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -62,15 +62,28 @@ #include <ft2build.h> #include FT_FREETYPE_H #include FT_INTERNAL_STREAM_H + +#ifdef __GNUC__ +#include "../truetype/ttobjs.h" +#include "../type1/t1objs.h" + /* This is for Mac OS X. Without redefinition, OS_INLINE */ + /* expands to `static inline' which doesn't survive the */ + /* -ansi compilation flag of GCC. */ +#define OS_INLINE static __inline__ +#include <Carbon/Carbon.h> +#else #include "truetype/ttobjs.h" #include "type1/t1objs.h" - #include <Resources.h> #include <Fonts.h> #include <Errors.h> #include <Files.h> #include <TextUtils.h> +#endif +#if defined( __MWERKS__ ) && !TARGET_RT_MAC_MACHO +#include <FSp_fopen.h> +#endif #include FT_MAC_H @@ -82,12 +95,50 @@ #define PREFER_LWFN 1 #endif + +#if defined( __MWERKS__ ) && !TARGET_RT_MAC_MACHO + +#define STREAM_FILE( stream ) ( (FILE*)stream->descriptor.pointer ) + + + FT_CALLBACK_DEF( void ) + ft_FSp_stream_close( FT_Stream stream ) + { + fclose( STREAM_FILE( stream ) ); + + stream->descriptor.pointer = NULL; + stream->size = 0; + stream->base = 0; + } + + + FT_CALLBACK_DEF( unsigned long ) + ft_FSp_stream_io( FT_Stream stream, + unsigned long offset, + unsigned char* buffer, + unsigned long count ) + { + FILE* file; + + + file = STREAM_FILE( stream ); + + fseek( file, offset, SEEK_SET ); + + return (unsigned long)fread( buffer, 1, count, file ); + } + +#endif /* __MWERKS__ && !TARGET_RT_MAC_MACHO */ + + /* Given a pathname, fill in a file spec. */ static int file_spec_from_path( const char* pathname, FSSpec* spec ) { -#if TARGET_API_MAC_CARBON + +#if !TARGET_API_MAC_OS8 && \ + !( defined( __MWERKS__ ) && !TARGET_RT_MAC_MACHO ) OSErr e; FSRef ref; @@ -118,12 +169,13 @@ return 0; #endif + } /* Return the file type of the file specified by spec. */ static OSType - get_file_type( FSSpec* spec ) + get_file_type( const FSSpec* spec ) { FInfo finfo; @@ -135,22 +187,6 @@ } -#if TARGET_API_MAC_CARBON - - /* is this a Mac OS X .dfont file */ - static Boolean - is_dfont( FSSpec* spec ) - { - int nameLen = spec->name[0]; - - - return nameLen >= 6 && - !memcmp( spec->name + nameLen - 5, ".dfont", 6 ); - } - -#endif - - /* Given a PostScript font name, create the Macintosh LWFN file name. */ static void create_lwfn_name( char* ps_name, @@ -165,7 +201,7 @@ while ( *q ) { - if ( isupper( *q ) ) + if ( ft_isupper( *q ) ) { if ( count ) max = 3; @@ -212,9 +248,9 @@ /* Make a file spec for an LWFN file from a FOND resource and a file name. */ static FT_Error - make_lwfn_spec( Handle fond, - unsigned char* file_name, - FSSpec* spec ) + make_lwfn_spec( Handle fond, + const unsigned char* file_name, + FSSpec* spec ) { FT_Error error; short ref_num, v_ref_num; @@ -235,12 +271,24 @@ } + static short + count_faces_sfnt( char *fond_data ) + { + /* The count is 1 greater than the value in the FOND. */ + /* Isn't that cute? :-) */ + + return 1 + *( (short *)( fond_data + sizeof ( FamRec ) ) ); + } + + /* Look inside the FOND data, answer whether there should be an SFNT resource, and answer the name of a possible LWFN Type 1 file. Thanks to Paul Miller (paulm@profoundeffects.com) for the fix to load a face OTHER than the first one in the FOND! */ + + static void parse_fond( char* fond_data, short* have_sfnt, @@ -260,19 +308,24 @@ fond = (FamRec*)fond_data; assoc = (AsscEntry*)( fond_data + sizeof ( FamRec ) + 2 ); base_assoc = assoc; - assoc += face_index; /* add on the face_index! */ - /* if the face at this index is not scalable, - fall back to the first one (old behavior) */ - if ( assoc->fontSize == 0 ) + /* Let's do a little range checking before we get too excited here */ + if ( face_index < count_faces_sfnt( fond_data ) ) { - *have_sfnt = 1; - *sfnt_id = assoc->fontID; - } - else if ( base_assoc->fontSize == 0 ) - { - *have_sfnt = 1; - *sfnt_id = base_assoc->fontID; + assoc += face_index; /* add on the face_index! */ + + /* if the face at this index is not scalable, + fall back to the first one (old behavior) */ + if ( assoc->fontSize == 0 ) + { + *have_sfnt = 1; + *sfnt_id = assoc->fontID; + } + else if ( base_assoc->fontSize == 0 ) + { + *have_sfnt = 1; + *sfnt_id = base_assoc->fontID; + } } if ( fond->ffStylOff ) @@ -304,7 +357,7 @@ if ( ps_name_len != 0 ) { - memcpy(ps_name, names[0] + 1, ps_name_len); + ft_memcpy(ps_name, names[0] + 1, ps_name_len); ps_name[ps_name_len] = 0; } if ( style->indexes[0] > 1 ) @@ -312,7 +365,7 @@ unsigned char* suffixes = names[style->indexes[0] - 1]; - for ( i = 1; i < suffixes[0]; i++ ) + for ( i = 1; i <= suffixes[0]; i++ ) { unsigned char* s; size_t j = suffixes[i] - 1; @@ -325,7 +378,7 @@ if ( s_len != 0 && ps_name_len + s_len < sizeof ( ps_name ) ) { - memcpy( ps_name + ps_name_len, s + 1, s_len ); + ft_memcpy( ps_name + ps_name_len, s + 1, s_len ); ps_name_len += s_len; ps_name[ps_name_len] = 0; } @@ -339,6 +392,33 @@ } + static short + count_faces( Handle fond ) + { + short sfnt_id, have_sfnt, have_lwfn = 0; + Str255 lwfn_file_name; + FSSpec lwfn_spec; + + + HLock( fond ); + parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, 0 ); + HUnlock( fond ); + + if ( lwfn_file_name[0] ) + { + if ( make_lwfn_spec( fond, lwfn_file_name, &lwfn_spec ) == FT_Err_Ok ) + have_lwfn = 1; /* yeah, we got one! */ + else + have_lwfn = 0; /* no LWFN file found */ + } + + if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) ) + return 1; + else + return count_faces_sfnt( *fond ); + } + + /* Read Type 1 data from the POST resources inside the LWFN file, return a PFB buffer. This is somewhat convoluted because the FT2 PFB parser wants the ASCII header as one chunk, and the LWFN @@ -346,12 +426,12 @@ of the same type together. */ static FT_Error read_lwfn( FT_Memory memory, - FSSpec* lwfn_spec, + short res_ref, FT_Byte** pfb_data, FT_ULong* size ) { FT_Error error = FT_Err_Ok; - short res_ref, res_id; + short res_id; unsigned char *buffer, *p, *size_p = NULL; FT_ULong total_size = 0; FT_ULong post_size, pfb_chunk_size; @@ -359,13 +439,10 @@ char code, last_code; - res_ref = FSpOpenResFile( lwfn_spec, fsRdPerm ); - if ( ResError() ) - return FT_Err_Out_Of_Memory; UseResFile( res_ref ); - /* First pass: load all POST resources, and determine the size of - the output buffer. */ + /* First pass: load all POST resources, and determine the size of */ + /* the output buffer. */ res_id = 501; last_code = -1; @@ -392,8 +469,8 @@ if ( FT_ALLOC( buffer, (FT_Long)total_size ) ) goto Error; - /* Second pass: append all POST data to the buffer, add PFB fields. - Glue all consecutive chunks of the same type together. */ + /* Second pass: append all POST data to the buffer, add PFB fields. */ + /* Glue all consecutive chunks of the same type together. */ p = buffer; res_id = 501; last_code = -1; @@ -538,32 +615,75 @@ args.driver = FT_Get_Module( library, driver_name ); } + /* At this point, face_index has served its purpose; */ + /* whoever calls this function has already used it to */ + /* locate the correct font data. We should not propagate */ + /* this index to FT_Open_Face() (unless it is negative). */ + + if ( face_index > 0 ) + face_index = 0; + error = FT_Open_Face( library, &args, face_index, aface ); if ( error == FT_Err_Ok ) (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM; - else - { - FT_Stream_CloseFunc( stream ); - FT_FREE( stream ); - } return error; } + static FT_Error + OpenFileAsResource( const FSSpec* spec, + short *p_res_ref ) + { + FT_Error error; + +#if !TARGET_API_MAC_OS8 + + FSRef hostContainerRef; + + + error = FSpMakeFSRef( spec, &hostContainerRef ); + if ( error == noErr ) + error = FSOpenResourceFile( &hostContainerRef, + 0, NULL, fsRdPerm, p_res_ref ); + + /* If the above fails, then it is probably not a resource file */ + /* However, it has been reported that FSOpenResourceFile() sometimes */ + /* fails on some old resource-fork files, which FSpOpenResFile() can */ + /* open. So, just try again with FSpOpenResFile() and see what */ + /* happens :-) */ + + if ( error != noErr ) + +#endif /* !TARGET_API_MAC_OS8 */ + + { + *p_res_ref = FSpOpenResFile( spec, fsRdPerm ); + error = ResError(); + } + + return error ? FT_Err_Cannot_Open_Resource : FT_Err_Ok; + } + + /* Create a new FT_Face from a file spec to an LWFN file. */ static FT_Error - FT_New_Face_From_LWFN( FT_Library library, - FSSpec* spec, - FT_Long face_index, - FT_Face *aface ) + FT_New_Face_From_LWFN( FT_Library library, + const FSSpec* lwfn_spec, + FT_Long face_index, + FT_Face *aface ) { FT_Byte* pfb_data; FT_ULong pfb_size; FT_Error error; + short res_ref; - error = read_lwfn( library->memory, spec, &pfb_data, &pfb_size ); + error = OpenFileAsResource( lwfn_spec, &res_ref ); + if ( error ) + return error; + + error = read_lwfn( library->memory, res_ref, &pfb_data, &pfb_size ); if ( error ) return error; @@ -588,6 +708,7 @@ size_t sfnt_size; FT_Error error = 0; FT_Memory memory = library->memory; + int is_cff; sfnt = GetResource( 'sfnt', sfnt_id ); @@ -606,11 +727,16 @@ HUnlock( sfnt ); ReleaseResource( sfnt ); + is_cff = sfnt_size > 4 && sfnt_data[0] == 'O' && + sfnt_data[1] == 'T' && + sfnt_data[2] == 'T' && + sfnt_data[3] == 'O'; + return open_face_from_buffer( library, sfnt_data, sfnt_size, face_index, - "truetype", + is_cff ? "cff" : "truetype", aface ); } @@ -618,34 +744,34 @@ /* Create a new FT_Face from a file spec to a suitcase file. */ static FT_Error FT_New_Face_From_Suitcase( FT_Library library, - FSSpec* spec, + short res_ref, FT_Long face_index, FT_Face *aface ) { FT_Error error = FT_Err_Ok; - short res_ref, res_index; + short res_index; Handle fond; + short num_faces; - res_ref = FSpOpenResFile( spec, fsRdPerm ); - if ( ResError() ) - return FT_Err_Cannot_Open_Resource; UseResFile( res_ref ); - /* face_index may be -1, in which case we - just need to do a sanity check */ - if ( face_index < 0 ) - res_index = 1; - else + for ( res_index = 1; ; ++res_index ) { - res_index = (short)( face_index + 1 ); - face_index = 0; - } - fond = Get1IndResource( 'FOND', res_index ); - if ( ResError() ) - { - error = FT_Err_Cannot_Open_Resource; - goto Error; + fond = Get1IndResource( 'FOND', res_index ); + if ( ResError() ) + { + error = FT_Err_Cannot_Open_Resource; + goto Error; + } + if ( face_index < 0 ) + break; + + num_faces = count_faces( fond ); + if ( face_index < num_faces ) + break; + + face_index -= num_faces; } error = FT_New_Face_From_FOND( library, fond, face_index, aface ); @@ -656,57 +782,6 @@ } -#if TARGET_API_MAC_CARBON - - /* Create a new FT_Face from a file spec to a suitcase file. */ - static FT_Error - FT_New_Face_From_dfont( FT_Library library, - FSSpec* spec, - FT_Long face_index, - FT_Face* aface ) - { - FT_Error error = FT_Err_Ok; - short res_ref, res_index; - Handle fond; - FSRef hostContainerRef; - - - error = FSpMakeFSRef( spec, &hostContainerRef ); - if ( error == noErr ) - error = FSOpenResourceFile( &hostContainerRef, - 0, NULL, fsRdPerm, &res_ref ); - - if ( error != noErr ) - return FT_Err_Cannot_Open_Resource; - - UseResFile( res_ref ); - - /* face_index may be -1, in which case we - just need to do a sanity check */ - if ( face_index < 0 ) - res_index = 1; - else - { - res_index = (short)( face_index + 1 ); - face_index = 0; - } - fond = Get1IndResource( 'FOND', res_index ); - if ( ResError() ) - { - error = FT_Err_Cannot_Open_Resource; - goto Error; - } - - error = FT_New_Face_From_FOND( library, fond, face_index, aface ); - - Error: - CloseResFile( res_ref ); - return error; - } - -#endif - - /* documentation is in ftmac.h */ FT_EXPORT_DEF( FT_Error ) @@ -757,9 +832,9 @@ /* documentation is in ftmac.h */ FT_EXPORT_DEF( FT_Error ) - FT_GetFile_From_Mac_Name( char* fontName, - FSSpec* pathSpec, - FT_Long* face_index ) + FT_GetFile_From_Mac_Name( const char* fontName, + FSSpec* pathSpec, + FT_Long* face_index ) { OptionBits options = kFMUseGlobalScopeOption; @@ -820,7 +895,7 @@ the_font = font; } else - ++(*face_index); + ++(*face_index); } } @@ -839,23 +914,46 @@ return FT_Err_Unknown_File_Format; } + /* Common function to load a new FT_Face from a resource file. */ - static long - ResourceForkSize(FSSpec* spec) + static FT_Error + FT_New_Face_From_Resource( FT_Library library, + const FSSpec *spec, + FT_Long face_index, + FT_Face *aface ) { - long len; - short refNum; - OSErr e; + OSType file_type; + short res_ref; + FT_Error error; - e = FSpOpenRF( spec, fsRdPerm, &refNum ); /* I.M. Files 2-155 */ - if ( e == noErr ) + if ( OpenFileAsResource( spec, &res_ref ) == FT_Err_Ok ) { - e = GetEOF( refNum, &len ); - FSClose( refNum ); + /* LWFN is a (very) specific file format, check for it explicitly */ + + file_type = get_file_type( spec ); + if ( file_type == 'LWFN' ) + return FT_New_Face_From_LWFN( library, spec, face_index, aface ); + + /* Otherwise the file type doesn't matter (there are more than */ + /* `FFIL' and `tfil'). Just try opening it as a font suitcase; */ + /* if it works, fine. */ + + error = FT_New_Face_From_Suitcase( library, res_ref, + face_index, aface ); + if ( error == 0 ) + return error; + + /* else forget about the resource fork and fall through to */ + /* data fork formats */ + + CloseResFile( res_ref ); } - return ( e == noErr ) ? len : 0; + /* let it fall through to normal loader (.ttf, .otf, etc.); */ + /* we signal this by returning no error and no FT_Face */ + *aface = NULL; + return 0; } @@ -878,7 +976,7 @@ { FT_Open_Args args; FSSpec spec; - OSType file_type; + FT_Error error; /* test for valid `library' and `aface' delayed to FT_Open_Face() */ @@ -888,26 +986,9 @@ if ( file_spec_from_path( pathname, &spec ) ) return FT_Err_Invalid_Argument; - /* Regardless of type, don't try to use the resource fork if it is */ - /* empty. Some TTF fonts have type `FFIL', for example, but they */ - /* only have data forks. */ - - if ( ResourceForkSize( &spec ) != 0 ) - { - file_type = get_file_type( &spec ); - if ( file_type == 'FFIL' || file_type == 'tfil' ) - return FT_New_Face_From_Suitcase( library, &spec, face_index, aface ); - - if ( file_type == 'LWFN' ) - return FT_New_Face_From_LWFN( library, &spec, face_index, aface ); - } - -#if TARGET_API_MAC_CARBON - - if ( is_dfont( &spec ) ) - return FT_New_Face_From_dfont( library, &spec, face_index, aface ); - -#endif + error = FT_New_Face_From_Resource( library, &spec, face_index, aface ); + if ( error != 0 || *aface != NULL ) + return error; /* let it fall through to normal loader (.ttf, .otf, etc.) */ args.flags = FT_OPEN_PATHNAME; @@ -916,4 +997,96 @@ } -/* END */ + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Face_From_FSSpec */ + /* */ + /* <Description> */ + /* FT_New_Face_From_FSSpec is identical to FT_New_Face except it */ + /* accepts an FSSpec instead of a path. */ + /* */ + FT_EXPORT_DEF( FT_Error ) + FT_New_Face_From_FSSpec( FT_Library library, + const FSSpec *spec, + FT_Long face_index, + FT_Face *aface ) + { + FT_Open_Args args; + FT_Error error; + FT_Stream stream; + FILE* file; + FT_Memory memory; + + + /* test for valid `library' and `aface' delayed to FT_Open_Face() */ + if ( !spec ) + return FT_Err_Invalid_Argument; + + error = FT_New_Face_From_Resource( library, spec, face_index, aface ); + if ( error != 0 || *aface != NULL ) + return error; + + /* let it fall through to normal loader (.ttf, .otf, etc.) */ + +#if defined( __MWERKS__ ) && !TARGET_RT_MAC_MACHO + + /* Codewarrior's C library can open a FILE from a FSSpec */ + /* but we must compile with FSp_fopen.c in addition to */ + /* runtime libraries. */ + + memory = library->memory; + + if ( FT_NEW( stream ) ) + return error; + stream->memory = memory; + + file = FSp_fopen( spec, "rb" ); + if ( !file ) + return FT_Err_Cannot_Open_Resource; + + fseek( file, 0, SEEK_END ); + stream->size = ftell( file ); + fseek( file, 0, SEEK_SET ); + + stream->descriptor.pointer = file; + stream->pathname.pointer = NULL; + stream->pos = 0; + + stream->read = ft_FSp_stream_io; + stream->close = ft_FSp_stream_close; + + args.flags = FT_OPEN_STREAM; + args.stream = stream; + + error = FT_Open_Face( library, &args, face_index, aface ); + if ( error == FT_Err_Ok ) + (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM; + +#else /* !(__MWERKS__ && !TARGET_RT_MAC_MACHO) */ + + { + FSRef ref; + UInt8 path[256]; + OSErr err; + + + err = FSpMakeFSRef(spec, &ref); + if ( !err ) + { + err = FSRefMakePath( &ref, path, sizeof ( path ) ); + if ( !err ) + error = FT_New_Face( library, (const char*)path, + face_index, aface ); + } + if ( err ) + error = FT_Err_Cannot_Open_Resource; + } + +#endif /* !(__MWERKS__ && !TARGET_RT_MAC_MACHO) */ + + return error; + } + + +/* END */ diff --git a/src/libs/freetype2/base/ftmm.c b/src/libs/freetype2/base/ftmm.c index 9bb7065d4b..0bb2813092 100644 --- a/src/libs/freetype2/base/ftmm.c +++ b/src/libs/freetype2/base/ftmm.c @@ -4,7 +4,7 @@ /* */ /* Multiple Master font support (body). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2001, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,6 +19,7 @@ #include <ft2build.h> #include FT_MULTIPLE_MASTERS_H #include FT_INTERNAL_OBJECTS_H +#include FT_SERVICE_MULTIPLE_MASTERS_H /*************************************************************************/ @@ -31,15 +32,15 @@ #define FT_COMPONENT trace_mm - /* documentation is in ftmm.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Get_Multi_Master( FT_Face face, - FT_Multi_Master *amaster ) + static FT_Error + ft_face_get_mm_service( FT_Face face, + FT_Service_MultiMasters *aservice ) { FT_Error error; + *aservice = NULL; + if ( !face ) return FT_Err_Invalid_Face_Handle; @@ -47,14 +48,34 @@ if ( FT_HAS_MULTIPLE_MASTERS( face ) ) { - FT_Driver driver = face->driver; - FT_Get_MM_Func func; + FT_FACE_LOOKUP_SERVICE( face, + *aservice, + MULTI_MASTERS ); + + if ( aservice ) + error = FT_Err_Ok; + } + + return error; + } - func = (FT_Get_MM_Func)driver->root.clazz->get_interface( - FT_MODULE( driver ), "get_mm" ); - if ( func ) - error = func( face, amaster ); + /* documentation is in ftmm.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Multi_Master( FT_Face face, + FT_Multi_Master *amaster ) + { + FT_Error error; + FT_Service_MultiMasters service; + + + error = ft_face_get_mm_service( face, &service ); + if ( !error ) + { + error = FT_Err_Invalid_Argument; + if ( service->get_mm ) + error = service->get_mm( face, amaster ); } return error; @@ -68,24 +89,16 @@ FT_UInt num_coords, FT_Long* coords ) { - FT_Error error; + FT_Error error; + FT_Service_MultiMasters service; - if ( !face ) - return FT_Err_Invalid_Face_Handle; - - error = FT_Err_Invalid_Argument; - - if ( FT_HAS_MULTIPLE_MASTERS( face ) ) + error = ft_face_get_mm_service( face, &service ); + if ( !error ) { - FT_Driver driver = face->driver; - FT_Set_MM_Design_Func func; - - - func = (FT_Set_MM_Design_Func)driver->root.clazz->get_interface( - FT_MODULE( driver ), "set_mm_design" ); - if ( func ) - error = func( face, num_coords, coords ); + error = FT_Err_Invalid_Argument; + if ( service->set_mm_design ) + error = service->set_mm_design( face, num_coords, coords ); } return error; @@ -99,28 +112,20 @@ FT_UInt num_coords, FT_Fixed* coords ) { - FT_Error error; + FT_Error error; + FT_Service_MultiMasters service; - if ( !face ) - return FT_Err_Invalid_Face_Handle; - - error = FT_Err_Invalid_Argument; - - if ( FT_HAS_MULTIPLE_MASTERS( face ) ) + error = ft_face_get_mm_service( face, &service ); + if ( !error ) { - FT_Driver driver = face->driver; - FT_Set_MM_Blend_Func func; - - - func = (FT_Set_MM_Blend_Func)driver->root.clazz->get_interface( - FT_MODULE( driver ), "set_mm_blend" ); - if ( func ) - error = func( face, num_coords, coords ); + error = FT_Err_Invalid_Argument; + if ( service->set_mm_blend ) + error = service->set_mm_blend( face, num_coords, coords ); } return error; } -/* END */ +/* END */ diff --git a/src/libs/freetype2/base/ftnames.c b/src/libs/freetype2/base/ftnames.c index 38098fb2af..7fde5c40bf 100644 --- a/src/libs/freetype2/base/ftnames.c +++ b/src/libs/freetype2/base/ftnames.c @@ -91,4 +91,4 @@ #endif /* TT_CONFIG_OPTION_SFNT_NAMES */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/base/ftobject.c b/src/libs/freetype2/base/ftobject.c index b54b433f50..34e41e943f 100644 --- a/src/libs/freetype2/base/ftobject.c +++ b/src/libs/freetype2/base/ftobject.c @@ -393,4 +393,4 @@ } return error; - } + } diff --git a/src/libs/freetype2/base/ftobjs.c b/src/libs/freetype2/base/ftobjs.c index 4f8f4d1c0e..517e83e42c 100644 --- a/src/libs/freetype2/base/ftobjs.c +++ b/src/libs/freetype2/base/ftobjs.c @@ -4,7 +4,7 @@ /* */ /* The FreeType private base classes (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,12 +21,42 @@ #include FT_OUTLINE_H #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_RFORK_H #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_SFNT_H /* for SFNT_Load_Table_Func */ #include FT_TRUETYPE_TABLES_H #include FT_TRUETYPE_IDS_H #include FT_OUTLINE_H +#include FT_SERVICE_SFNT_H +#include FT_SERVICE_POSTSCRIPT_NAME_H +#include FT_SERVICE_GLYPH_DICT_H +#include FT_SERVICE_TT_CMAP_H + + + FT_BASE_DEF( FT_Pointer ) + ft_service_list_lookup( FT_ServiceDesc service_descriptors, + const char* service_id ) + { + FT_Pointer result = NULL; + FT_ServiceDesc desc = service_descriptors; + + + if ( desc && service_id ) + { + for ( ; desc->serv_id != NULL; desc++ ) + { + if ( ft_strcmp( desc->serv_id, service_id ) == 0 ) + { + result = (FT_Pointer)desc->serv_data; + break; + } + } + } + + return result; + } + FT_BASE_DEF( void ) ft_validator_init( FT_Validator valid, @@ -74,12 +104,12 @@ /*************************************************************************/ - /* create a new input stream from a FT_Open_Args structure */ - /* */ - static FT_Error - ft_input_stream_new( FT_Library library, - const FT_Open_Args* args, - FT_Stream* astream ) + /* create a new input stream from an FT_Open_Args structure */ + /* */ + FT_BASE_DEF( FT_Error ) + FT_Stream_New( FT_Library library, + const FT_Open_Args* args, + FT_Stream *astream ) { FT_Error error; FT_Memory memory; @@ -137,9 +167,9 @@ } - static void - ft_input_stream_free( FT_Stream stream, - FT_Int external ) + FT_BASE_DEF( void ) + FT_Stream_Free( FT_Stream stream, + FT_Int external ) { if ( stream ) { @@ -198,16 +228,17 @@ return error; } + FT_BASE_DEF( void ) ft_glyphslot_free_bitmap( FT_GlyphSlot slot ) { - if ( slot->flags & FT_GLYPH_OWN_BITMAP ) + if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) { FT_Memory memory = FT_FACE_MEMORY( slot->face ); - - + + FT_FREE( slot->bitmap.buffer ); - slot->flags &= ~FT_GLYPH_OWN_BITMAP; + slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; } else { @@ -220,14 +251,14 @@ FT_BASE_DEF( void ) ft_glyphslot_set_bitmap( FT_GlyphSlot slot, - FT_Pointer buffer ) + FT_Byte* buffer ) { ft_glyphslot_free_bitmap( slot ); - + slot->bitmap.buffer = buffer; - - FT_ASSERT( (slot->flags & FT_GLYPH_OWN_BITMAP) == 0 ); - } + + FT_ASSERT( (slot->internal->flags & FT_GLYPH_OWN_BITMAP) == 0 ); + } FT_BASE_DEF( FT_Error ) @@ -235,15 +266,15 @@ FT_ULong size ) { FT_Memory memory = FT_FACE_MEMORY( slot->face ); - - - if ( slot->flags & FT_GLYPH_OWN_BITMAP ) + + + if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) FT_FREE( slot->bitmap.buffer ); else - slot->flags |= FT_GLYPH_OWN_BITMAP; - + slot->internal->flags |= FT_GLYPH_OWN_BITMAP; + return FT_MEM_ALLOC( slot->bitmap.buffer, size ); - } + } static void @@ -260,7 +291,7 @@ slot->bitmap.rows = 0; slot->bitmap.pitch = 0; slot->bitmap.pixel_mode = 0; - /* don't touch 'slot->bitmap.buffer' !! */ + /* don't touch 'slot->bitmap.buffer'! */ slot->bitmap_left = 0; slot->bitmap_top = 0; @@ -426,23 +457,6 @@ } - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( void ) - FT_Set_Hint_Flags( FT_Face face, - FT_ULong flags ) - { - FT_Face_Internal internal; - - if ( !face ) - return; - - internal = face->internal; - - internal->hint_flags = (FT_UInt)flags; - } - - static FT_Renderer ft_lookup_glyph_renderer( FT_GlyphSlot slot ); @@ -465,7 +479,7 @@ if ( !face || !face->size || !face->glyph ) return FT_Err_Invalid_Face_Handle; - if ( glyph_index > (FT_UInt)face->num_glyphs ) + if ( glyph_index >= (FT_UInt)face->num_glyphs ) return FT_Err_Invalid_Argument; slot = face->glyph; @@ -503,7 +517,10 @@ autohint = 0; } - if ( autohint ) + /* don't apply autohinting if glyph is vertically distorted or */ + /* mirrored */ + if ( autohint && !( face->internal->transform_matrix.yy <= 0 || + face->internal->transform_matrix.yx != 0 ) ) { FT_AutoHinter_Service hinting; @@ -560,17 +577,17 @@ } /* compute the linear advance in 16.16 pixels */ - if ( ( load_flags & FT_LOAD_LINEAR_DESIGN ) == 0 ) + if ( ( load_flags & FT_LOAD_LINEAR_DESIGN ) == 0 && + ( face->face_flags & FT_FACE_FLAG_SCALABLE ) ) { - FT_UInt EM = face->units_per_EM; FT_Size_Metrics* metrics = &face->size->metrics; slot->linearHoriAdvance = FT_MulDiv( slot->linearHoriAdvance, - (FT_Long)metrics->x_ppem << 16, EM ); + metrics->x_scale, 64 ); slot->linearVertAdvance = FT_MulDiv( slot->linearVertAdvance, - (FT_Long)metrics->y_ppem << 16, EM ); + metrics->y_scale, 64 ); } if ( ( load_flags & FT_LOAD_IGNORE_TRANSFORM ) == 0 ) @@ -656,6 +673,28 @@ } + static void + destroy_charmaps( FT_Face face, + FT_Memory memory ) + { + FT_Int n; + + + for ( n = 0; n < face->num_charmaps; n++ ) + { + FT_CMap cmap = FT_CMAP( face->charmaps[n] ); + + + FT_CMap_Done( cmap ); + + face->charmaps[n] = NULL; + } + + FT_FREE( face->charmaps ); + face->num_charmaps = 0; + } + + /* destructor for faces list */ static void destroy_face( FT_Memory memory, @@ -676,9 +715,9 @@ /* discard all sizes for this face */ FT_List_Finalize( &face->sizes_list, - (FT_List_Destructor)destroy_size, - memory, - driver ); + (FT_List_Destructor)destroy_size, + memory, + driver ); face->size = 0; /* now discard client data */ @@ -686,31 +725,14 @@ face->generic.finalizer( face ); /* discard charmaps */ - { - FT_Int n; - - - for ( n = 0; n < face->num_charmaps; n++ ) - { - FT_CMap cmap = FT_CMAP( face->charmaps[n] ); - - - FT_CMap_Done( cmap ); - - face->charmaps[n] = NULL; - } - - FT_FREE( face->charmaps ); - face->num_charmaps = 0; - } - + destroy_charmaps( face, memory ); /* finalize format-specific stuff */ if ( clazz->done_face ) clazz->done_face( face ); /* close the stream for this face if needed */ - ft_input_stream_free( + FT_Stream_Free( face->stream, ( face->face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 ); @@ -719,7 +741,6 @@ /* get rid of it */ if ( face->internal ) { - FT_FREE( face->internal->postscript_name ); FT_FREE( face->internal ); } FT_FREE( face ); @@ -748,11 +769,11 @@ /* <Description> */ /* This function finds a Unicode charmap, if there is one. */ /* And if there is more than one, it tries to favour the more */ - /* extensive one, i.e. one that supports UCS-4 against those which */ + /* extensive one, i.e., one that supports UCS-4 against those which */ /* are limited to the BMP (said UCS-2 encoding.) */ /* */ /* This function is called from open_face() (just below), and also */ - /* from FT_Select_Charmap( , FT_ENCODING_UNICODE). */ + /* from FT_Select_Charmap( ..., FT_ENCODING_UNICODE). */ /* */ static FT_Error find_unicode_charmap( FT_Face face ) @@ -763,7 +784,7 @@ /* caller should have already checked that `face' is valid */ - FT_ASSERT ( face ); + FT_ASSERT( face ); first = face->charmaps; @@ -771,26 +792,26 @@ return FT_Err_Invalid_CharMap_Handle; /* - * the original TrueType specification(s) only specified charmap + * The original TrueType specification(s) only specified charmap * formats that are capable of mapping 8 or 16 bit character codes to * glyph indices. * - * however, recent updates to the Apple and OpenType specifications + * However, recent updates to the Apple and OpenType specifications * introduced new formats that are capable of mapping 32-bit character - * codes as well. And these are already used on some fonts, mainly to + * codes as well. And these are already used on some fonts, mainly to * map non-BMP Asian ideographs as defined in Unicode. * - * for compatibility purposes, these fonts generally come with + * For compatibility purposes, these fonts generally come with * *several* Unicode charmaps: * - * - one of them in the "old" 16-bit format, that cannot access - * all glyphs in the font + * - One of them in the "old" 16-bit format, that cannot access + * all glyphs in the font. * - * - another one in the "new" 32-bit format, that can access all + * - Another one in the "new" 32-bit format, that can access all * the glyphs. * - * this function has been written to always favor a 32-bit charmap - * when found. Otherwise, a 16-bit one is returned when found + * This function has been written to always favor a 32-bit charmap + * when found. Otherwise, a 16-bit one is returned when found. */ /* since the `interesting' table, with id's 3,10, is normally the */ @@ -848,10 +869,10 @@ FT_Long face_index, FT_Int num_params, FT_Parameter* params, - FT_Face* aface ) + FT_Face *aface ) { FT_Memory memory; - FT_Driver_Class clazz; + FT_Driver_Class clazz; FT_Face face = 0; FT_Error error, error2; FT_Face_Internal internal; @@ -897,11 +918,10 @@ /* select Unicode charmap by default */ error2 = find_unicode_charmap( face ); - /* if no Unicode charmap can be found, FT_Err_Invalid_CharMap_Handle is - * returned. - */ + /* if no Unicode charmap can be found, FT_Err_Invalid_CharMap_Handle */ + /* is returned. */ - /* no error should happen, but we want to play safe. */ + /* no error should happen, but we want to play safe */ if ( error2 && error2 != FT_Err_Invalid_CharMap_Handle ) { error = error2; @@ -913,8 +933,9 @@ Fail: if ( error ) { + destroy_charmaps( face, memory ); clazz->done_face( face ); - FT_FREE( face->internal ); + FT_FREE( internal ); FT_FREE( face ); *aface = 0; } @@ -976,6 +997,536 @@ } +#if !defined( FT_MACINTOSH ) && defined( FT_CONFIG_OPTION_MAC_FONTS ) + + /* The behavior here is very similar to that in base/ftmac.c, but it */ + /* is designed to work on non-mac systems, so no mac specific calls. */ + /* */ + /* We look at the file and determine if it is a mac dfont file or a mac */ + /* resource file, or a macbinary file containing a mac resource file. */ + /* */ + /* Unlike ftmac I'm not going to look at a `FOND'. I don't really see */ + /* the point, especially since there may be multiple `FOND' resources. */ + /* Instead I'll just look for `sfnt' and `POST' resources, ordered as */ + /* they occur in the file. */ + /* */ + /* Note that multiple `POST' resources do not mean multiple postscript */ + /* fonts; they all get jammed together to make what is essentially a */ + /* pfb file. */ + /* */ + /* We aren't interested in `NFNT' or `FONT' bitmap resources. */ + /* */ + /* As soon as we get an `sfnt' load it into memory and pass it off to */ + /* FT_Open_Face. */ + /* */ + /* If we have a (set of) `POST' resources, massage them into a (memory) */ + /* pfb file and pass that to FT_Open_Face. (As with ftmac.c I'm not */ + /* going to try to save the kerning info. After all that lives in the */ + /* `FOND' which isn't in the file containing the `POST' resources so */ + /* we don't really have access to it. */ + + + /* Finalizer for a memory stream; gets called by FT_Done_Face(). + It frees the memory it uses. */ + /* from ftmac.c */ + static void + memory_stream_close( FT_Stream stream ) + { + FT_Memory memory = stream->memory; + + + FT_FREE( stream->base ); + + stream->size = 0; + stream->base = 0; + stream->close = 0; + } + + + /* Create a new memory stream from a buffer and a size. */ + /* from ftmac.c */ + static FT_Error + new_memory_stream( FT_Library library, + FT_Byte* base, + FT_ULong size, + FT_Stream_CloseFunc close, + FT_Stream *astream ) + { + FT_Error error; + FT_Memory memory; + FT_Stream stream; + + + if ( !library ) + return FT_Err_Invalid_Library_Handle; + + if ( !base ) + return FT_Err_Invalid_Argument; + + *astream = 0; + memory = library->memory; + if ( FT_NEW( stream ) ) + goto Exit; + + FT_Stream_OpenMemory( stream, base, size ); + + stream->close = close; + + *astream = stream; + + Exit: + return error; + } + + + /* Create a new FT_Face given a buffer and a driver name. */ + /* from ftmac.c */ + static FT_Error + open_face_from_buffer( FT_Library library, + FT_Byte* base, + FT_ULong size, + FT_Long face_index, + const char* driver_name, + FT_Face *aface ) + { + FT_Open_Args args; + FT_Error error; + FT_Stream stream; + FT_Memory memory = library->memory; + + + error = new_memory_stream( library, + base, + size, + memory_stream_close, + &stream ); + if ( error ) + { + FT_FREE( base ); + return error; + } + + args.flags = FT_OPEN_STREAM; + args.stream = stream; + if ( driver_name ) + { + args.flags = args.flags | FT_OPEN_DRIVER; + args.driver = FT_Get_Module( library, driver_name ); + } + + error = FT_Open_Face( library, &args, face_index, aface ); + + if ( error == FT_Err_Ok ) + (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM; + else + { + FT_Stream_Close( stream ); + FT_FREE( stream ); + } + + return error; + } + + + /* The resource header says we've got resource_cnt `POST' (type1) */ + /* resources in this file. They all need to be coalesced into */ + /* one lump which gets passed on to the type1 driver. */ + /* Here can be only one PostScript font in a file so face_index */ + /* must be 0 (or -1). */ + /* */ + static FT_Error + Mac_Read_POST_Resource( FT_Library library, + FT_Stream stream, + FT_Long *offsets, + FT_Long resource_cnt, + FT_Long face_index, + FT_Face *aface ) + { + FT_Error error = FT_Err_Cannot_Open_Resource; + FT_Memory memory = library->memory; + FT_Byte* pfb_data; + int i, type, flags; + FT_Long len; + FT_Long pfb_len, pfb_pos, pfb_lenpos; + FT_Long rlen, temp; + + + if ( face_index == -1 ) + face_index = 0; + if ( face_index != 0 ) + return error; + + /* Find the length of all the POST resources, concatenated. Assume */ + /* worst case (each resource in its own section). */ + pfb_len = 0; + for ( i = 0; i < resource_cnt; ++i ) + { + error = FT_Stream_Seek( stream, offsets[i] ); + if ( error ) + goto Exit; + if ( FT_READ_LONG( temp ) ) + goto Exit; + pfb_len += temp + 6; + } + + if ( FT_ALLOC( pfb_data, (FT_Long)pfb_len + 2 ) ) + goto Exit; + + pfb_data[0] = 0x80; + pfb_data[1] = 1; /* Ascii section */ + pfb_data[2] = 0; /* 4-byte length, fill in later */ + pfb_data[3] = 0; + pfb_data[4] = 0; + pfb_data[5] = 0; + pfb_pos = 7; + pfb_lenpos = 2; + + len = 0; + type = 1; + for ( i = 0; i < resource_cnt; ++i ) + { + error = FT_Stream_Seek( stream, offsets[i] ); + if ( error ) + goto Exit2; + if ( FT_READ_LONG( rlen ) ) + goto Exit; + if ( FT_READ_USHORT( flags ) ) + goto Exit; + rlen -= 2; /* the flags are part of the resource */ + if ( ( flags >> 8 ) == type ) + len += rlen; + else + { + pfb_data[pfb_lenpos ] = (FT_Byte)( len ); + pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 ); + pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 ); + pfb_data[pfb_lenpos + 3] = (FT_Byte)( len >> 24 ); + + if ( ( flags >> 8 ) == 5 ) /* End of font mark */ + break; + + pfb_data[pfb_pos++] = 0x80; + + type = flags >> 8; + len = rlen; + + pfb_data[pfb_pos++] = (FT_Byte)type; + pfb_lenpos = (FT_Byte)pfb_pos; + pfb_data[pfb_pos++] = 0; /* 4-byte length, fill in later */ + pfb_data[pfb_pos++] = 0; + pfb_data[pfb_pos++] = 0; + pfb_data[pfb_pos++] = 0; + } + + error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen ); + pfb_pos += rlen; + } + + pfb_data[pfb_pos++] = 0x80; + pfb_data[pfb_pos++] = 3; + + pfb_data[pfb_lenpos ] = (FT_Byte)( len ); + pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 ); + pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 ); + pfb_data[pfb_lenpos + 3] = (FT_Byte)( len >> 24 ); + + return open_face_from_buffer( library, + pfb_data, + pfb_pos, + face_index, + "type1", + aface ); + + Exit2: + FT_FREE( pfb_data ); + + Exit: + return error; + } + + + /* The resource header says we've got resource_cnt `sfnt' */ + /* (TrueType/OpenType) resources in this file. Look through */ + /* them for the one indicated by face_index, load it into mem, */ + /* pass it on the the truetype driver and return it. */ + /* */ + static FT_Error + Mac_Read_sfnt_Resource( FT_Library library, + FT_Stream stream, + FT_Long *offsets, + FT_Long resource_cnt, + FT_Long face_index, + FT_Face *aface ) + { + FT_Memory memory = library->memory; + FT_Byte* sfnt_data; + FT_Error error; + FT_Long flag_offset; + FT_Long rlen; + int is_cff; + + + if ( face_index == -1 ) + face_index = 0; + if ( face_index >= resource_cnt ) + return FT_Err_Cannot_Open_Resource; + + flag_offset = offsets[face_index]; + error = FT_Stream_Seek( stream, flag_offset ); + if ( error ) + goto Exit; + + if ( FT_READ_LONG( rlen ) ) + goto Exit; + if ( rlen == -1 ) + return FT_Err_Cannot_Open_Resource; + + if ( FT_ALLOC( sfnt_data, (FT_Long)rlen ) ) + return error; + error = FT_Stream_Read( stream, (FT_Byte *)sfnt_data, rlen ); + if ( error ) + goto Exit; + + is_cff = rlen > 4 && sfnt_data[0] == 'O' && + sfnt_data[1] == 'T' && + sfnt_data[2] == 'T' && + sfnt_data[3] == 'O'; + + error = open_face_from_buffer( library, + sfnt_data, + rlen, + face_index, + is_cff ? "cff" : "truetype", + aface ); + + Exit: + return error; + } + + + /* Check for a valid resource fork header, or a valid dfont */ + /* header. In a resource fork the first 16 bytes are repeated */ + /* at the location specified by bytes 4-7. In a dfont bytes */ + /* 4-7 point to 16 bytes of zeroes instead. */ + /* */ + static FT_Error + IsMacResource( FT_Library library, + FT_Stream stream, + FT_Long resource_offset, + FT_Long face_index, + FT_Face *aface ) + { + FT_Memory memory = library->memory; + FT_Error error; + FT_Long map_offset, rdara_pos; + FT_Long *data_offsets; + FT_Long count; + + + error = FT_Raccess_Get_HeaderInfo( library, stream, resource_offset, + &map_offset, &rdara_pos ); + if ( error ) + return error; + + error = FT_Raccess_Get_DataOffsets( library, stream, + map_offset, rdara_pos, + FT_MAKE_TAG( 'P', 'O', 'S', 'T' ), + &data_offsets, &count ); + if ( !error ) + { + error = Mac_Read_POST_Resource( library, stream, data_offsets, count, + face_index, aface ); + FT_FREE( data_offsets ); + return error; + } + + error = FT_Raccess_Get_DataOffsets( library, stream, + map_offset, rdara_pos, + FT_MAKE_TAG( 's', 'f', 'n', 't' ), + &data_offsets, &count ); + if ( !error ) + { + error = Mac_Read_sfnt_Resource( library, stream, data_offsets, count, + face_index, aface ); + FT_FREE( data_offsets ); + } + + return error; + } + + + /* Check for a valid macbinary header, and if we find one */ + /* check that the (flattened) resource fork in it is valid. */ + /* */ + static FT_Error + IsMacBinary( FT_Library library, + FT_Stream stream, + FT_Long face_index, + FT_Face *aface ) + { + unsigned char header[128]; + FT_Error error; + FT_Long dlen, offset; + + + error = FT_Stream_Seek( stream, 0 ); + if ( error ) + goto Exit; + + error = FT_Stream_Read( stream, (FT_Byte*)header, 128 ); + if ( error ) + goto Exit; + + if ( header[ 0] != 0 || + header[74] != 0 || + header[82] != 0 || + header[ 1] == 0 || + header[ 1] > 33 || + header[63] != 0 || + header[2 + header[1]] != 0 ) + return FT_Err_Unknown_File_Format; + + dlen = ( header[0x53] << 24 ) | + ( header[0x54] << 16 ) | + ( header[0x55] << 8 ) | + header[0x56]; +#if 0 + rlen = ( header[0x57] << 24 ) | + ( header[0x58] << 16 ) | + ( header[0x59] << 8 ) | + header[0x5a]; +#endif /* 0 */ + offset = 128 + ( ( dlen + 127 ) & ~127 ); + + return IsMacResource( library, stream, offset, face_index, aface ); + + Exit: + return error; + } + + + static FT_Error + load_face_in_embedded_rfork( FT_Library library, + FT_Stream stream, + FT_Long face_index, + FT_Face *aface, + const FT_Open_Args *args ) + { + +#undef FT_COMPONENT +#define FT_COMPONENT trace_raccess + + FT_Memory memory = library->memory; + FT_Error error = FT_Err_Unknown_File_Format; + int i; + + char * file_names[FT_RACCESS_N_RULES]; + FT_Long offsets[FT_RACCESS_N_RULES]; + FT_Error errors[FT_RACCESS_N_RULES]; + + FT_Open_Args args2; + FT_Stream stream2; + + + FT_Raccess_Guess( library, stream, + args->pathname, file_names, offsets, errors ); + + for ( i = 0; i < FT_RACCESS_N_RULES; i++ ) + { + if ( errors[i] ) + { + FT_TRACE3(( "Error[%d] has occurred in rule %d\n", errors[i], i )); + continue; + } + + args2.flags = FT_OPEN_PATHNAME; + args2.pathname = file_names[i] ? file_names[i] : args->pathname; + + FT_TRACE3(( "Try rule %d: %s (offset=%d) ...", + i, args2.pathname, offsets[i] )); + + error = FT_Stream_New( library, &args2, &stream2 ); + if ( error ) + { + FT_TRACE3(( "failed\n" )); + continue; + } + + error = IsMacResource( library, stream2, offsets[i], + face_index, aface ); + FT_Stream_Close( stream2 ); + + FT_TRACE3(( "%s\n", error ? "failed": "successful" )); + + if ( !error ) + break; + } + + for (i = 0; i < FT_RACCESS_N_RULES; i++) + { + if ( file_names[i] ) + FT_FREE( file_names[i] ); + } + + /* Caller (load_mac_face) requires FT_Err_Unknown_File_Format. */ + if ( error ) + error = FT_Err_Unknown_File_Format; + + return error; + +#undef FT_COMPONENT +#define FT_COMPONENT trace_objs + + } + + + /* Check for some macintosh formats. */ + /* Is this a macbinary file? If so look at the resource fork. */ + /* Is this a mac dfont file? */ + /* Is this an old style resource fork? (in data) */ + /* Else call load_face_in_embedded_rfork to try extra rules */ + /* (defined in `ftrfork.c'). */ + /* */ + static FT_Error + load_mac_face( FT_Library library, + FT_Stream stream, + FT_Long face_index, + FT_Face *aface, + const FT_Open_Args *args ) + { + FT_Error error; + FT_UNUSED( args ); + + + error = IsMacBinary( library, stream, face_index, aface ); + if ( FT_ERROR_BASE( error ) == FT_Err_Unknown_File_Format ) + { + +#undef FT_COMPONENT +#define FT_COMPONENT trace_raccess + + FT_TRACE3(( "Try as dfont: %s ...", args->pathname )); + + error = IsMacResource( library, stream, 0, face_index, aface ); + + FT_TRACE3(( "%s\n", error ? "failed" : "successful" )); + +#undef FT_COMPONENT +#define FT_COMPONENT trace_objs + + } + + if ( ( FT_ERROR_BASE( error ) == FT_Err_Unknown_File_Format || + FT_ERROR_BASE( error ) == FT_Err_Invalid_Stream_Operation ) && + ( args->flags & FT_OPEN_PATHNAME ) ) + error = load_face_in_embedded_rfork( library, stream, + face_index, aface, args ); + return error; + } + +#endif /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */ + + /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_Error ) @@ -994,7 +1545,7 @@ /* test for valid `library' delayed to */ - /* ft_input_stream_new() */ + /* FT_Stream_New() */ if ( !aface || !args ) return FT_Err_Invalid_Argument; @@ -1005,7 +1556,7 @@ args->stream ); /* create input stream */ - error = ft_input_stream_new( library, args, &stream ); + error = FT_Stream_New( library, args, &stream ); if ( error ) goto Exit; @@ -1038,7 +1589,7 @@ else error = FT_Err_Invalid_Handle; - ft_input_stream_free( stream, external_stream ); + FT_Stream_Free( stream, external_stream ); goto Fail; } else @@ -1066,20 +1617,45 @@ } error = open_face( driver, stream, face_index, - num_params, params, &face ); + num_params, params, &face ); if ( !error ) goto Success; if ( FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format ) - goto Fail2; + goto Fail3; } } + Fail3: + /* If we are on the mac, and we get an FT_Err_Invalid_Stream_Operation */ + /* it may be because we have an empty data fork, so we need to check */ + /* the resource fork. */ + if ( FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format && + FT_ERROR_BASE( error ) != FT_Err_Invalid_Stream_Operation ) + goto Fail2; + +#if !defined( FT_MACINTOSH ) && defined( FT_CONFIG_OPTION_MAC_FONTS ) + error = load_mac_face( library, stream, face_index, aface, args ); + if ( !error ) + { + /* We don't want to go to Success here. We've already done that. */ + /* On the other hand, if we succeeded we still need to close this */ + /* stream (we opened a different stream which extracted the */ + /* interesting information out of this stream here. That stream */ + /* will still be open and the face will point to it). */ + FT_Stream_Free( stream, external_stream ); + return error; + } + + if ( FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format ) + goto Fail2; +#endif /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */ + /* no driver is able to handle this format */ error = FT_Err_Unknown_File_Format; Fail2: - ft_input_stream_free( stream, external_stream ); + FT_Stream_Free( stream, external_stream ); goto Fail; } @@ -1188,7 +1764,7 @@ FT_Driver_Class clazz; - /* test for valid `parameters' delayed to ft_input_stream_new() */ + /* test for valid `parameters' delayed to FT_Stream_New() */ if ( !face ) return FT_Err_Invalid_Face_Handle; @@ -1197,7 +1773,7 @@ if ( !driver ) return FT_Err_Invalid_Driver_Handle; - error = ft_input_stream_new( driver->root.library, parameters, &stream ); + error = FT_Stream_New( driver->root.library, parameters, &stream ); if ( error ) goto Exit; @@ -1210,7 +1786,7 @@ error = clazz->attach_file( face, stream ); /* close the attached stream */ - ft_input_stream_free( stream, + FT_Stream_Free( stream, (FT_Bool)( parameters->stream && ( parameters->flags & FT_OPEN_STREAM ) ) ); @@ -1368,17 +1944,17 @@ { /* Compute root ascender, descender, test height, and max_advance */ - metrics->ascender = ( FT_MulFix( face->ascender, - metrics->y_scale ) + 63 ) & -64; + metrics->ascender = FT_PIX_CEIL( FT_MulFix( face->ascender, + metrics->y_scale ) ); - metrics->descender = ( FT_MulFix( face->descender, - metrics->y_scale ) + 0 ) & -64; + metrics->descender = FT_PIX_FLOOR( FT_MulFix( face->descender, + metrics->y_scale ) ); - metrics->height = ( FT_MulFix( face->height, - metrics->y_scale ) + 32 ) & -64; + metrics->height = FT_PIX_ROUND( FT_MulFix( face->height, + metrics->y_scale ) ); - metrics->max_advance = ( FT_MulFix( face->max_advance_width, - metrics->x_scale ) + 32 ) & -64; + metrics->max_advance = FT_PIX_ROUND( FT_MulFix( face->max_advance_width, + metrics->x_scale ) ); } @@ -1403,6 +1979,7 @@ driver = face->driver; metrics = &face->size->metrics; + clazz = driver->clazz; if ( !char_width ) char_width = char_height; @@ -1416,22 +1993,27 @@ if ( !vert_resolution ) vert_resolution = 72; - driver = face->driver; - clazz = driver->clazz; - /* default processing -- this can be overridden by the driver */ if ( char_width < 1 * 64 ) char_width = 1 * 64; if ( char_height < 1 * 64 ) char_height = 1 * 64; - /* Compute pixel sizes in 26.6 units. we use rounding - */ - dim_x = ( ( char_width * horz_resolution + (36+32*72) ) / 72 ) & -64; - dim_y = ( ( char_height * vert_resolution + (36+32*72) ) / 72 ) & -64; + /* Compute pixel sizes in 26.6 units with rounding */ + dim_x = ( char_width * horz_resolution + 36 ) / 72; + dim_y = ( char_height * vert_resolution + 36 ) / 72; - metrics->x_ppem = (FT_UShort)( dim_x >> 6 ); - metrics->y_ppem = (FT_UShort)( dim_y >> 6 ); + { + FT_UShort x_ppem = (FT_UShort)( ( dim_x + 32 ) >> 6 ); + FT_UShort y_ppem = (FT_UShort)( ( dim_y + 32 ) >> 6 ); + + + if ( x_ppem == metrics->x_ppem && y_ppem == metrics->y_ppem ) + return FT_Err_Ok; + + metrics->x_ppem = x_ppem; + metrics->y_ppem = y_ppem; + } metrics->x_scale = 0x10000L; metrics->y_scale = 0x10000L; @@ -1464,16 +2046,16 @@ FT_Error error = FT_Err_Ok; FT_Driver driver; FT_Driver_Class clazz; - FT_Size_Metrics* metrics = &face->size->metrics; + FT_Size_Metrics* metrics; if ( !face || !face->size || !face->driver ) return FT_Err_Invalid_Face_Handle; - driver = face->driver; - clazz = driver->clazz; + driver = face->driver; + metrics = &face->size->metrics; + clazz = driver->clazz; - /* default processing -- this can be overridden by the driver */ if ( pixel_width == 0 ) pixel_width = pixel_height; @@ -1485,6 +2067,12 @@ if ( pixel_height < 1 ) pixel_height = 1; + /* use `>=' to avoid potention compiler warning on 16bit platforms */ + if ( pixel_width >= 0xFFFFU ) + pixel_width = 0xFFFFU; + if ( pixel_height >= 0xFFFFU ) + pixel_height = 0xFFFFU; + metrics->x_ppem = (FT_UShort)pixel_width; metrics->y_ppem = (FT_UShort)pixel_height; @@ -1546,8 +2134,8 @@ if ( kern_mode != FT_KERNING_UNFITTED ) { - akerning->x = ( akerning->x + 32 ) & -64; - akerning->y = ( akerning->y + 32 ) & -64; + akerning->x = FT_PIX_ROUND( akerning->x ); + akerning->y = FT_PIX_ROUND( akerning->y ); } } } @@ -1570,10 +2158,10 @@ if ( !face ) return FT_Err_Invalid_Face_Handle; - /* FT_ENCODING_UNICODE is special. We try to find the `best' Unicode */ - /* charmap available, i.e. one with UCS-4 characters, if possible. */ - /* */ - /* This is done by find_unicode_charmap() above, to share code. */ + /* FT_ENCODING_UNICODE is special. We try to find the `best' Unicode */ + /* charmap available, i.e., one with UCS-4 characters, if possible. */ + /* */ + /* This is done by find_unicode_charmap() above, to share code. */ if ( encoding == FT_ENCODING_UNICODE ) return find_unicode_charmap( face ); @@ -1661,7 +2249,7 @@ return FT_Err_Invalid_Argument; face = charmap->face; - memory = FT_FACE_MEMORY(face); + memory = FT_FACE_MEMORY( face ); if ( !FT_ALLOC( cmap, clazz->size ) ) { @@ -1717,7 +2305,6 @@ } - /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_ULong ) @@ -1741,8 +2328,8 @@ return result; } - /* documentation is in freetype.h */ + /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_ULong ) FT_Get_Next_Char( FT_Face face, @@ -1770,7 +2357,6 @@ } - /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_UInt ) @@ -1782,21 +2368,15 @@ if ( face && FT_HAS_GLYPH_NAMES( face ) ) { - /* now, lookup for glyph name */ - FT_Driver driver = face->driver; - FT_Module_Class* clazz = FT_MODULE_CLASS( driver ); + FT_Service_GlyphDict service; - if ( clazz->get_interface ) - { - FT_Face_GetGlyphNameIndexFunc requester; + FT_FACE_LOOKUP_SERVICE( face, + service, + GLYPH_DICT ); - - requester = (FT_Face_GetGlyphNameIndexFunc)clazz->get_interface( - FT_MODULE( driver ), "name_index" ); - if ( requester ) - result = requester( face, glyph_name ); - } + if ( service && service->name_index ) + result = service->name_index( face, glyph_name ); } return result; @@ -1822,21 +2402,15 @@ glyph_index <= (FT_UInt)face->num_glyphs && FT_HAS_GLYPH_NAMES( face ) ) { - /* now, lookup for glyph name */ - FT_Driver driver = face->driver; - FT_Module_Class* clazz = FT_MODULE_CLASS( driver ); + FT_Service_GlyphDict service; - if ( clazz->get_interface ) - { - FT_Face_GetGlyphNameFunc requester; + FT_FACE_LOOKUP_SERVICE( face, + service, + GLYPH_DICT ); - - requester = (FT_Face_GetGlyphNameFunc)clazz->get_interface( - FT_MODULE( driver ), "glyph_name" ); - if ( requester ) - error = requester( face, glyph_index, buffer, buffer_max ); - } + if ( service && service->get_name ) + error = service->get_name( face, glyph_index, buffer, buffer_max ); } return error; @@ -1854,25 +2428,19 @@ if ( !face ) goto Exit; - result = face->internal->postscript_name; if ( !result ) { - /* now, look up glyph name */ - FT_Driver driver = face->driver; - FT_Module_Class* clazz = FT_MODULE_CLASS( driver ); + FT_Service_PsFontName service; - if ( clazz->get_interface ) - { - FT_Face_GetPostscriptNameFunc requester; + FT_FACE_LOOKUP_SERVICE( face, + service, + POSTSCRIPT_FONT_NAME ); - - requester = (FT_Face_GetPostscriptNameFunc)clazz->get_interface( - FT_MODULE( driver ), "postscript_name" ); - if ( requester ) - result = requester( face ); - } + if ( service && service->get_ps_font_name ) + result = service->get_ps_font_name( face ); } + Exit: return result; } @@ -1884,21 +2452,17 @@ FT_Get_Sfnt_Table( FT_Face face, FT_Sfnt_Tag tag ) { - void* table = 0; - FT_Get_Sfnt_Table_Func func; - FT_Driver driver; + void* table = 0; + FT_Service_SFNT_Table service; - if ( !face || !FT_IS_SFNT( face ) ) - goto Exit; + if ( face && FT_IS_SFNT( face ) ) + { + FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); + if ( service != NULL ) + table = service->get_table( face, tag ); + } - driver = face->driver; - func = (FT_Get_Sfnt_Table_Func)driver->root.clazz->get_interface( - FT_MODULE( driver ), "get_sfnt" ); - if ( func ) - table = func( face, tag ); - - Exit: return table; } @@ -1906,26 +2470,45 @@ /* documentation is in tttables.h */ FT_EXPORT_DEF( FT_Error ) - FT_Load_Sfnt_Table( FT_Face face, - FT_ULong tag, - FT_Long offset, - FT_Byte* buffer, - FT_ULong* length ) + FT_Load_Sfnt_Table( FT_Face face, + FT_ULong tag, + FT_Long offset, + FT_Byte* buffer, + FT_ULong* length ) { - SFNT_Load_Table_Func func; - FT_Driver driver; + FT_Service_SFNT_Table service; if ( !face || !FT_IS_SFNT( face ) ) return FT_Err_Invalid_Face_Handle; - driver = face->driver; - func = (SFNT_Load_Table_Func) driver->root.clazz->get_interface( - FT_MODULE( driver ), "load_sfnt" ); - if ( !func ) + FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); + if ( service == NULL ) return FT_Err_Unimplemented_Feature; - return func( face, tag, offset, buffer, length ); + return service->load_table( face, tag, offset, buffer, length ); + } + + + FT_EXPORT_DEF( FT_ULong ) + FT_Get_CMap_Language_ID( FT_CharMap charmap ) + { + FT_Service_TTCMaps service; + FT_Face face; + TT_CMapInfo cmap_info; + + + if ( !charmap || !charmap->face ) + return 0; + + face = charmap->face; + FT_FACE_FIND_SERVICE( face, service, TT_CMAP ); + if ( service == NULL ) + return 0; + if ( service->get_cmap_info( charmap, &cmap_info )) + return 0; + + return cmap_info.language; } @@ -2475,6 +3058,50 @@ } + FT_BASE_DEF( FT_Pointer ) + ft_module_get_service( FT_Module module, + const char* service_id ) + { + FT_Pointer result = NULL; + + if ( module ) + { + FT_ASSERT( module->clazz && module->clazz->get_interface ); + + /* first, look for the service in the module + */ + if ( module->clazz->get_interface ) + result = module->clazz->get_interface( module, service_id ); + + if ( result == NULL ) + { + /* we didn't find it, look in all other modules then + */ + FT_Library library = module->library; + FT_Module* cur = library->modules; + FT_Module* limit = cur + library->num_modules; + + for ( ; cur < limit; cur++ ) + { + if ( cur[0] != module ) + { + FT_ASSERT( cur[0]->clazz ); + + if ( cur[0]->clazz->get_interface ) + { + result = cur[0]->clazz->get_interface( cur[0], service_id ); + if ( result != NULL ) + break; + } + } + } + } + } + + return result; + } + + /* documentation is in ftmodule.h */ FT_EXPORT_DEF( FT_Error ) @@ -2664,4 +3291,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/base/ftoutln.c b/src/libs/freetype2/base/ftoutln.c index 0eca3d5eee..5cae931f67 100644 --- a/src/libs/freetype2/base/ftoutln.c +++ b/src/libs/freetype2/base/ftoutln.c @@ -4,7 +4,7 @@ /* */ /* FreeType outline management (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -26,6 +26,7 @@ #include <ft2build.h> #include FT_OUTLINE_H #include FT_INTERNAL_OBJECTS_H +#include FT_TRIGONOMETRY_H /*************************************************************************/ @@ -357,14 +358,11 @@ source->n_contours != target->n_contours ) return FT_Err_Invalid_Argument; - FT_MEM_COPY( target->points, source->points, - source->n_points * sizeof ( FT_Vector ) ); + FT_ARRAY_COPY( target->points, source->points, source->n_points ); - FT_MEM_COPY( target->tags, source->tags, - source->n_points * sizeof ( FT_Byte ) ); + FT_ARRAY_COPY( target->tags, source->tags, source->n_points ); - FT_MEM_COPY( target->contours, source->contours, - source->n_contours * sizeof ( FT_Short ) ); + FT_ARRAY_COPY( target->contours, source->contours, source->n_contours ); /* copy all flags, except the `FT_OUTLINE_OWNER' one */ is_owner = target->flags & FT_OUTLINE_OWNER; @@ -655,4 +653,143 @@ } -/* END */ + typedef struct FT_OrientationExtremumRec_ + { + FT_Int index; + FT_Long pos; + FT_Int first; + FT_Int last; + + } FT_OrientationExtremumRec; + + + static FT_Orientation + ft_orientation_extremum_compute( FT_OrientationExtremumRec* extremum, + FT_Outline* outline ) + { + FT_Vector *point, *first, *last, *prev, *next; + FT_Vector* points = outline->points; + FT_Angle angle_in, angle_out; + + + /* compute the previous and next points in the same contour */ + point = points + extremum->index; + first = points + extremum->first; + last = points + extremum->last; + + prev = point; + next = point; + + do + { + prev = ( prev == first ) ? last : prev - 1; + if ( prev == point ) + return FT_ORIENTATION_TRUETYPE; /* degenerate case */ + + } while ( prev->x != point->x || prev->y != point->y ); + + do + { + next = ( next == last ) ? first : next + 1; + if ( next == point ) + return FT_ORIENTATION_TRUETYPE; /* shouldn't happen */ + + } while ( next->x != point->x || next->y != point->y ); + + /* now compute the orientation of the `out' vector relative */ + /* to the `in' vector. */ + angle_in = FT_Atan2( point->x - prev->x, point->y - prev->y ); + angle_out = FT_Atan2( next->x - point->x, next->y - point->y ); + + return ( FT_Angle_Diff( angle_in, angle_out ) >= 0 ) + ? FT_ORIENTATION_TRUETYPE + : FT_ORIENTATION_POSTSCRIPT; + } + + + FT_EXPORT_DEF( FT_Orientation ) + FT_Outline_Get_Orientation( FT_Outline* outline ) + { + FT_Orientation result = FT_ORIENTATION_TRUETYPE; + + + if ( outline && outline->n_points > 0 ) + { + FT_OrientationExtremumRec xmin, ymin, xmax, ymax; + FT_Int n; + FT_Int first, last; + FT_Vector* points = outline->points; + + + xmin.pos = ymin.pos = +32768L; + xmax.pos = ymax.pos = -32768L; + + xmin.index = ymin.index = xmax.index = ymax.index = -1; + + first = 0; + for ( n = 0; n < outline->n_contours; n++, first = last + 1 ) + { + last = outline->contours[n]; + + /* skip single-point contours; these are degenerated cases */ + if ( last > first + 1 ) + { + FT_Int i; + + + for ( i = first; i < last; i++ ) + { + FT_Pos x = points[i].x; + FT_Pos y = points[i].y; + + + if ( x < xmin.pos ) + { + xmin.pos = x; + xmin.index = i; + xmin.first = first; + xmin.last = last; + } + if ( x > xmax.pos ) + { + xmax.pos = x; + xmax.index = i; + xmax.first = first; + xmax.last = last; + } + if ( y < ymin.pos ) + { + ymin.pos = y; + ymin.index = i; + ymin.first = first; + ymin.last = last; + } + if ( y > ymax.pos ) + { + ymax.pos = y; + ymax.index = i; + ymax.first = first; + ymax.last = last; + } + } + } + + if ( xmin.index >= 0 ) + result = ft_orientation_extremum_compute( &xmin, outline ); + + else if ( xmax.index >= 0 ) + result = ft_orientation_extremum_compute( &xmax, outline ); + + else if ( ymin.index >= 0 ) + result = ft_orientation_extremum_compute( &ymin, outline ); + + else if ( ymax.index >= 0 ) + result = ft_orientation_extremum_compute( &ymax, outline ); + } + } + + return result; + } + + +/* END */ diff --git a/src/libs/freetype2/base/ftpfr.c b/src/libs/freetype2/base/ftpfr.c index e091c3e4c0..fb959e37fc 100644 --- a/src/libs/freetype2/base/ftpfr.c +++ b/src/libs/freetype2/base/ftpfr.c @@ -2,9 +2,9 @@ /* */ /* ftpfr.c */ /* */ -/* FreeType API for accessing PFR-specific data */ +/* FreeType API for accessing PFR-specific data (body). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,48 +16,36 @@ /***************************************************************************/ #include <ft2build.h> -#include FT_INTERNAL_PFR_H #include FT_INTERNAL_OBJECTS_H +#include FT_SERVICE_PFR_H - /* check the format */ - static FT_Error - ft_pfr_check( FT_Face face, - FT_PFR_Service *aservice ) + /* check the format */ + static FT_Service_PfrMetrics + ft_pfr_check( FT_Face face ) { - FT_Error error = FT_Err_Bad_Argument; + FT_Service_PfrMetrics service; - if ( face && face->driver ) - { - FT_Module module = (FT_Module) face->driver; - const char* name = module->clazz->module_name; - if ( name[0] == 'p' && - name[1] == 'f' && - name[2] == 'r' && - name[4] == 0 ) - { - *aservice = (FT_PFR_Service) module->clazz->module_interface; - error = 0; - } - } - return error; + FT_FACE_LOOKUP_SERVICE( face, service, PFR_METRICS ); + + return service; } - FT_EXPORT_DEF( FT_Error ) - FT_Get_PFR_Metrics( FT_Face face, - FT_UInt *aoutline_resolution, - FT_UInt *ametrics_resolution, - FT_Fixed *ametrics_x_scale, - FT_Fixed *ametrics_y_scale ) + FT_Get_PFR_Metrics( FT_Face face, + FT_UInt *aoutline_resolution, + FT_UInt *ametrics_resolution, + FT_Fixed *ametrics_x_scale, + FT_Fixed *ametrics_y_scale ) { - FT_Error error; - FT_PFR_Service service; + FT_Error error = FT_Err_Ok; + FT_Service_PfrMetrics service; - error = ft_pfr_check( face, &service ); - if ( !error ) + + service = ft_pfr_check( face ); + if ( service ) { error = service->get_metrics( face, aoutline_resolution, @@ -65,41 +53,74 @@ ametrics_x_scale, ametrics_y_scale ); } + else if ( face ) + { + FT_Fixed x_scale, y_scale; + + + /* this is not a PFR font */ + *aoutline_resolution = face->units_per_EM; + *ametrics_resolution = face->units_per_EM; + + x_scale = y_scale = 0x10000L; + if ( face->size ) + { + x_scale = face->size->metrics.x_scale; + y_scale = face->size->metrics.y_scale; + } + *ametrics_x_scale = x_scale; + *ametrics_y_scale = y_scale; + } + else + error = FT_Err_Invalid_Argument; + return error; } + FT_EXPORT_DEF( FT_Error ) FT_Get_PFR_Kerning( FT_Face face, FT_UInt left, FT_UInt right, FT_Vector *avector ) { - FT_Error error; - FT_PFR_Service service; + FT_Error error; + FT_Service_PfrMetrics service; - error = ft_pfr_check( face, &service ); - if ( !error ) - { + + service = ft_pfr_check( face ); + if ( service ) error = service->get_kerning( face, left, right, avector ); - } + else if ( face ) + error = FT_Get_Kerning( face, left, right, + FT_KERNING_UNSCALED, avector ); + else + error = FT_Err_Invalid_Argument; + return error; } FT_EXPORT_DEF( FT_Error ) - FT_Get_PFR_Advance( FT_Face face, - FT_UInt gindex, - FT_Pos *aadvance ) + FT_Get_PFR_Advance( FT_Face face, + FT_UInt gindex, + FT_Pos *aadvance ) { - FT_Error error; - FT_PFR_Service service; + FT_Error error; + FT_Service_PfrMetrics service; - error = ft_pfr_check( face, &service ); - if ( !error ) + + service = ft_pfr_check( face ); + if ( service ) { error = service->get_advance( face, gindex, aadvance ); } + else + /* XXX: TODO: PROVIDE ADVANCE-LOADING METHOD TO ALL FONT DRIVERS */ + error = FT_Err_Invalid_Argument; + return error; } -/* END */ + +/* END */ diff --git a/src/libs/freetype2/base/ftrfork.c b/src/libs/freetype2/base/ftrfork.c new file mode 100644 index 0000000000..cf790ccc00 --- /dev/null +++ b/src/libs/freetype2/base/ftrfork.c @@ -0,0 +1,717 @@ +/***************************************************************************/ +/* */ +/* ftrfork.c */ +/* */ +/* Embedded resource forks accessor (body). */ +/* */ +/* Copyright 2004 by */ +/* Masatake YAMATO and Redhat K.K. */ +/* */ +/* FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are */ +/* derived from ftobjs.c. */ +/* */ +/* 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. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* Development of the code in this file is support of */ +/* Information-technology Promotion Agency, Japan. */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_RFORK_H + + +#undef FT_COMPONENT +#define FT_COMPONENT trace_raccess + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** Resource fork directory access ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + FT_BASE_DEF( FT_Error ) + FT_Raccess_Get_HeaderInfo( FT_Library library, + FT_Stream stream, + FT_Long rfork_offset, + FT_Long *map_offset, + FT_Long *rdata_pos ) + { + FT_Error error; + unsigned char head[16], head2[16]; + FT_Long map_pos, rdata_len; + int allzeros, allmatch, i; + FT_Long type_list; + + FT_UNUSED( library ); + + + error = FT_Stream_Seek( stream, rfork_offset ); + if ( error ) + return error; + + error = FT_Stream_Read( stream, (FT_Byte *)head, 16 ); + if ( error ) + return error; + + *rdata_pos = rfork_offset + ( ( head[0] << 24 ) | + ( head[1] << 16 ) | + ( head[2] << 8 ) | + head[3] ); + map_pos = rfork_offset + ( ( head[4] << 24 ) | + ( head[5] << 16 ) | + ( head[6] << 8 ) | + head[7] ); + rdata_len = ( head[ 8] << 24 ) | + ( head[ 9] << 16 ) | + ( head[10] << 8 ) | + head[11]; + + /* map_len = head[12] .. head[15] */ + + if ( *rdata_pos + rdata_len != map_pos || map_pos == rfork_offset ) + return FT_Err_Unknown_File_Format; + + error = FT_Stream_Seek( stream, map_pos ); + if ( error ) + return error; + + head2[15] = (FT_Byte)( head[15] + 1 ); /* make it be different */ + + error = FT_Stream_Read( stream, (FT_Byte*)head2, 16 ); + if ( error ) + return error; + + allzeros = 1; + allmatch = 1; + for ( i = 0; i < 16; ++i ) + { + if ( head2[i] != 0 ) + allzeros = 0; + if ( head2[i] != head[i] ) + allmatch = 0; + } + if ( !allzeros && !allmatch ) + return FT_Err_Unknown_File_Format; + + /* If we have reached this point then it is probably a mac resource */ + /* file. Now, does it contain any interesting resources? */ + /* Skip handle to next resource map, the file resource number, and */ + /* attributes. */ + (void)FT_STREAM_SKIP( 4 /* skip handle to next resource map */ + + 2 /* skip file resource number */ + + 2 ); /* skip attributes */ + + if ( FT_READ_USHORT( type_list ) ) + return error; + if ( type_list == -1 ) + return FT_Err_Unknown_File_Format; + + error = FT_Stream_Seek( stream, map_pos + type_list ); + if ( error ) + return error; + + *map_offset = map_pos + type_list; + return FT_Err_Ok; + } + + + FT_BASE_DEF( FT_Error ) + FT_Raccess_Get_DataOffsets( FT_Library library, + FT_Stream stream, + FT_Long map_offset, + FT_Long rdata_pos, + FT_Long tag, + FT_Long **offsets, + FT_Long *count ) + { + FT_Error error; + int i, j, cnt, subcnt; + FT_Long tag_internal, rpos; + FT_Memory memory = library->memory; + FT_Long temp; + FT_Long *offsets_internal; + + + error = FT_Stream_Seek( stream, map_offset ); + if ( error ) + return error; + + if ( FT_READ_USHORT( cnt ) ) + return error; + cnt++; + + for ( i = 0; i < cnt; ++i ) + { + if ( FT_READ_LONG( tag_internal ) || + FT_READ_USHORT( subcnt ) || + FT_READ_USHORT( rpos ) ) + return error; + + FT_TRACE2(( "Resource tags: %c%c%c%c\n", + (char)( 0xff & ( tag_internal >> 24 ) ), + (char)( 0xff & ( tag_internal >> 16 ) ), + (char)( 0xff & ( tag_internal >> 8 ) ), + (char)( 0xff & ( tag_internal >> 0 ) ) )); + + if ( tag_internal == tag ) + { + *count = subcnt + 1; + rpos += map_offset; + + error = FT_Stream_Seek( stream, rpos ); + if ( error ) + return error; + + if ( FT_ALLOC( offsets_internal, *count * sizeof( FT_Long ) ) ) + return error; + + for ( j = 0; j < *count; ++j ) + { + (void)FT_STREAM_SKIP( 2 ); /* resource id */ + (void)FT_STREAM_SKIP( 2 ); /* rsource name */ + + if ( FT_READ_LONG( temp ) ) + { + FT_FREE( offsets_internal ); + return error; + } + + offsets_internal[j] = rdata_pos + ( temp & 0xFFFFFFL ); + + (void)FT_STREAM_SKIP( 4 ); /* mbz */ + } + + *offsets = offsets_internal; + + return FT_Err_Ok; + } + } + + return FT_Err_Cannot_Open_Resource; + } + + +#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** Guessing functions ****/ + /**** ****/ + /**** When you add a new guessing function, ****/ + /**** update FT_RACCESS_N_RULES in ftrfork.h. ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + typedef FT_Error + (*raccess_guess_func)( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + + static FT_Error + raccess_guess_apple_double( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_apple_single( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_darwin_ufs_export( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_darwin_hfsplus( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_vfat( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_linux_cap( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_linux_double( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_linux_netatalk( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ); + + + /*************************************************************************/ + /**** ****/ + /**** Helper functions ****/ + /**** ****/ + /*************************************************************************/ + + static FT_Error + raccess_guess_apple_generic( FT_Library library, + FT_Stream stream, + char * base_file_name, + FT_Int32 magic, + FT_Long *result_offset ); + + static FT_Error + raccess_guess_linux_double_from_file_name( FT_Library library, + char * file_name, + FT_Long *result_offset ); + + static char * + raccess_make_file_name( FT_Memory memory, + const char *original_name, + const char *insertion ); + + + FT_BASE_DEF( void ) + FT_Raccess_Guess( FT_Library library, + FT_Stream stream, + char* base_name, + char **new_names, + FT_Long *offsets, + FT_Error *errors ) + { + FT_Long i; + + + raccess_guess_func funcs[FT_RACCESS_N_RULES] = + { + raccess_guess_apple_double, + raccess_guess_apple_single, + raccess_guess_darwin_ufs_export, + raccess_guess_darwin_hfsplus, + raccess_guess_vfat, + raccess_guess_linux_cap, + raccess_guess_linux_double, + raccess_guess_linux_netatalk, + }; + + for ( i = 0; i < FT_RACCESS_N_RULES; i++ ) + { + new_names[i] = NULL; + errors[i] = FT_Stream_Seek( stream, 0 ); + if ( errors[i] ) + continue ; + + errors[i] = (funcs[i])( library, stream, base_name, + &(new_names[i]), &(offsets[i]) ); + } + + return; + } + + + static FT_Error + raccess_guess_apple_double( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + FT_Int32 magic = ( 0x00 << 24 | 0x05 << 16 | 0x16 << 8 | 0x07 ); + + + *result_file_name = NULL; + return raccess_guess_apple_generic( library, stream, base_file_name, + magic, result_offset ); + } + + + static FT_Error + raccess_guess_apple_single( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + FT_Int32 magic = (0x00 << 24 | 0x05 << 16 | 0x16 << 8 | 0x00); + + + *result_file_name = NULL; + return raccess_guess_apple_generic( library, stream, base_file_name, + magic, result_offset ); + } + + + static FT_Error + raccess_guess_darwin_ufs_export( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + char* newpath; + FT_Error error; + FT_Memory memory; + + FT_UNUSED( stream ); + + + memory = library->memory; + newpath = raccess_make_file_name( memory, base_file_name, "._" ); + if ( !newpath ) + return FT_Err_Out_Of_Memory; + + error = raccess_guess_linux_double_from_file_name( library, newpath, + result_offset ); + if ( !error ) + *result_file_name = newpath; + else + FT_FREE( newpath ); + + return error; + } + + + static FT_Error + raccess_guess_darwin_hfsplus( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + /* + Only meaningful on systems with hfs+ drivers (or Macs). + */ + FT_Error error; + char* newpath; + FT_Memory memory; + + FT_UNUSED( stream ); + + + memory = library->memory; + + if ( FT_ALLOC( newpath, + ft_strlen( base_file_name ) + ft_strlen( "/rsrc" ) + 1 ) ) + return error; + + ft_strcpy( newpath, base_file_name ); + ft_strcat( newpath, "/rsrc" ); + *result_file_name = newpath; + *result_offset = 0; + return FT_Err_Ok; + } + + + static FT_Error + raccess_guess_vfat( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + char* newpath; + FT_Memory memory; + + FT_UNUSED( stream ); + + + memory = library->memory; + + newpath = raccess_make_file_name( memory, base_file_name, + "resource.frk/" ); + if ( !newpath ) + return FT_Err_Out_Of_Memory; + + *result_file_name = newpath; + *result_offset = 0; + + return FT_Err_Ok; + } + + + static FT_Error + raccess_guess_linux_cap( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + char* newpath; + FT_Memory memory; + + FT_UNUSED( stream ); + + + memory = library->memory; + + newpath = raccess_make_file_name( memory, base_file_name, ".resource/" ); + if ( !newpath ) + return FT_Err_Out_Of_Memory; + + *result_file_name = newpath; + *result_offset = 0; + + return FT_Err_Ok; + } + + + static FT_Error + raccess_guess_linux_double( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + char* newpath; + FT_Error error; + FT_Memory memory; + + FT_UNUSED( stream ); + + + memory = library->memory; + + newpath = raccess_make_file_name( memory, base_file_name, "%" ); + if ( !newpath ) + return FT_Err_Out_Of_Memory; + + error = raccess_guess_linux_double_from_file_name( library, newpath, + result_offset ); + if ( !error ) + *result_file_name = newpath; + else + FT_FREE( newpath ); + + return error; + } + + + static FT_Error + raccess_guess_linux_netatalk( FT_Library library, + FT_Stream stream, + char * base_file_name, + char **result_file_name, + FT_Long *result_offset ) + { + char* newpath; + FT_Error error; + FT_Memory memory; + + FT_UNUSED( stream ); + + + memory = library->memory; + + newpath = raccess_make_file_name( memory, base_file_name, + ".AppleDouble/" ); + if ( !newpath ) + return FT_Err_Out_Of_Memory; + + error = raccess_guess_linux_double_from_file_name( library, newpath, + result_offset ); + if ( !error ) + *result_file_name = newpath; + else + FT_FREE( newpath ); + + return error; + } + + + static FT_Error + raccess_guess_apple_generic( FT_Library library, + FT_Stream stream, + char * base_file_name, + FT_Int32 magic, + FT_Long *result_offset ) + { + FT_Int32 magic_from_stream; + FT_Error error; + FT_Int32 version_number; + FT_UShort n_of_entries; + + int i; + FT_UInt32 entry_id, entry_offset, entry_length; + + const FT_UInt32 resource_fork_entry_id = 0x2; + + FT_UNUSED( library ); + FT_UNUSED( base_file_name ); + + + if ( FT_READ_LONG ( magic_from_stream ) ) + return error; + if ( magic_from_stream != magic ) + return FT_Err_Unknown_File_Format; + + if ( FT_READ_LONG( version_number ) ) + return error; + + /* filler */ + error = FT_Stream_Skip( stream, 16 ); + if ( error ) + return error; + + if ( FT_READ_USHORT( n_of_entries ) ) + return error; + if ( n_of_entries == 0 ) + return FT_Err_Unknown_File_Format; + + for ( i = 0; i < n_of_entries; i++ ) + { + if ( FT_READ_LONG( entry_id ) ) + return error; + if ( entry_id == resource_fork_entry_id ) + { + if ( FT_READ_LONG( entry_offset ) || + FT_READ_LONG( entry_length ) ) + continue; + *result_offset = entry_offset; + + return FT_Err_Ok; + } + else + FT_Stream_Skip( stream, 4 + 4 ); /* offset + length */ + } + + return FT_Err_Unknown_File_Format; + } + + + static FT_Error + raccess_guess_linux_double_from_file_name( FT_Library library, + char * file_name, + FT_Long *result_offset ) + { + FT_Memory memory; + FT_Open_Args args2; + FT_Stream stream2; + char * nouse = NULL; + FT_Error error; + + + memory = library->memory; + + args2.flags = FT_OPEN_PATHNAME; + args2.pathname = file_name; + error = FT_Stream_New( library, &args2, &stream2 ); + if ( error ) + return error; + + error = raccess_guess_apple_double( library, stream2, file_name, + &nouse, result_offset ); + + FT_Stream_Close( stream2 ); + + return error; + } + + + static char* + raccess_make_file_name( FT_Memory memory, + const char *original_name, + const char *insertion ) + { + char* new_name; + char* tmp; + const char* slash; + unsigned new_length; + FT_ULong error; + + new_length = ft_strlen( original_name ) + ft_strlen( insertion ); + if ( FT_ALLOC( new_name, new_length + 1 ) ) + return NULL; + + tmp = ft_strrchr( original_name, '/' ); + if ( tmp ) + { + ft_strncpy( new_name, original_name, tmp - original_name + 1 ); + new_name[tmp - original_name + 1] = '\0'; + slash = tmp + 1; + } + else + { + slash = original_name; + new_name[0] = '\0'; + } + + ft_strcat( new_name, insertion ); + ft_strcat( new_name, slash ); + + return new_name; + } + + +#else /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */ + + + /*************************************************************************/ + /* Dummy function; just sets errors */ + /*************************************************************************/ + + FT_BASE_DEF( void ) + FT_Raccess_Guess( FT_Library library, + FT_Stream stream, + char* base_name, + char **new_names, + FT_Long *offsets, + FT_Error *errors ) + { + int i; + + + for ( i = 0; i < FT_RACCESS_N_RULES; i++ ) + { + new_names[i] = NULL; + offsets[i] = 0; + errors[i] = FT_Err_Unimplemented_Feature; + } + } + + +#endif /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */ + + +/* END */ diff --git a/src/libs/freetype2/base/ftstream.c b/src/libs/freetype2/base/ftstream.c index 919c22254e..7ff1e90532 100644 --- a/src/libs/freetype2/base/ftstream.c +++ b/src/libs/freetype2/base/ftstream.c @@ -4,7 +4,7 @@ /* */ /* I/O stream support (body). */ /* */ -/* Copyright 2000-2001, 2002 by */ +/* Copyright 2000-2001, 2002, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -770,15 +770,15 @@ p = (FT_Byte*)structure + fields->offset; switch ( fields->size ) { - case 1: + case (8 / FT_CHAR_BIT): *(FT_Byte*)p = (FT_Byte)value; break; - case 2: + case (16 / FT_CHAR_BIT): *(FT_UShort*)p = (FT_UShort)value; break; - case 4: + case (32 / FT_CHAR_BIT): *(FT_UInt32*)p = (FT_UInt32)value; break; @@ -800,4 +800,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/base/ftstroker.c b/src/libs/freetype2/base/ftstroke.c similarity index 60% rename from src/libs/freetype2/base/ftstroker.c rename to src/libs/freetype2/base/ftstroke.c index 4a3b01e6e4..10aad2db81 100644 --- a/src/libs/freetype2/base/ftstroker.c +++ b/src/libs/freetype2/base/ftstroke.c @@ -1,8 +1,50 @@ +/***************************************************************************/ +/* */ +/* ftstroke.c */ +/* */ +/* FreeType path stroker (body). */ +/* */ +/* Copyright 2002, 2003, 2004 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. */ +/* */ +/***************************************************************************/ + + #include <ft2build.h> #include FT_STROKER_H #include FT_TRIGONOMETRY_H +#include FT_OUTLINE_H #include FT_INTERNAL_MEMORY_H #include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_OBJECTS_H + + FT_EXPORT_DEF( FT_StrokerBorder ) + FT_Outline_GetInsideBorder( FT_Outline* outline ) + { + FT_Orientation o = FT_Outline_Get_Orientation( outline ); + + + return o == FT_ORIENTATION_TRUETYPE ? FT_STROKER_BORDER_RIGHT + : FT_STROKER_BORDER_LEFT ; + } + + + FT_EXPORT_DEF( FT_StrokerBorder ) + FT_Outline_GetOutsideBorder( FT_Outline* outline ) + { + FT_Orientation o = FT_Outline_Get_Orientation( outline ); + + + return o == FT_ORIENTATION_TRUETYPE ? FT_STROKER_BORDER_LEFT + : FT_STROKER_BORDER_RIGHT ; + } + /***************************************************************************/ /***************************************************************************/ @@ -12,18 +54,20 @@ /***************************************************************************/ /***************************************************************************/ -#define FT_SMALL_CONIC_THRESHOLD (FT_ANGLE_PI/6) -#define FT_SMALL_CUBIC_THRESHOLD (FT_ANGLE_PI/6) +#define FT_SMALL_CONIC_THRESHOLD ( FT_ANGLE_PI / 6 ) +#define FT_SMALL_CUBIC_THRESHOLD ( FT_ANGLE_PI / 6 ) #define FT_EPSILON 2 -#define FT_IS_SMALL(x) ((x) > -FT_EPSILON && (x) < FT_EPSILON) +#define FT_IS_SMALL( x ) ( (x) > -FT_EPSILON && (x) < FT_EPSILON ) + static FT_Pos ft_pos_abs( FT_Pos x ) { - return x >= 0 ? x : -x ; + return x >= 0 ? x : -x ; } + static void ft_conic_split( FT_Vector* base ) { @@ -32,15 +76,15 @@ base[4].x = base[2].x; b = base[1].x; - a = base[3].x = ( base[2].x + b )/2; - b = base[1].x = ( base[0].x + b )/2; - base[2].x = ( a + b )/2; + a = base[3].x = ( base[2].x + b ) / 2; + b = base[1].x = ( base[0].x + b ) / 2; + base[2].x = ( a + b ) / 2; base[4].y = base[2].y; b = base[1].y; - a = base[3].y = ( base[2].y + b )/2; - b = base[1].y = ( base[0].y + b )/2; - base[2].y = ( a + b )/2; + a = base[3].y = ( base[2].y + b ) / 2; + b = base[1].y = ( base[0].y + b ) / 2; + base[2].y = ( a + b ) / 2; } @@ -53,22 +97,23 @@ FT_Angle theta; FT_Int close1, close2; + d1.x = base[1].x - base[2].x; d1.y = base[1].y - base[2].y; d2.x = base[0].x - base[1].x; d2.y = base[0].y - base[1].y; - close1 = FT_IS_SMALL(d1.x) && FT_IS_SMALL(d1.y); - close2 = FT_IS_SMALL(d2.x) && FT_IS_SMALL(d2.y); + close1 = FT_IS_SMALL( d1.x ) && FT_IS_SMALL( d1.y ); + close2 = FT_IS_SMALL( d2.x ) && FT_IS_SMALL( d2.y ); - if (close1) + if ( close1 ) { - if (close2) + if ( close2 ) *angle_in = *angle_out = 0; else *angle_in = *angle_out = FT_Atan2( d2.x, d2.y ); } - else if (close2) + else if ( close2 ) { *angle_in = *angle_out = FT_Atan2( d1.x, d1.y ); } @@ -93,22 +138,22 @@ base[6].x = base[3].x; c = base[1].x; d = base[2].x; - base[1].x = a = ( base[0].x + c )/2; - base[5].x = b = ( base[3].x + d )/2; - c = ( c + d )/2; - base[2].x = a = ( a + c )/2; - base[4].x = b = ( b + c )/2; - base[3].x = ( a + b )/2; + base[1].x = a = ( base[0].x + c ) / 2; + base[5].x = b = ( base[3].x + d ) / 2; + c = ( c + d ) / 2; + base[2].x = a = ( a + c ) / 2; + base[4].x = b = ( b + c ) / 2; + base[3].x = ( a + b ) / 2; base[6].y = base[3].y; c = base[1].y; d = base[2].y; - base[1].y = a = ( base[0].y + c )/2; - base[5].y = b = ( base[3].y + d )/2; - c = ( c + d )/2; - base[2].y = a = ( a + c )/2; - base[4].y = b = ( b + c )/2; - base[3].y = ( a + b )/2; + base[1].y = a = ( base[0].y + c ) / 2; + base[5].y = b = ( base[3].y + d ) / 2; + c = ( c + d ) / 2; + base[2].y = a = ( a + c ) / 2; + base[4].y = b = ( b + c ) / 2; + base[3].y = ( a + b ) / 2; } @@ -122,6 +167,7 @@ FT_Angle theta1, theta2; FT_Int close1, close2, close3; + d1.x = base[2].x - base[3].x; d1.y = base[2].y - base[3].y; d2.x = base[1].x - base[2].x; @@ -129,18 +175,18 @@ d3.x = base[0].x - base[1].x; d3.y = base[0].y - base[1].y; - close1 = FT_IS_SMALL(d1.x) && FT_IS_SMALL(d1.y); - close2 = FT_IS_SMALL(d2.x) && FT_IS_SMALL(d2.y); - close3 = FT_IS_SMALL(d3.x) && FT_IS_SMALL(d3.y); + close1 = FT_IS_SMALL( d1.x ) && FT_IS_SMALL( d1.y ); + close2 = FT_IS_SMALL( d2.x ) && FT_IS_SMALL( d2.y ); + close3 = FT_IS_SMALL( d3.x ) && FT_IS_SMALL( d3.y ); - if (close1 || close3) + if ( close1 || close3 ) { - if (close2) + if ( close2 ) { /* basically a point */ *angle_in = *angle_out = *angle_mid = 0; } - else if (close1) + else if ( close1 ) { *angle_in = *angle_mid = FT_Atan2( d2.x, d2.y ); *angle_out = FT_Atan2( d3.x, d3.y ); @@ -151,7 +197,7 @@ *angle_mid = *angle_out = FT_Atan2( d2.x, d2.y ); } } - else if (close2) + else if ( close2 ) { *angle_in = *angle_mid = FT_Atan2( d1.x, d1.y ); *angle_out = FT_Atan2( d3.x, d3.y ); @@ -162,6 +208,7 @@ *angle_mid = FT_Atan2( d2.x, d2.y ); *angle_out = FT_Atan2( d3.x, d3.y ); } + theta1 = ft_pos_abs( FT_Angle_Diff( *angle_in, *angle_mid ) ); theta2 = ft_pos_abs( FT_Angle_Diff( *angle_mid, *angle_out ) ); @@ -170,7 +217,6 @@ } - /***************************************************************************/ /***************************************************************************/ /***** *****/ @@ -189,7 +235,7 @@ } FT_StrokeTags; - typedef struct FT_StrokeBorderRec_ + typedef struct FT_StrokeBorderRec_ { FT_UInt num_points; FT_UInt max_points; @@ -198,6 +244,7 @@ FT_Bool movable; FT_Int start; /* index of current sub-path start point */ FT_Memory memory; + FT_Bool valid; } FT_StrokeBorderRec, *FT_StrokeBorder; @@ -210,13 +257,15 @@ FT_UInt new_max = border->num_points + new_points; FT_Error error = 0; + if ( new_max > old_max ) { FT_UInt cur_max = old_max; FT_Memory memory = border->memory; + while ( cur_max < new_max ) - cur_max += (cur_max >> 1) + 16; + cur_max += ( cur_max >> 1 ) + 16; if ( FT_RENEW_ARRAY( border->points, old_max, cur_max ) || FT_RENEW_ARRAY( border->tags, old_max, cur_max ) ) @@ -228,16 +277,17 @@ return error; } + static void ft_stroke_border_close( FT_StrokeBorder border ) { FT_ASSERT( border->start >= 0 ); - /* don't record empty paths !! */ + /* don't record empty paths! */ if ( border->num_points > (FT_UInt)border->start ) { - border->tags[ border->start ] |= FT_STROKE_TAG_BEGIN; - border->tags[ border->num_points-1 ] |= FT_STROKE_TAG_END; + border->tags[border->start ] |= FT_STROKE_TAG_BEGIN; + border->tags[border->num_points - 1] |= FT_STROKE_TAG_END; } border->start = -1; @@ -252,22 +302,24 @@ { FT_Error error = 0; + FT_ASSERT( border->start >= 0 ); if ( border->movable ) { /* move last point */ - border->points[ border->num_points-1 ] = *to; + border->points[border->num_points - 1] = *to; } else { /* add one point */ error = ft_stroke_border_grow( border, 1 ); - if (!error) + if ( !error ) { FT_Vector* vec = border->points + border->num_points; FT_Byte* tag = border->tags + border->num_points; + vec[0] = *to; tag[0] = FT_STROKE_TAG_ON; @@ -286,10 +338,11 @@ { FT_Error error; + FT_ASSERT( border->start >= 0 ); error = ft_stroke_border_grow( border, 2 ); - if (!error) + if ( !error ) { FT_Vector* vec = border->points + border->num_points; FT_Byte* tag = border->tags + border->num_points; @@ -315,14 +368,16 @@ { FT_Error error; + FT_ASSERT( border->start >= 0 ); error = ft_stroke_border_grow( border, 3 ); - if (!error) + if ( !error ) { FT_Vector* vec = border->points + border->num_points; FT_Byte* tag = border->tags + border->num_points; + vec[0] = *control1; vec[1] = *control2; vec[2] = *to; @@ -338,7 +393,7 @@ } -#define FT_ARC_CUBIC_ANGLE (FT_ANGLE_PI/2) +#define FT_ARC_CUBIC_ANGLE ( FT_ANGLE_PI / 2 ) static FT_Error @@ -353,6 +408,7 @@ FT_Fixed length; FT_Error error = 0; + /* compute start point */ FT_Vector_From_Polar( &a, radius, angle_start ); a.x += center->x; @@ -362,11 +418,11 @@ angle = angle_start; rotate = ( angle_diff >= 0 ) ? FT_ANGLE_PI2 : -FT_ANGLE_PI2; - while (total != 0) + while ( total != 0 ) { step = total; if ( step > FT_ARC_CUBIC_ANGLE ) - step = FT_ARC_CUBIC_ANGLE; + step = FT_ARC_CUBIC_ANGLE; else if ( step < -FT_ARC_CUBIC_ANGLE ) step = -FT_ARC_CUBIC_ANGLE; @@ -384,8 +440,8 @@ b.y += center->y; /* compute first and second control points */ - length = FT_MulDiv( radius, FT_Sin(theta)*4, - (0x10000L + FT_Cos(theta))*3 ); + length = FT_MulDiv( radius, FT_Sin( theta ) * 4, + ( 0x10000L + FT_Cos( theta ) ) * 3 ); FT_Vector_From_Polar( &a2, length, angle + rotate ); a2.x += a.x; @@ -397,13 +453,15 @@ /* add cubic arc */ error = ft_stroke_border_cubicto( border, &a2, &b2, &b ); - if (error) break; + if ( error ) + break; /* process the rest of the arc ?? */ a = b; total -= step; angle = next; } + return error; } @@ -423,139 +481,149 @@ } - static void - ft_stroke_border_init( FT_StrokeBorder border, - FT_Memory memory ) - { - border->memory = memory; - border->points = NULL; - border->tags = NULL; + static void + ft_stroke_border_init( FT_StrokeBorder border, + FT_Memory memory ) + { + border->memory = memory; + border->points = NULL; + border->tags = NULL; - border->num_points = 0; - border->max_points = 0; - border->start = -1; - } + border->num_points = 0; + border->max_points = 0; + border->start = -1; + border->valid = 0; + } - static void - ft_stroke_border_reset( FT_StrokeBorder border ) - { - border->num_points = 0; - border->start = -1; - } + static void + ft_stroke_border_reset( FT_StrokeBorder border ) + { + border->num_points = 0; + border->start = -1; + border->valid = 0; + } - static void - ft_stroke_border_done( FT_StrokeBorder border ) - { - FT_Memory memory = border->memory; - - FT_FREE( border->points ); - FT_FREE( border->tags ); - - border->num_points = 0; - border->max_points = 0; - border->start = -1; - } + static void + ft_stroke_border_done( FT_StrokeBorder border ) + { + FT_Memory memory = border->memory; - static FT_Error - ft_stroke_border_get_counts( FT_StrokeBorder border, - FT_UInt *anum_points, - FT_UInt *anum_contours ) - { - FT_Error error = 0; - FT_UInt num_points = 0; - FT_UInt num_contours = 0; + FT_FREE( border->points ); + FT_FREE( border->tags ); - FT_UInt count = border->num_points; - FT_Vector* point = border->points; - FT_Byte* tags = border->tags; - FT_Int in_contour = 0; - - for ( ; count > 0; count--, num_points++, point++, tags++ ) - { - if ( tags[0] & FT_STROKE_TAG_BEGIN ) - { - if ( in_contour != 0 ) - goto Fail; - - in_contour = 1; - } - else if ( in_contour == 0 ) - goto Fail; - - if ( tags[0] & FT_STROKE_TAG_END ) - { - if ( in_contour == 0 ) - goto Fail; - - in_contour = 0; - num_contours++; - } - } - if ( in_contour != 0 ) - goto Fail; - - Exit: - *anum_points = num_points; - *anum_contours = num_contours; - return error; - - Fail: - num_points = 0; - num_contours = 0; - goto Exit; - } + border->num_points = 0; + border->max_points = 0; + border->start = -1; + border->valid = 0; + } - static void - ft_stroke_border_export( FT_StrokeBorder border, - FT_Outline* outline ) - { - /* copy point locations */ - FT_MEM_COPY( outline->points + outline->n_points, - border->points, - border->num_points * sizeof(FT_Vector) ); + static FT_Error + ft_stroke_border_get_counts( FT_StrokeBorder border, + FT_UInt *anum_points, + FT_UInt *anum_contours ) + { + FT_Error error = 0; + FT_UInt num_points = 0; + FT_UInt num_contours = 0; - /* copy tags */ - { - FT_UInt count = border->num_points; - FT_Byte* read = border->tags; - FT_Byte* write = (FT_Byte*) outline->tags + outline->n_points; + FT_UInt count = border->num_points; + FT_Vector* point = border->points; + FT_Byte* tags = border->tags; + FT_Int in_contour = 0; - for ( ; count > 0; count--, read++, write++ ) - { - if ( *read & FT_STROKE_TAG_ON ) - *write = FT_CURVE_TAG_ON; - else if ( *read & FT_STROKE_TAG_CUBIC ) - *write = FT_CURVE_TAG_CUBIC; - else - *write = FT_CURVE_TAG_CONIC; - } - } - /* copy contours */ - { - FT_UInt count = border->num_points; - FT_Byte* tags = border->tags; - FT_Short* write = outline->contours + outline->n_contours; - FT_Short index = (FT_Short) outline->n_points; + for ( ; count > 0; count--, num_points++, point++, tags++ ) + { + if ( tags[0] & FT_STROKE_TAG_BEGIN ) + { + if ( in_contour != 0 ) + goto Fail; - for ( ; count > 0; count--, tags++, index++ ) - { - if ( *tags & FT_STROKE_TAG_END ) - { - *write++ = index; - outline->n_contours++; - } - } - } + in_contour = 1; + } + else if ( in_contour == 0 ) + goto Fail; - outline->n_points = (short)( outline->n_points + border->num_points ); + if ( tags[0] & FT_STROKE_TAG_END ) + { + if ( in_contour == 0 ) + goto Fail; - FT_ASSERT( FT_Outline_Check( outline ) == 0 ); - } + in_contour = 0; + num_contours++; + } + } + + if ( in_contour != 0 ) + goto Fail; + + border->valid = 1; + + Exit: + *anum_points = num_points; + *anum_contours = num_contours; + return error; + + Fail: + num_points = 0; + num_contours = 0; + goto Exit; + } + + + static void + ft_stroke_border_export( FT_StrokeBorder border, + FT_Outline* outline ) + { + /* copy point locations */ + FT_ARRAY_COPY( outline->points + outline->n_points, + border->points, + border->num_points ); + + /* copy tags */ + { + FT_UInt count = border->num_points; + FT_Byte* read = border->tags; + FT_Byte* write = (FT_Byte*)outline->tags + outline->n_points; + + + for ( ; count > 0; count--, read++, write++ ) + { + if ( *read & FT_STROKE_TAG_ON ) + *write = FT_CURVE_TAG_ON; + else if ( *read & FT_STROKE_TAG_CUBIC ) + *write = FT_CURVE_TAG_CUBIC; + else + *write = FT_CURVE_TAG_CONIC; + } + } + + /* copy contours */ + { + FT_UInt count = border->num_points; + FT_Byte* tags = border->tags; + FT_Short* write = outline->contours + outline->n_contours; + FT_Short idx = (FT_Short)outline->n_points; + + + for ( ; count > 0; count--, tags++, idx++ ) + { + if ( *tags & FT_STROKE_TAG_END ) + { + *write++ = idx; + outline->n_contours++; + } + } + } + + outline->n_points = (short)( outline->n_points + border->num_points ); + + FT_ASSERT( FT_Outline_Check( outline ) == 0 ); + } /***************************************************************************/ @@ -566,9 +634,9 @@ /***************************************************************************/ /***************************************************************************/ -#define FT_SIDE_TO_ROTATE(s) (FT_ANGLE_PI2 - (s)*FT_ANGLE_PI) +#define FT_SIDE_TO_ROTATE( s ) ( FT_ANGLE_PI2 - (s) * FT_ANGLE_PI ) - typedef struct FT_StrokerRec_ + typedef struct FT_StrokerRec_ { FT_Angle angle_in; FT_Angle angle_out; @@ -597,6 +665,7 @@ FT_Error error; FT_Stroker stroker; + if ( !FT_NEW( stroker ) ) { stroker->memory = memory; @@ -621,10 +690,18 @@ stroker->line_join = line_join; stroker->miter_limit = miter_limit; - stroker->valid = 0; + FT_Stroker_Rewind( stroker ); + } - ft_stroke_border_reset( &stroker->borders[0] ); - ft_stroke_border_reset( &stroker->borders[1] ); + + FT_EXPORT_DEF( void ) + FT_Stroker_Rewind( FT_Stroker stroker ) + { + if ( stroker ) + { + ft_stroke_border_reset( &stroker->borders[0] ); + ft_stroke_border_reset( &stroker->borders[1] ); + } } @@ -635,6 +712,7 @@ { FT_Memory memory = stroker->memory; + ft_stroke_border_done( &stroker->borders[0] ); ft_stroke_border_done( &stroker->borders[1] ); @@ -644,22 +722,22 @@ } - - /* creates a circular arc at a corner or cap */ + /* creates a circular arc at a corner or cap */ static FT_Error ft_stroker_arcto( FT_Stroker stroker, FT_Int side ) { - FT_Angle total, rotate; - FT_Fixed radius = stroker->radius; - FT_Error error = 0; - FT_StrokeBorder border = stroker->borders + side; + FT_Angle total, rotate; + FT_Fixed radius = stroker->radius; + FT_Error error = 0; + FT_StrokeBorder border = stroker->borders + side; - rotate = FT_SIDE_TO_ROTATE(side); + + rotate = FT_SIDE_TO_ROTATE( side ); total = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); - if (total == FT_ANGLE_PI) - total = -rotate*2; + if ( total == FT_ANGLE_PI ) + total = -rotate * 2; error = ft_stroke_border_arcto( border, &stroker->center, @@ -679,6 +757,7 @@ { FT_Error error = 0; + if ( stroker->line_cap == FT_STROKER_LINECAP_ROUND ) { /* add a round cap */ @@ -689,21 +768,23 @@ else if ( stroker->line_cap == FT_STROKER_LINECAP_SQUARE ) { /* add a square cap */ - FT_Vector delta, delta2; - FT_Angle rotate = FT_SIDE_TO_ROTATE(side); - FT_Fixed radius = stroker->radius; - FT_StrokeBorder border = stroker->borders + side; + FT_Vector delta, delta2; + FT_Angle rotate = FT_SIDE_TO_ROTATE( side ); + FT_Fixed radius = stroker->radius; + FT_StrokeBorder border = stroker->borders + side; - FT_Vector_From_Polar( &delta2, radius, angle+rotate ); + + FT_Vector_From_Polar( &delta2, radius, angle + rotate ); FT_Vector_From_Polar( &delta, radius, angle ); delta.x += stroker->center.x + delta2.x; delta.y += stroker->center.y + delta2.y; error = ft_stroke_border_lineto( border, &delta, 0 ); - if (error) goto Exit; + if ( error ) + goto Exit; - FT_Vector_From_Polar( &delta2, radius, angle-rotate ); + FT_Vector_From_Polar( &delta2, radius, angle - rotate ); FT_Vector_From_Polar( &delta, radius, angle ); delta.x += delta2.x + stroker->center.x; @@ -711,13 +792,13 @@ error = ft_stroke_border_lineto( border, &delta, 0 ); } + Exit: return error; } - - /* process an inside corner, i.e. compute intersection */ + /* process an inside corner, i.e. compute intersection */ static FT_Error ft_stroker_inside( FT_Stroker stroker, FT_Int side) @@ -729,14 +810,14 @@ FT_Error error = 0; - rotate = FT_SIDE_TO_ROTATE(side); + rotate = FT_SIDE_TO_ROTATE( side ); /* compute median angle */ theta = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); if ( theta == FT_ANGLE_PI ) theta = rotate; else - theta = theta/2; + theta = theta / 2; phi = stroker->angle_in + theta; @@ -745,7 +826,8 @@ if ( sigma < 0x10000L ) { - FT_Vector_From_Polar( &delta, stroker->radius, stroker->angle_out + rotate ); + FT_Vector_From_Polar( &delta, stroker->radius, + stroker->angle_out + rotate ); delta.x += stroker->center.x; delta.y += stroker->center.y; border->movable = 0; @@ -765,7 +847,7 @@ } - /* process an outside corner, i.e. compute bevel/miter/round */ + /* process an outside corner, i.e. compute bevel/miter/round */ static FT_Error ft_stroker_outside( FT_Stroker stroker, FT_Int side ) @@ -774,6 +856,7 @@ FT_Error error; FT_Angle rotate; + if ( stroker->line_join == FT_STROKER_LINEJOIN_ROUND ) { error = ft_stroker_arcto( stroker, side ); @@ -781,54 +864,58 @@ else { /* this is a mitered or beveled corner */ - FT_Fixed sigma, radius = stroker->radius; - FT_Angle theta, phi; - FT_Fixed thcos; - FT_Bool miter; + FT_Fixed sigma, radius = stroker->radius; + FT_Angle theta, phi; + FT_Fixed thcos; + FT_Bool miter; - rotate = FT_SIDE_TO_ROTATE(side); + + rotate = FT_SIDE_TO_ROTATE( side ); miter = FT_BOOL( stroker->line_join == FT_STROKER_LINEJOIN_MITER ); theta = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); - if (theta == FT_ANGLE_PI) + if ( theta == FT_ANGLE_PI ) { theta = rotate; phi = stroker->angle_in; } else { - theta = theta/2; + theta = theta / 2; phi = stroker->angle_in + theta + rotate; } - thcos = FT_Cos( theta ); - sigma = FT_MulFix( stroker->miter_limit, thcos ); + thcos = FT_Cos( theta ); + sigma = FT_MulFix( stroker->miter_limit, thcos ); if ( sigma >= 0x10000L ) miter = 0; - - if (miter) /* this is a miter (broken angle) */ + if ( miter ) /* this is a miter (broken angle) */ { FT_Vector middle, delta; - FT_Fixed length; + FT_Fixed length; + /* compute middle point */ - FT_Vector_From_Polar( &middle, FT_MulFix( radius, stroker->miter_limit ), + FT_Vector_From_Polar( &middle, + FT_MulFix( radius, stroker->miter_limit ), phi ); middle.x += stroker->center.x; middle.y += stroker->center.y; /* compute first angle point */ - length = FT_MulFix( radius, FT_DivFix( 0x10000L - sigma, - ft_pos_abs( FT_Sin( theta ) ) ) ); + length = FT_MulFix( radius, + FT_DivFix( 0x10000L - sigma, + ft_pos_abs( FT_Sin( theta ) ) ) ); FT_Vector_From_Polar( &delta, length, phi + rotate ); delta.x += middle.x; delta.y += middle.y; error = ft_stroke_border_lineto( border, &delta, 0 ); - if (error) goto Exit; + if ( error ) + goto Exit; /* compute second angle point */ FT_Vector_From_Polar( &delta, length, phi - rotate ); @@ -836,7 +923,8 @@ delta.y += middle.y; error = ft_stroke_border_lineto( border, &delta, 0 ); - if (error) goto Exit; + if ( error ) + goto Exit; /* finally, add a movable end point */ FT_Vector_From_Polar( &delta, radius, stroker->angle_out + rotate ); @@ -845,11 +933,13 @@ error = ft_stroke_border_lineto( border, &delta, 1 ); } + else /* this is a bevel (intersection) */ { - FT_Fixed length; + FT_Fixed length; FT_Vector delta; + length = FT_DivFix( stroker->radius, thcos ); FT_Vector_From_Polar( &delta, length, phi ); @@ -860,13 +950,15 @@ if (error) goto Exit; /* now add end point */ - FT_Vector_From_Polar( &delta, stroker->radius, stroker->angle_out + rotate ); + FT_Vector_From_Polar( &delta, stroker->radius, + stroker->angle_out + rotate ); delta.x += stroker->center.x; delta.y += stroker->center.y; error = ft_stroke_border_lineto( border, &delta, 1 ); } } + Exit: return error; } @@ -879,33 +971,35 @@ FT_Angle turn; FT_Int inside_side; + turn = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); /* no specific corner processing is required if the turn is 0 */ - if (turn == 0) + if ( turn == 0 ) goto Exit; /* when we turn to the right, the inside side is 0 */ inside_side = 0; /* otherwise, the inside side is 1 */ - if (turn < 0) + if ( turn < 0 ) inside_side = 1; /* process the inside side */ error = ft_stroker_inside( stroker, inside_side ); - if (error) goto Exit; + if ( error ) + goto Exit; /* process the outside side */ - error = ft_stroker_outside( stroker, 1-inside_side ); + error = ft_stroker_outside( stroker, 1 - inside_side ); Exit: return error; } - /* add two points to the left and right borders corresponding to the */ - /* start of the subpath.. */ + /* add two points to the left and right borders corresponding to the */ + /* start of the subpath.. */ static FT_Error ft_stroker_subpath_start( FT_Stroker stroker, FT_Angle start_angle ) @@ -915,14 +1009,17 @@ FT_Error error; FT_StrokeBorder border; - FT_Vector_From_Polar( &delta, stroker->radius, start_angle + FT_ANGLE_PI2 ); + + FT_Vector_From_Polar( &delta, stroker->radius, + start_angle + FT_ANGLE_PI2 ); point.x = stroker->center.x + delta.x; point.y = stroker->center.y + delta.y; border = stroker->borders; error = ft_stroke_border_moveto( border, &point ); - if (error) goto Exit; + if ( error ) + goto Exit; point.x = stroker->center.x - delta.x; point.y = stroker->center.y - delta.y; @@ -958,18 +1055,20 @@ /* process corner if necessary */ if ( stroker->first_point ) { - /* this is the first segment of a subpath. We need to */ + /* This is the first segment of a subpath. We need to */ /* add a point to each border at their respective starting */ - /* point locations.. */ + /* point locations. */ error = ft_stroker_subpath_start( stroker, angle ); - if (error) goto Exit; + if ( error ) + goto Exit; } else { /* process the current corner */ stroker->angle_out = angle; error = ft_stroker_process_corner( stroker ); - if (error) goto Exit; + if ( error ) + goto Exit; } /* now add a line segment to both the "inside" and "outside" paths */ @@ -978,25 +1077,26 @@ { FT_Vector point; + point.x = to->x + delta.x; point.y = to->y + delta.y; error = ft_stroke_border_lineto( border, &point, 1 ); - if (error) goto Exit; + if ( error ) + goto Exit; delta.x = -delta.x; delta.y = -delta.y; } - stroker->angle_in = angle; - stroker->center = *to; + stroker->angle_in = angle; + stroker->center = *to; Exit: return error; } - FT_EXPORT_DEF( FT_Error ) FT_Stroker_ConicTo( FT_Stroker stroker, FT_Vector* control, @@ -1009,6 +1109,7 @@ FT_Angle start_angle; FT_Bool first_arc = 1; + arc = bez_stack; arc[0] = *to; arc[1] = *control; @@ -1018,9 +1119,10 @@ { FT_Angle angle_in, angle_out; + angle_in = angle_out = 0; /* remove compiler warnings */ - if ( arc < limit && + if ( arc < limit && !ft_conic_is_small_enough( arc, &angle_in, &angle_out ) ) { ft_conic_split( arc ); @@ -1044,21 +1146,22 @@ } } - /* the arc's angle is small enough, we can add it directly to each */ - /* border.. */ + /* the arc's angle is small enough; we can add it directly to each */ + /* border */ { FT_Vector ctrl, end; FT_Angle theta, phi, rotate; - FT_Fixed length; + FT_Fixed length; FT_Int side; - theta = FT_Angle_Diff( angle_in, angle_out )/2; + + theta = FT_Angle_Diff( angle_in, angle_out ) / 2; phi = angle_in + theta; - length = FT_DivFix( stroker->radius, FT_Cos(theta) ); + length = FT_DivFix( stroker->radius, FT_Cos( theta ) ); for ( side = 0; side <= 1; side++ ) { - rotate = FT_SIDE_TO_ROTATE(side); + rotate = FT_SIDE_TO_ROTATE( side ); /* compute control point */ FT_Vector_From_Polar( &ctrl, length, phi + rotate ); @@ -1070,14 +1173,16 @@ end.x += arc[0].x; end.y += arc[0].y; - error = ft_stroke_border_conicto( stroker->borders + side, &ctrl, &end ); - if (error) goto Exit; + error = ft_stroke_border_conicto( stroker->borders + side, + &ctrl, &end ); + if ( error ) + goto Exit; } } arc -= 2; - if (arc < bez_stack) + if ( arc < bez_stack ) stroker->angle_in = angle_out; } @@ -1088,12 +1193,11 @@ } - FT_EXPORT_DEF( FT_Error ) FT_Stroker_CubicTo( FT_Stroker stroker, - FT_Vector* control1, - FT_Vector* control2, - FT_Vector* to ) + FT_Vector* control1, + FT_Vector* control2, + FT_Vector* to ) { FT_Error error = 0; FT_Vector bez_stack[37]; @@ -1102,6 +1206,7 @@ FT_Angle start_angle; FT_Bool first_arc = 1; + arc = bez_stack; arc[0] = *to; arc[1] = *control2; @@ -1112,11 +1217,13 @@ { FT_Angle angle_in, angle_mid, angle_out; + /* remove compiler warnings */ angle_in = angle_out = angle_mid = 0; - if ( arc < limit && - !ft_cubic_is_small_enough( arc, &angle_in, &angle_mid, &angle_out ) ) + if ( arc < limit && + !ft_cubic_is_small_enough( arc, &angle_in, + &angle_mid, &angle_out ) ) { ft_cubic_split( arc ); arc += 3; @@ -1133,31 +1240,33 @@ if ( stroker->first_point ) error = ft_stroker_subpath_start( stroker, start_angle ); else - { - stroker->angle_out = start_angle; - error = ft_stroker_process_corner( stroker ); - } - if (error) goto Exit; + { + stroker->angle_out = start_angle; + error = ft_stroker_process_corner( stroker ); + } + if ( error ) + goto Exit; } - /* the arc's angle is small enough, we can add it directly to each */ - /* border.. */ + /* the arc's angle is small enough; we can add it directly to each */ + /* border */ { FT_Vector ctrl1, ctrl2, end; FT_Angle theta1, phi1, theta2, phi2, rotate; FT_Fixed length1, length2; FT_Int side; - theta1 = ft_pos_abs( angle_mid - angle_in )/2; - theta2 = ft_pos_abs( angle_out - angle_mid )/2; - phi1 = (angle_mid+angle_in)/2; - phi2 = (angle_mid+angle_out)/2; - length1 = FT_DivFix( stroker->radius, FT_Cos(theta1) ); + + theta1 = ft_pos_abs( angle_mid - angle_in ) / 2; + theta2 = ft_pos_abs( angle_out - angle_mid ) / 2; + phi1 = (angle_mid + angle_in ) / 2; + phi2 = (angle_mid + angle_out ) / 2; + length1 = FT_DivFix( stroker->radius, FT_Cos( theta1 ) ); length2 = FT_DivFix( stroker->radius, FT_Cos(theta2) ); for ( side = 0; side <= 1; side++ ) { - rotate = FT_SIDE_TO_ROTATE(side); + rotate = FT_SIDE_TO_ROTATE( side ); /* compute control points */ FT_Vector_From_Polar( &ctrl1, length1, phi1 + rotate ); @@ -1173,13 +1282,15 @@ end.x += arc[0].x; end.y += arc[0].y; - error = ft_stroke_border_cubicto( stroker->borders + side, &ctrl1, &ctrl2, &end ); - if (error) goto Exit; + error = ft_stroke_border_cubicto( stroker->borders + side, + &ctrl1, &ctrl2, &end ); + if ( error ) + goto Exit; } } arc -= 3; - if (arc < bez_stack) + if ( arc < bez_stack ) stroker->angle_in = angle_out; } @@ -1195,10 +1306,10 @@ FT_Vector* to, FT_Bool open ) { - /* we cannot process the first point, because there is not enough */ - /* information regarding its corner/cap. The latter will be processed */ - /* in the "end_subpath" routine */ - /* */ + /* We cannot process the first point, because there is not enough */ + /* information regarding its corner/cap. The latter will be processed */ + /* in the "end_subpath" routine. */ + /* */ stroker->first_point = 1; stroker->center = *to; stroker->subpath_open = open; @@ -1209,40 +1320,43 @@ } - static - FT_Error ft_stroker_add_reverse_left( FT_Stroker stroker, - FT_Bool open ) + static FT_Error + ft_stroker_add_reverse_left( FT_Stroker stroker, + FT_Bool open ) { FT_StrokeBorder right = stroker->borders + 0; FT_StrokeBorder left = stroker->borders + 1; FT_Int new_points; FT_Error error = 0; + FT_ASSERT( left->start >= 0 ); new_points = left->num_points - left->start; if ( new_points > 0 ) { error = ft_stroke_border_grow( right, (FT_UInt)new_points ); - if (error) goto Exit; + if ( error ) + goto Exit; + { - FT_Vector* dst_point = right->points + right->num_points; - FT_Byte* dst_tag = right->tags + right->num_points; - FT_Vector* src_point = left->points + left->num_points - 1; - FT_Byte* src_tag = left->tags + left->num_points - 1; + FT_Vector* dst_point = right->points + right->num_points; + FT_Byte* dst_tag = right->tags + right->num_points; + FT_Vector* src_point = left->points + left->num_points - 1; + FT_Byte* src_tag = left->tags + left->num_points - 1; while ( src_point >= left->points + left->start ) { *dst_point = *src_point; *dst_tag = *src_tag; - if (open) - dst_tag[0] &= ~(FT_STROKE_TAG_BEGIN | FT_STROKE_TAG_END); + if ( open ) + dst_tag[0] &= ~( FT_STROKE_TAG_BEGIN | FT_STROKE_TAG_END ); else { /* switch begin/end tags if necessary.. */ - if (dst_tag[0] & (FT_STROKE_TAG_BEGIN | FT_STROKE_TAG_END)) - dst_tag[0] ^= (FT_STROKE_TAG_BEGIN | FT_STROKE_TAG_END); + if ( dst_tag[0] & ( FT_STROKE_TAG_BEGIN | FT_STROKE_TAG_END ) ) + dst_tag[0] ^= ( FT_STROKE_TAG_BEGIN | FT_STROKE_TAG_END ); } src_point--; @@ -1251,18 +1365,20 @@ dst_tag++; } } + left->num_points = left->start; right->num_points += new_points; right->movable = 0; left->movable = 0; } + Exit: return error; } - /* there's a lot of magic in this function !! */ + /* there's a lot of magic in this function! */ FT_EXPORT_DEF( FT_Error ) FT_Stroker_EndSubPath( FT_Stroker stroker ) { @@ -1272,61 +1388,73 @@ { FT_StrokeBorder right = stroker->borders; - /* all right, this is an opened path, we need to add a cap between */ - /* right & left, add the reverse of left, then add a final cap between */ - /* left & right.. */ + /* All right, this is an opened path, we need to add a cap between */ + /* right & left, add the reverse of left, then add a final cap */ + /* between left & right. */ error = ft_stroker_cap( stroker, stroker->angle_in, 0 ); - if (error) goto Exit; + if ( error ) + goto Exit; /* add reversed points from "left" to "right" */ error = ft_stroker_add_reverse_left( stroker, 1 ); - if (error) goto Exit; + if ( error ) + goto Exit; /* now add the final cap */ stroker->center = stroker->subpath_start; - error = ft_stroker_cap( stroker, stroker->subpath_angle+FT_ANGLE_PI, 0 ); - if (error) goto Exit; + error = ft_stroker_cap( stroker, + stroker->subpath_angle + FT_ANGLE_PI, 0 ); + if ( error ) + goto Exit; - /* now, end the right subpath accordingly. the left one is */ - /* rewind and doesn't need further processing.. */ + /* Now end the right subpath accordingly. The left one is */ + /* rewind and doesn't need further processing. */ ft_stroke_border_close( right ); } else { - FT_Angle turn; - FT_Int inside_side; + FT_Angle turn; + FT_Int inside_side; - /* process the corner ... */ + /* close the path if needed */ + if ( stroker->center.x != stroker->subpath_start.x || + stroker->center.y != stroker->subpath_start.y ) + { + error = FT_Stroker_LineTo( stroker, &stroker->subpath_start ); + if ( error ) + goto Exit; + } + + /* process the corner */ stroker->angle_out = stroker->subpath_angle; - turn = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); + turn = FT_Angle_Diff( stroker->angle_in, + stroker->angle_out ); /* no specific corner processing is required if the turn is 0 */ - if (turn != 0) + if ( turn != 0 ) { /* when we turn to the right, the inside side is 0 */ inside_side = 0; /* otherwise, the inside side is 1 */ - if (turn < 0) + if ( turn < 0 ) inside_side = 1; - /* IMPORTANT: WE DO NOT PROCESS THE INSIDE BORDER HERE !! */ - /* process the inside side */ - /* error = ft_stroker_inside( stroker, inside_side ); - if (error) goto Exit; */ + /* IMPORTANT: WE DO NOT PROCESS THE INSIDE BORDER HERE! */ + /* process the inside side */ + /* error = ft_stroker_inside( stroker, inside_side ); */ + /* if ( error ) */ + /* goto Exit; */ /* process the outside side */ - error = ft_stroker_outside( stroker, 1-inside_side ); - if (error) goto Exit; + error = ft_stroker_outside( stroker, 1 - inside_side ); + if ( error ) + goto Exit; } - /* we will first end our two subpaths */ + /* then end our two subpaths */ ft_stroke_border_close( stroker->borders + 0 ); ft_stroke_border_close( stroker->borders + 1 ); - - /* now, add the reversed left subpath to "right" */ - error = ft_stroker_add_reverse_left( stroker, 0 ); - if (error) goto Exit; } Exit: @@ -1334,6 +1462,35 @@ } + FT_EXPORT_DEF( FT_Error ) + FT_Stroker_GetBorderCounts( FT_Stroker stroker, + FT_StrokerBorder border, + FT_UInt *anum_points, + FT_UInt *anum_contours ) + { + FT_UInt num_points = 0, num_contours = 0; + FT_Error error; + + + if ( !stroker || border > 1 ) + { + error = FT_Err_Invalid_Argument; + goto Exit; + } + + error = ft_stroke_border_get_counts( stroker->borders + border, + &num_points, &num_contours ); + Exit: + if ( anum_points ) + *anum_points = num_points; + + if ( anum_contours ) + *anum_contours = num_contours; + + return error; + } + + FT_EXPORT_DEF( FT_Error ) FT_Stroker_GetCounts( FT_Stroker stroker, FT_UInt *anum_points, @@ -1343,17 +1500,20 @@ FT_UInt count3, count4, num_contours = 0; FT_Error error; - error = ft_stroke_border_get_counts( stroker->borders+0, &count1, &count2 ); - if (error) goto Exit; - error = ft_stroke_border_get_counts( stroker->borders+1, &count3, &count4 ); - if (error) goto Exit; + error = ft_stroke_border_get_counts( stroker->borders + 0, + &count1, &count2 ); + if ( error ) + goto Exit; + + error = ft_stroke_border_get_counts( stroker->borders + 1, + &count3, &count4 ); + if ( error ) + goto Exit; num_points = count1 + count3; num_contours = count2 + count4; - stroker->valid = 1; - Exit: *anum_points = num_points; *anum_contours = num_contours; @@ -1362,24 +1522,35 @@ FT_EXPORT_DEF( void ) - FT_Stroker_Export( FT_Stroker stroker, - FT_Outline* outline ) + FT_Stroker_ExportBorder( FT_Stroker stroker, + FT_StrokerBorder border, + FT_Outline* outline ) { - if ( stroker->valid ) + if ( border == FT_STROKER_BORDER_LEFT || + border == FT_STROKER_BORDER_RIGHT ) { - ft_stroke_border_export( stroker->borders+0, outline ); - ft_stroke_border_export( stroker->borders+1, outline ); + FT_StrokeBorder sborder = & stroker->borders[border]; + + + if ( sborder->valid ) + ft_stroke_border_export( sborder, outline ); } } + FT_EXPORT_DEF( void ) + FT_Stroker_Export( FT_Stroker stroker, + FT_Outline* outline ) + { + FT_Stroker_ExportBorder( stroker, FT_STROKER_BORDER_LEFT, outline ); + FT_Stroker_ExportBorder( stroker, FT_STROKER_BORDER_RIGHT, outline ); + } - - /* - * the following is very similar to FT_Outline_Decompose, except - * that we do support opened paths, and do not scale the outline - */ + /* + * The following is very similar to FT_Outline_Decompose, except + * that we do support opened paths, and do not scale the outline. + */ FT_EXPORT_DEF( FT_Error ) FT_Stroker_ParseOutline( FT_Stroker stroker, FT_Outline* outline, @@ -1398,14 +1569,14 @@ FT_Int n; /* index of contour in outline */ FT_UInt first; /* index of first point in contour */ FT_Int tag; /* current point's state */ - FT_Int in_path; + if ( !outline || !stroker ) return FT_Err_Invalid_Argument; - first = 0; + FT_Stroker_Rewind( stroker ); - in_path = 0; + first = 0; for ( n = 0; n < outline->n_contours; n++ ) { @@ -1431,7 +1602,7 @@ /* check first point to determine origin */ if ( tag == FT_CURVE_TAG_CONIC ) { - /* first point is conic control. Yes, this happens. */ + /* First point is conic control. Yes, this happens. */ if ( FT_CURVE_TAG( outline->tags[last] ) == FT_CURVE_TAG_ON ) { /* start at last point if it is on the curve */ @@ -1456,8 +1627,6 @@ if ( error ) goto Exit; - in_path = 1; - while ( point < limit ) { point++; @@ -1574,4 +1743,164 @@ Invalid_Outline: return FT_Err_Invalid_Outline; - } + } + + + extern const FT_Glyph_Class ft_outline_glyph_class; + + + FT_EXPORT_DEF( FT_Error ) + FT_Glyph_Stroke( FT_Glyph *pglyph, + FT_Stroker stroker, + FT_Bool destroy ) + { + FT_Error error = FT_Err_Invalid_Argument; + FT_Glyph glyph = NULL; + + + if ( pglyph == NULL ) + goto Exit; + + glyph = *pglyph; + if ( glyph == NULL || glyph->clazz != &ft_outline_glyph_class ) + goto Exit; + + { + FT_Glyph copy; + + + error = FT_Glyph_Copy( glyph, © ); + if ( error ) + goto Exit; + + glyph = copy; + } + + { + FT_OutlineGlyph oglyph = (FT_OutlineGlyph) glyph; + FT_Outline* outline = &oglyph->outline; + FT_UInt num_points, num_contours; + + + error = FT_Stroker_ParseOutline( stroker, outline, 0 ); + if ( error ) + goto Fail; + + (void)FT_Stroker_GetCounts( stroker, &num_points, &num_contours ); + + FT_Outline_Done( glyph->library, outline ); + + error = FT_Outline_New( glyph->library, + num_points, num_contours, outline ); + if ( error ) + goto Fail; + + outline->n_points = 0; + outline->n_contours = 0; + + FT_Stroker_Export( stroker, outline ); + } + + if ( destroy ) + FT_Done_Glyph( *pglyph ); + + *pglyph = glyph; + goto Exit; + + Fail: + FT_Done_Glyph( glyph ); + glyph = NULL; + + if ( !destroy ) + *pglyph = NULL; + + Exit: + return error; + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Glyph_StrokeBorder( FT_Glyph *pglyph, + FT_Stroker stroker, + FT_Bool inside, + FT_Bool destroy ) + { + FT_Error error = FT_Err_Invalid_Argument; + FT_Glyph glyph = NULL; + + + if ( pglyph == NULL ) + goto Exit; + + glyph = *pglyph; + if ( glyph == NULL || glyph->clazz != &ft_outline_glyph_class ) + goto Exit; + + { + FT_Glyph copy; + + + error = FT_Glyph_Copy( glyph, © ); + if ( error ) + goto Exit; + + glyph = copy; + } + + { + FT_OutlineGlyph oglyph = (FT_OutlineGlyph) glyph; + FT_StrokerBorder border; + FT_Outline* outline = &oglyph->outline; + FT_UInt num_points, num_contours; + + + border = FT_Outline_GetOutsideBorder( outline ); + if ( inside ) + { + if ( border == FT_STROKER_BORDER_LEFT ) + border = FT_STROKER_BORDER_RIGHT; + else + border = FT_STROKER_BORDER_LEFT; + } + + error = FT_Stroker_ParseOutline( stroker, outline, 0 ); + if ( error ) + goto Fail; + + (void)FT_Stroker_GetBorderCounts( stroker, border, + &num_points, &num_contours ); + + FT_Outline_Done( glyph->library, outline ); + + error = FT_Outline_New( glyph->library, + num_points, + num_contours, + outline ); + if ( error ) + goto Fail; + + outline->n_points = 0; + outline->n_contours = 0; + + FT_Stroker_ExportBorder( stroker, border, outline ); + } + + if ( destroy ) + FT_Done_Glyph( *pglyph ); + + *pglyph = glyph; + goto Exit; + + Fail: + FT_Done_Glyph( glyph ); + glyph = NULL; + + if ( !destroy ) + *pglyph = NULL; + + Exit: + return error; + } + + +/* END */ diff --git a/src/libs/freetype2/base/ftsynth.c b/src/libs/freetype2/base/ftsynth.c index 8a8fabdc25..cee36822fd 100644 --- a/src/libs/freetype2/base/ftsynth.c +++ b/src/libs/freetype2/base/ftsynth.c @@ -4,7 +4,7 @@ /* */ /* FreeType synthesizing code for emboldening and slanting (body). */ /* */ -/* Copyright 2000-2001 by */ +/* Copyright 2000-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -82,14 +82,14 @@ /* we need to compute the `previous' and `next' point */ /* for these extrema. */ - cur = outline->points + n; - prev = cur - 1; - next = cur + 1; + cur = outline->points + n; + prev = cur - 1; + next = cur + 1; first = 0; for ( c = 0; c < outline->n_contours; c++ ) { - last = outline->contours[c]; + last = outline->contours[c]; if ( n == first ) prev = outline->points + last; @@ -279,8 +279,9 @@ first = last + 1; } - slot->metrics.horiAdvance = ( slot->metrics.horiAdvance + distance*4 ) & -64; + slot->metrics.horiAdvance = + ( slot->metrics.horiAdvance + distance*4 ) & ~63; } -/* END */ +/* END */ diff --git a/src/libs/freetype2/base/ftsysio.c b/src/libs/freetype2/base/ftsysio.c index 05cb518d43..344ee516dd 100644 --- a/src/libs/freetype2/base/ftsysio.c +++ b/src/libs/freetype2/base/ftsysio.c @@ -128,4 +128,4 @@ ft_object_create( clazz, pathname, FT_OBJECT_P(astream) ); } - + diff --git a/src/libs/freetype2/base/ftsysmem.c b/src/libs/freetype2/base/ftsysmem.c index b6a0dd1fcf..6a34f693f3 100644 --- a/src/libs/freetype2/base/ftsysmem.c +++ b/src/libs/freetype2/base/ftsysmem.c @@ -27,4 +27,4 @@ }; FT_APIVAR_DEF( const FT_Memory_Funcs ) - ft_memory_funcs_default = &ft_memory_funcs_defaults_rec; + ft_memory_funcs_default = &ft_memory_funcs_defaults_rec; diff --git a/src/libs/freetype2/base/ftsystem.c b/src/libs/freetype2/base/ftsystem.c index 73db9f0956..2365de2571 100644 --- a/src/libs/freetype2/base/ftsystem.c +++ b/src/libs/freetype2/base/ftsystem.c @@ -300,4 +300,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/base/fttrigon.c b/src/libs/freetype2/base/fttrigon.c index cc50b5e12b..5347dd852a 100644 --- a/src/libs/freetype2/base/fttrigon.c +++ b/src/libs/freetype2/base/fttrigon.c @@ -4,7 +4,7 @@ /* */ /* FreeType trigonometric functions (body). */ /* */ -/* Copyright 2001 by */ +/* Copyright 2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,6 +17,7 @@ #include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H #include FT_TRIGONOMETRY_H @@ -71,10 +72,10 @@ val = ( val >= 0 ) ? val : -val; v1 = (FT_UInt32)val >> 16; - v2 = (FT_UInt32)val & 0xFFFF; + v2 = (FT_UInt32)val & 0xFFFFL; k1 = FT_TRIG_SCALE >> 16; /* constant */ - k2 = FT_TRIG_SCALE & 0xFFFF; /* constant */ + k2 = FT_TRIG_SCALE & 0xFFFFL; /* constant */ hi = k1 * v1; lo1 = k1 * v2 + k2 * v1; /* can't overflow */ @@ -271,9 +272,9 @@ /* round theta */ if ( theta >= 0 ) - theta = ( theta + 16 ) & -32; + theta = FT_PAD_ROUND( theta, 32 ); else - theta = - (( -theta + 16 ) & -32); + theta = - FT_PAD_ROUND( -theta, 32 ); vec->x = x; vec->y = theta; @@ -356,6 +357,14 @@ } + /* these macros return 0 for positive numbers, + and -1 for negative ones */ +#define FT_SIGN_LONG( x ) ( (x) >> ( FT_SIZEOF_LONG * 8 - 1 ) ) +#define FT_SIGN_INT( x ) ( (x) >> ( FT_SIZEOF_INT * 8 - 1 ) ) +#define FT_SIGN_INT32( x ) ( (x) >> 31 ) +#define FT_SIGN_INT16( x ) ( (x) >> 15 ) + + /* documentation is in fttrigon.h */ FT_EXPORT_DEF( void ) @@ -376,10 +385,13 @@ v.x = ft_trig_downscale( v.x ); v.y = ft_trig_downscale( v.y ); - if ( shift >= 0 ) + if ( shift > 0 ) { - vec->x = v.x >> shift; - vec->y = v.y >> shift; + FT_Int32 half = 1L << ( shift - 1 ); + + + vec->x = ( v.x + half + FT_SIGN_LONG( v.x ) ) >> shift; + vec->y = ( v.y + half + FT_SIGN_LONG( v.y ) ) >> shift; } else { @@ -484,4 +496,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/base/fttype1.c b/src/libs/freetype2/base/fttype1.c index fad6ae5b93..553b84f56f 100644 --- a/src/libs/freetype2/base/fttype1.c +++ b/src/libs/freetype2/base/fttype1.c @@ -4,7 +4,7 @@ /* */ /* FreeType utility file for PS names support (body). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,9 +17,9 @@ #include <ft2build.h> -#include FT_INTERNAL_TYPE1_TYPES_H -#include FT_INTERNAL_TYPE42_TYPES_H #include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_SERVICE_H +#include FT_SERVICE_POSTSCRIPT_INFO_H /* documentation is in t1tables.h */ @@ -28,60 +28,43 @@ FT_Get_PS_Font_Info( FT_Face face, PS_FontInfoRec* afont_info ) { - PS_FontInfo font_info = NULL; - FT_Error error = FT_Err_Invalid_Argument; - const char* driver_name; + FT_Error error = FT_Err_Invalid_Argument; - if ( face && face->driver && face->driver->root.clazz ) + if ( face ) { - driver_name = face->driver->root.clazz->module_name; - if ( ft_strcmp( driver_name, "type1" ) == 0 ) - font_info = &((T1_Face)face)->type1.font_info; - else if ( ft_strcmp( driver_name, "t1cid" ) == 0 ) - font_info = &((CID_Face)face)->cid.font_info; - else if ( ft_strcmp( driver_name, "type42" ) == 0 ) - font_info = &((T42_Face)face)->type1.font_info; - } - if ( font_info != NULL ) - { - *afont_info = *font_info; - error = FT_Err_Ok; + FT_Service_PsInfo service = NULL; + + + FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO ); + + if ( service && service->ps_get_font_info ) + error = service->ps_get_font_info( face, afont_info ); } return error; } - /* XXX: Bad hack, but I didn't want to change several drivers here. */ - /* documentation is in t1tables.h */ FT_EXPORT_DEF( FT_Int ) FT_Has_PS_Glyph_Names( FT_Face face ) { - FT_Int result = 0; - const char* driver_name; + FT_Int result = 0; + FT_Service_PsInfo service = NULL; - if ( face && face->driver && face->driver->root.clazz ) + if ( face ) { - /* Currently, only the type1, type42, and cff drivers provide */ - /* reliable glyph names... */ + FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO ); - /* We could probably hack the TrueType driver to recognize */ - /* certain cases where the glyph names are most certainly */ - /* correct (e.g. using a 20 or 22 format `post' table), but */ - /* this will probably happen later... */ - - driver_name = face->driver->root.clazz->module_name; - result = ( ft_strcmp( driver_name, "type1" ) == 0 || - ft_strcmp( driver_name, "type42" ) == 0 || - ft_strcmp( driver_name, "cff" ) == 0 ); + if ( service && service->ps_has_glyph_names ) + result = service->ps_has_glyph_names( face ); } return result; } -/* END */ +/* END */ diff --git a/src/libs/freetype2/base/ftutil.c b/src/libs/freetype2/base/ftutil.c index f3244dfa27..451bee524c 100644 --- a/src/libs/freetype2/base/ftutil.c +++ b/src/libs/freetype2/base/ftutil.c @@ -327,4 +327,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/base/ftwinfnt.c b/src/libs/freetype2/base/ftwinfnt.c index b8db7d363d..46f618c518 100644 --- a/src/libs/freetype2/base/ftwinfnt.c +++ b/src/libs/freetype2/base/ftwinfnt.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing Windows FNT specific info (body). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,38 +18,32 @@ #include <ft2build.h> #include FT_WINFONTS_H -#include FT_INTERNAL_FNT_TYPES_H #include FT_INTERNAL_OBJECTS_H +#include FT_SERVICE_WINFNT_H FT_EXPORT_DEF( FT_Error ) - FT_Get_WinFNT_Header( FT_Face face, - FT_WinFNT_HeaderRec *header ) + FT_Get_WinFNT_Header( FT_Face face, + FT_WinFNT_HeaderRec *header ) { - FT_Error error; + FT_Service_WinFnt service; + FT_Error error; + error = FT_Err_Invalid_Argument; - if ( face != NULL && face->driver != NULL ) + if ( face != NULL ) { - FT_Module driver = (FT_Module) face->driver; + FT_FACE_LOOKUP_SERVICE( face, service, WINFNT ); - - if ( driver->clazz && driver->clazz->module_name && - ft_strcmp( driver->clazz->module_name, "winfonts" ) == 0 ) + if ( service != NULL ) { - FNT_Size size = (FNT_Size)face->size; - FNT_Font font = size->font; - - if (font) - { - FT_MEM_COPY( header, &font->header, sizeof(*header) ); - error = 0; - } + error = service->get_header( face, header ); } } + return error; } -/* END */ +/* END */ diff --git a/src/libs/freetype2/base/ftxf86.c b/src/libs/freetype2/base/ftxf86.c index 614d888922..04e80236e6 100644 --- a/src/libs/freetype2/base/ftxf86.c +++ b/src/libs/freetype2/base/ftxf86.c @@ -4,7 +4,7 @@ /* */ /* FreeType utility file for X11 support (body). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,62 +19,19 @@ #include <ft2build.h> #include FT_XFREE86_H #include FT_INTERNAL_OBJECTS_H - - /* XXX: This really is a sad hack, but I didn't want to change every */ - /* driver just to support this at the moment, since other important */ - /* changes are coming anyway. */ - - typedef struct FT_FontFormatRec_ - { - const char* driver_name; - const char* format_name; - - } FT_FontFormatRec; - +#include FT_SERVICE_XFREE86_NAME_H FT_EXPORT_DEF( const char* ) FT_Get_X11_Font_Format( FT_Face face ) { - static const FT_FontFormatRec font_formats[] = - { - { "type1", "Type 1" }, - { "truetype", "TrueType" }, - { "bdf", "BDF" }, - { "pcf", "PCF" }, - { "type42", "Type 42" }, - { "cidtype1", "CID Type 1" }, - { "cff", "CFF" }, - { "pfr", "PFR" }, - { "winfonts", "Windows FNT" } - }; - const char* result = NULL; - if ( face && face->driver ) - { - FT_Module driver = (FT_Module)face->driver; - - - if ( driver->clazz && driver->clazz->module_name ) - { - FT_Int n; - FT_Int count = sizeof( font_formats ) / sizeof ( font_formats[0] ); - - - result = driver->clazz->module_name; - - for ( n = 0; n < count; n++ ) - if ( ft_strcmp( result, font_formats[n].driver_name ) == 0 ) - { - result = font_formats[n].format_name; - break; - } - } - } + if ( face ) + FT_FACE_FIND_SERVICE( face, result, XF86_NAME ); return result; } -/* END */ +/* END */ diff --git a/src/libs/freetype2/base/rules.mk b/src/libs/freetype2/base/rules.mk index 3b63bcc702..8017e8589f 100644 --- a/src/libs/freetype2/base/rules.mk +++ b/src/libs/freetype2/base/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2002 by +# Copyright 1996-2000, 2002, 2003, 2004 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -25,23 +25,24 @@ # BASE_H is defined in freetype.mk to simplify the dependency rules. -BASE_COMPILE := $(FT_COMPILE) $I$(SRC_)base +BASE_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(SRC_DIR)/base) # Base layer sources # # ftsystem, ftinit, and ftdebug are handled by freetype.mk # -BASE_SRC := $(BASE_)ftcalc.c \ - $(BASE_)fttrigon.c \ - $(BASE_)ftutil.c \ - $(BASE_)ftstream.c \ - $(BASE_)ftgloadr.c \ - $(BASE_)ftoutln.c \ - $(BASE_)ftobjs.c \ - $(BASE_)ftapi.c \ - $(BASE_)ftnames.c \ - $(BASE_)ftdbgmem.c +BASE_SRC := $(BASE_DIR)/ftapi.c \ + $(BASE_DIR)/ftcalc.c \ + $(BASE_DIR)/ftdbgmem.c \ + $(BASE_DIR)/ftgloadr.c \ + $(BASE_DIR)/ftnames.c \ + $(BASE_DIR)/ftobjs.c \ + $(BASE_DIR)/ftoutln.c \ + $(BASE_DIR)/ftrfork.c \ + $(BASE_DIR)/ftstream.c \ + $(BASE_DIR)/fttrigon.c \ + $(BASE_DIR)/ftutil.c # Base layer `extensions' sources # @@ -49,19 +50,19 @@ BASE_SRC := $(BASE_)ftcalc.c \ # object. It will then be linked to the final executable only if one of its # symbols is used by the application. # -BASE_EXT_SRC := $(BASE_)ftglyph.c \ - $(BASE_)ftmm.c \ - $(BASE_)ftbdf.c \ - $(BASE_)fttype1.c \ - $(BASE_)ftxf86.c \ - $(BASE_)ftpfr.c \ - $(BASE_)ftstroker.c \ - $(BASE_)ftwinfnt.c \ - $(BASE_)ftbbox.c +BASE_EXT_SRC := $(BASE_DIR)/ftbbox.c \ + $(BASE_DIR)/ftbdf.c \ + $(BASE_DIR)/ftglyph.c \ + $(BASE_DIR)/ftmm.c \ + $(BASE_DIR)/ftpfr.c \ + $(BASE_DIR)/ftstroke.c \ + $(BASE_DIR)/fttype1.c \ + $(BASE_DIR)/ftwinfnt.c \ + $(BASE_DIR)/ftxf86.c # Default extensions objects # -BASE_EXT_OBJ := $(BASE_EXT_SRC:$(BASE_)%.c=$(OBJ_)%.$O) +BASE_EXT_OBJ := $(BASE_EXT_SRC:$(BASE_DIR)/%.c=$(OBJ_DIR)/%.$O) # Base layer object(s) @@ -72,23 +73,24 @@ BASE_EXT_OBJ := $(BASE_EXT_SRC:$(BASE_)%.c=$(OBJ_)%.$O) # BASE_OBJ_S is used during `single' builds (the whole base layer is # compiled as a single object file using ftbase.c). # -BASE_OBJ_M := $(BASE_SRC:$(BASE_)%.c=$(OBJ_)%.$O) -BASE_OBJ_S := $(OBJ_)ftbase.$O +BASE_OBJ_M := $(BASE_SRC:$(BASE_DIR)/%.c=$(OBJ_DIR)/%.$O) +BASE_OBJ_S := $(OBJ_DIR)/ftbase.$O # Base layer root source file for single build # -BASE_SRC_S := $(BASE_)ftbase.c +BASE_SRC_S := $(BASE_DIR)/ftbase.c # Base layer - single object build # $(BASE_OBJ_S): $(BASE_SRC_S) $(BASE_SRC) $(FREETYPE_H) - $(BASE_COMPILE) $T$@ $(BASE_SRC_S) + $(BASE_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(BASE_SRC_S)) # Multiple objects build + extensions # -$(OBJ_)%.$O: $(BASE_)%.c $(FREETYPE_H) - $(BASE_COMPILE) $T$@ $< +$(OBJ_DIR)/%.$O: $(BASE_DIR)/%.c $(FREETYPE_H) + $(BASE_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) -# EOF + +# EOF diff --git a/src/libs/freetype2/bdf/README b/src/libs/freetype2/bdf/README index 73785b4e8f..d45e4fb15a 100644 --- a/src/libs/freetype2/bdf/README +++ b/src/libs/freetype2/bdf/README @@ -145,4 +145,4 @@ Credits This driver is based on excellent Mark Leisher's bdf library. If you find something good in this driver you should probably thank him, not -me. +me. diff --git a/src/libs/freetype2/bdf/bdf.c b/src/libs/freetype2/bdf/bdf.c index 26f969e57f..9c828853e1 100644 --- a/src/libs/freetype2/bdf/bdf.c +++ b/src/libs/freetype2/bdf/bdf.c @@ -31,4 +31,4 @@ THE SOFTWARE. #include "bdfdrivr.c" -/* END */ +/* END */ diff --git a/src/libs/freetype2/bdf/bdf.h b/src/libs/freetype2/bdf/bdf.h index 2f093fc03a..4dab5ae9d0 100644 --- a/src/libs/freetype2/bdf/bdf.h +++ b/src/libs/freetype2/bdf/bdf.h @@ -1,6 +1,6 @@ /* * Copyright 2000 Computing Research Labs, New Mexico State University - * Copyright 2001, 2002 Francesco Zappa Nardelli + * Copyright 2001, 2002, 2003 Francesco Zappa Nardelli * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -159,8 +159,8 @@ FT_BEGIN_HEADER typedef struct _hashnode_ { - char* key; - void* data; + const char* key; + void* data; } _hashnode, *hashnode; @@ -283,7 +283,7 @@ FT_BEGIN_HEADER FT_LOCAL( bdf_property_t * ) bdf_get_font_property( bdf_font_t* font, - char* name ); + const char* name ); FT_END_HEADER @@ -292,4 +292,4 @@ FT_END_HEADER #endif /* __BDF_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/bdf/bdfdrivr.c b/src/libs/freetype2/bdf/bdfdrivr.c index 21615715c3..2e8f93ca6b 100644 --- a/src/libs/freetype2/bdf/bdfdrivr.c +++ b/src/libs/freetype2/bdf/bdfdrivr.c @@ -2,7 +2,7 @@ FreeType font driver for bdf files - Copyright (C) 2001-2002 by + Copyright (C) 2001, 2002, 2003, 2004 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy @@ -31,6 +31,9 @@ THE SOFTWARE. #include FT_INTERNAL_OBJECTS_H #include FT_BDF_H +#include FT_SERVICE_BDF_H +#include FT_SERVICE_XFREE86_NAME_H + #include "bdf.h" #include "bdfdrivr.h" @@ -65,7 +68,7 @@ THE SOFTWARE. cmap->num_encodings = face->bdffont->glyphs_used; cmap->encodings = face->en_table; - return FT_Err_Ok; + return BDF_Err_Ok; } @@ -169,6 +172,116 @@ THE SOFTWARE. }; + static FT_Error + bdf_interpret_style( BDF_Face bdf ) + { + FT_Error error = BDF_Err_Ok; + FT_Face face = FT_FACE( bdf ); + FT_Memory memory = face->memory; + bdf_font_t* font = bdf->bdffont; + bdf_property_t* prop; + + char *istr = NULL, *bstr = NULL; + char *sstr = NULL, *astr = NULL; + + int parts = 0, len = 0; + + + face->style_flags = 0; + + prop = bdf_get_font_property( font, (char *)"SLANT" ); + if ( prop && prop->format == BDF_ATOM && + prop->value.atom && + ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' || + *(prop->value.atom) == 'I' || *(prop->value.atom) == 'i' ) ) + { + face->style_flags |= FT_STYLE_FLAG_ITALIC; + istr = ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' ) + ? (char *)"Oblique" + : (char *)"Italic"; + len += ft_strlen( istr ); + parts++; + } + + prop = bdf_get_font_property( font, (char *)"WEIGHT_NAME" ); + if ( prop && prop->format == BDF_ATOM && + prop->value.atom && + ( *(prop->value.atom) == 'B' || *(prop->value.atom) == 'b' ) ) + { + face->style_flags |= FT_STYLE_FLAG_BOLD; + bstr = (char *)"Bold"; + len += ft_strlen( bstr ); + parts++; + } + + prop = bdf_get_font_property( font, (char *)"SETWIDTH_NAME" ); + if ( prop && prop->format == BDF_ATOM && + prop->value.atom && *(prop->value.atom) && + !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) + { + sstr = (char *)(prop->value.atom); + len += ft_strlen( sstr ); + parts++; + } + + prop = bdf_get_font_property( font, (char *)"ADD_STYLE_NAME" ); + if ( prop && prop->format == BDF_ATOM && + prop->value.atom && *(prop->value.atom) && + !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) + { + astr = (char *)(prop->value.atom); + len += ft_strlen( astr ); + parts++; + } + + if ( !parts || !len ) + face->style_name = (char *)"Regular"; + else + { + char *style, *s; + unsigned int i; + + + if ( FT_ALLOC( style, len + parts ) ) + return error; + + s = style; + + if ( astr ) + { + ft_strcpy( s, astr ); + for ( i = 0; i < ft_strlen( astr ); i++, s++ ) + if ( *s == ' ' ) + *s = '-'; /* replace spaces with dashes */ + *(s++) = ' '; + } + if ( bstr ) + { + ft_strcpy( s, bstr ); + s += ft_strlen( bstr ); + *(s++) = ' '; + } + if ( istr ) + { + ft_strcpy( s, istr ); + s += ft_strlen( istr ); + *(s++) = ' '; + } + if ( sstr ) + { + ft_strcpy( s, sstr ); + for ( i = 0; i < ft_strlen( sstr ); i++, s++ ) + if ( *s == ' ' ) + *s = '-'; /* replace spaces with dashes */ + *(s++) = ' '; + } + *(--s) = '\0'; /* overwrite last ' ', terminate the string */ + + face->style_name = style; /* allocated string */ + } + + return error; + } FT_CALLBACK_DEF( FT_Error ) @@ -250,35 +363,18 @@ THE SOFTWARE. FT_FACE_FLAG_HORIZONTAL | FT_FACE_FLAG_FAST_GLYPHS; - prop = bdf_get_font_property( font, (char *)"SPACING" ); - if ( prop != NULL ) - if ( prop->format == BDF_ATOM ) - if ( prop->value.atom != NULL ) - if ( ( *(prop->value.atom) == 'M' ) || - ( *(prop->value.atom) == 'C' ) ) - root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; + prop = bdf_get_font_property( font, "SPACING" ); + if ( prop && prop->format == BDF_ATOM && + prop->value.atom && + ( *(prop->value.atom) == 'M' || *(prop->value.atom) == 'm' || + *(prop->value.atom) == 'C' || *(prop->value.atom) == 'c' ) ) + root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; /* FZ XXX: TO DO: FT_FACE_FLAGS_VERTICAL */ /* FZ XXX: I need a font to implement this */ - root->style_flags = 0; - prop = bdf_get_font_property( font, (char *)"SLANT" ); - if ( prop != NULL ) - if ( prop->format == BDF_ATOM ) - if ( prop->value.atom != NULL ) - if ( ( *(prop->value.atom) == 'O' ) || - ( *(prop->value.atom) == 'I' ) ) - root->style_flags |= FT_STYLE_FLAG_ITALIC; - - prop = bdf_get_font_property( font, (char *)"WEIGHT_NAME" ); - if ( prop != NULL ) - if ( prop->format == BDF_ATOM ) - if ( prop->value.atom != NULL ) - if ( *(prop->value.atom) == 'B' ) - root->style_flags |= FT_STYLE_FLAG_BOLD; - - prop = bdf_get_font_property( font, (char *)"FAMILY_NAME" ); - if ( ( prop != NULL ) && ( prop->value.atom != NULL ) ) + prop = bdf_get_font_property( font, "FAMILY_NAME" ); + if ( prop && prop->value.atom ) { int l = ft_strlen( prop->value.atom ) + 1; @@ -290,16 +386,8 @@ THE SOFTWARE. else root->family_name = 0; - root->style_name = (char *)"Regular"; - if ( root->style_flags & FT_STYLE_FLAG_BOLD ) - { - if ( root->style_flags & FT_STYLE_FLAG_ITALIC ) - root->style_name = (char *)"Bold Italic"; - else - root->style_name = (char *)"Bold"; - } - else if ( root->style_flags & FT_STYLE_FLAG_ITALIC ) - root->style_name = (char *)"Italic"; + if ( ( error = bdf_interpret_style( face ) ) != 0 ) + goto Exit; root->num_glyphs = font->glyphs_size; /* unencoded included */ @@ -307,45 +395,50 @@ THE SOFTWARE. if ( FT_NEW_ARRAY( root->available_sizes, 1 ) ) goto Exit; - prop = bdf_get_font_property( font, (char *)"AVERAGE_WIDTH" ); - if ( ( prop != NULL ) && ( prop->value.int32 >= 10 ) ) - root->available_sizes->width = (short)( prop->value.int32 / 10 ); - - prop = bdf_get_font_property( font, (char *)"PIXEL_SIZE" ); - if ( prop != NULL ) - root->available_sizes->height = (short) prop->value.int32; - else { - prop = bdf_get_font_property( font, (char *)"POINT_SIZE" ); - if ( prop != NULL ) - { - bdf_property_t *yres; + FT_Bitmap_Size* bsize = root->available_sizes; + FT_Short resolution_x = 0, resolution_y = 0; - yres = bdf_get_font_property( font, (char *)"RESOLUTION_Y" ); - if ( yres != NULL ) - { - FT_TRACE4(( "POINT_SIZE: %d RESOLUTION_Y: %d\n", - prop->value.int32, yres->value.int32 )); - root->available_sizes->height = - (FT_Short)( prop->value.int32 * yres->value.int32 / 720 ); - } - } - } + FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) ); - if ( root->available_sizes->width == 0 ) - { - if ( root->available_sizes->height == 0 ) - { - /* some fonts have broken SIZE declaration (jiskan24.bdf) */ - FT_ERROR(( "BDF_Face_Init: reading size\n" )); - root->available_sizes->width = (FT_Short)font->point_size; - } + bsize->height = font->font_ascent + font->font_descent; + + prop = bdf_get_font_property( font, "AVERAGE_WIDTH" ); + if ( prop ) + bsize->width = (FT_Short)( ( prop->value.int32 + 5 ) / 10 ); else - root->available_sizes->width = root->available_sizes->height; + bsize->width = bsize->height * 2/3; + + prop = bdf_get_font_property( font, "POINT_SIZE" ); + if ( prop ) + /* convert from 722.7 decipoints to 72 points per inch */ + bsize->size = + (FT_Pos)( ( prop->value.int32 * 64 * 7200 + 36135L ) / 72270L ); + + prop = bdf_get_font_property( font, "PIXEL_SIZE" ); + if ( prop ) + bsize->y_ppem = (FT_Short)prop->value.int32 << 6; + + prop = bdf_get_font_property( font, "RESOLUTION_X" ); + if ( prop ) + resolution_x = (FT_Short)prop->value.int32; + + prop = bdf_get_font_property( font, "RESOLUTION_Y" ); + if ( prop ) + resolution_y = (FT_Short)prop->value.int32; + + if ( bsize->y_ppem == 0 ) + { + bsize->y_ppem = bsize->size; + if ( resolution_y ) + bsize->y_ppem = bsize->y_ppem * resolution_y / 72; + } + if ( resolution_x && resolution_y ) + bsize->x_ppem = bsize->y_ppem * resolution_x / resolution_y; + else + bsize->x_ppem = bsize->y_ppem; } - if ( root->available_sizes->height == 0 ) - root->available_sizes->height = root->available_sizes->width; /* encoding table */ { @@ -371,28 +464,42 @@ THE SOFTWARE. charset_registry = - bdf_get_font_property( font, (char *)"CHARSET_REGISTRY" ); + bdf_get_font_property( font, "CHARSET_REGISTRY" ); charset_encoding = - bdf_get_font_property( font, (char *)"CHARSET_ENCODING" ); - if ( ( charset_registry != NULL ) && ( charset_encoding != NULL ) ) + bdf_get_font_property( font, "CHARSET_ENCODING" ); + if ( charset_registry && charset_encoding ) { - if ( ( charset_registry->format == BDF_ATOM ) && - ( charset_encoding->format == BDF_ATOM ) && - ( charset_registry->value.atom != NULL ) && - ( charset_encoding->value.atom != NULL ) ) + if ( charset_registry->format == BDF_ATOM && + charset_encoding->format == BDF_ATOM && + charset_registry->value.atom && + charset_encoding->value.atom ) { + const char* s; + + if ( FT_NEW_ARRAY( face->charset_encoding, - strlen( charset_encoding->value.atom ) + 1 ) ) + ft_strlen( charset_encoding->value.atom ) + 1 ) ) goto Exit; if ( FT_NEW_ARRAY( face->charset_registry, - strlen( charset_registry->value.atom ) + 1 ) ) + ft_strlen( charset_registry->value.atom ) + 1 ) ) goto Exit; + ft_strcpy( face->charset_registry, charset_registry->value.atom ); ft_strcpy( face->charset_encoding, charset_encoding->value.atom ); - if ( !ft_strcmp( face->charset_registry, "ISO10646" ) || - ( !ft_strcmp( face->charset_registry, "ISO8859" ) && - !ft_strcmp( face->charset_encoding, "1" ) ) ) + + /* Uh, oh, compare first letters manually to avoid dependency + on locales. */ + s = face->charset_registry; + if ( ( s[0] == 'i' || s[0] == 'I' ) && + ( s[1] == 's' || s[1] == 'S' ) && + ( s[2] == 'o' || s[2] == 'O' ) ) + { + s += 3; + if ( !ft_strcmp( s, "10646" ) || + ( !ft_strcmp( s, "8859" ) && + !ft_strcmp( face->charset_encoding, "1" ) ) ) unicode_charmap = 1; + } { FT_CharMapRec charmap; @@ -460,13 +567,15 @@ THE SOFTWARE. FT_TRACE4(( "rec %d - pres %d\n", - size->metrics.y_ppem, root->available_sizes->height )); + size->metrics.y_ppem, root->available_sizes->y_ppem )); - if ( size->metrics.y_ppem == root->available_sizes->height ) + if ( size->metrics.y_ppem == root->available_sizes->y_ppem >> 6 ) { - size->metrics.ascender = face->bdffont->bbx.ascent << 6; - size->metrics.descender = face->bdffont->bbx.descent * ( -64 ); - size->metrics.height = face->bdffont->bbx.height << 6; + size->metrics.ascender = face->bdffont->font_ascent << 6; + size->metrics.descender = -face->bdffont->font_descent << 6; + size->metrics.height = ( face->bdffont->font_ascent + + face->bdffont->font_descent ) << 6; + size->metrics.max_advance = face->bdffont->bbx.width << 6; return BDF_Err_Ok; } @@ -611,14 +720,13 @@ THE SOFTWARE. } } - slot->bitmap_left = 0; + slot->bitmap_left = glyph.bbx.x_offset; slot->bitmap_top = glyph.bbx.ascent; /* FZ XXX: TODO: vertical metrics */ slot->metrics.horiAdvance = glyph.dwidth << 6; slot->metrics.horiBearingX = glyph.bbx.x_offset << 6; - slot->metrics.horiBearingY = ( glyph.bbx.y_offset + - glyph.bbx.height ) << 6; + slot->metrics.horiBearingY = glyph.bbx.ascent << 6; slot->metrics.width = bitmap->width << 6; slot->metrics.height = bitmap->rows << 6; @@ -630,6 +738,12 @@ THE SOFTWARE. } + /* + * + * BDF SERVICE + * + */ + static FT_Error bdf_get_bdf_property( BDF_Face face, const char* prop_name, @@ -637,37 +751,71 @@ THE SOFTWARE. { bdf_property_t* prop; + FT_ASSERT( face && face->bdffont ); - prop = bdf_get_font_property( face->bdffont, (char*)prop_name ); - if ( prop != NULL ) + prop = bdf_get_font_property( face->bdffont, prop_name ); + if ( prop ) { switch ( prop->format ) { - case BDF_ATOM: - aproperty->type = BDF_PROPERTY_TYPE_ATOM; - aproperty->u.atom = prop->value.atom; - break; + case BDF_ATOM: + aproperty->type = BDF_PROPERTY_TYPE_ATOM; + aproperty->u.atom = prop->value.atom; + break; - case BDF_INTEGER: - aproperty->type = BDF_PROPERTY_TYPE_INTEGER; - aproperty->u.integer = prop->value.int32; - break; + case BDF_INTEGER: + aproperty->type = BDF_PROPERTY_TYPE_INTEGER; + aproperty->u.integer = prop->value.int32; + break; - case BDF_CARDINAL: - aproperty->type = BDF_PROPERTY_TYPE_CARDINAL; - aproperty->u.cardinal = prop->value.card32; - break; + case BDF_CARDINAL: + aproperty->type = BDF_PROPERTY_TYPE_CARDINAL; + aproperty->u.cardinal = prop->value.card32; + break; - default: - goto Fail; + default: + goto Fail; } return 0; } + Fail: - return FT_Err_Invalid_Argument; + return BDF_Err_Invalid_Argument; } + static FT_Error + bdf_get_charset_id( BDF_Face face, + const char* *acharset_encoding, + const char* *acharset_registry ) + { + *acharset_encoding = face->charset_encoding; + *acharset_registry = face->charset_registry; + + return 0; + } + + + static const FT_Service_BDFRec bdf_service_bdf = + { + (FT_BDF_GetCharsetIdFunc)bdf_get_charset_id, + (FT_BDF_GetPropertyFunc) bdf_get_bdf_property + }; + + + /* + * + * SERVICES LIST + * + */ + + static const FT_ServiceDescRec bdf_services[] = + { + { FT_SERVICE_ID_BDF, &bdf_service_bdf }, + { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_BDF }, + { NULL, NULL } + }; + static FT_Module_Interface bdf_driver_requester( FT_Module module, @@ -675,18 +823,17 @@ THE SOFTWARE. { FT_UNUSED( module ); - if ( name && ft_strcmp( name, "get_bdf_property" ) == 0 ) - return (FT_Module_Interface) bdf_get_bdf_property; - - return NULL; + return ft_service_list_lookup( bdf_services, name ); } + FT_CALLBACK_TABLE_DEF const FT_Driver_ClassRec bdf_driver_class = { { - ft_module_font_driver, + FT_MODULE_FONT_DRIVER | + FT_MODULE_DRIVER_NO_OUTLINES, sizeof ( FT_DriverRec ), "bdf", @@ -722,4 +869,4 @@ THE SOFTWARE. }; -/* END */ +/* END */ diff --git a/src/libs/freetype2/bdf/bdfdrivr.h b/src/libs/freetype2/bdf/bdfdrivr.h index 70265bc83e..148041ff24 100644 --- a/src/libs/freetype2/bdf/bdfdrivr.h +++ b/src/libs/freetype2/bdf/bdfdrivr.h @@ -2,7 +2,7 @@ FreeType font driver for bdf fonts - Copyright (C) 2001, 2002 by + Copyright (C) 2001, 2002, 2003 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy @@ -39,8 +39,8 @@ FT_BEGIN_HEADER typedef struct BDF_encoding_el_ { - FT_ULong enc; - FT_Short glyph; + FT_ULong enc; + FT_UShort glyph; } BDF_encoding_el; @@ -71,4 +71,4 @@ FT_END_HEADER #endif /* __BDFDRIVR_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/bdf/bdferror.h b/src/libs/freetype2/bdf/bdferror.h index d2a046791d..b27fa333bb 100644 --- a/src/libs/freetype2/bdf/bdferror.h +++ b/src/libs/freetype2/bdf/bdferror.h @@ -41,4 +41,4 @@ #endif /* __BDFERROR_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/bdf/bdflib.c b/src/libs/freetype2/bdf/bdflib.c index 9deeb90c04..be0e3987e4 100644 --- a/src/libs/freetype2/bdf/bdflib.c +++ b/src/libs/freetype2/bdf/bdflib.c @@ -1,6 +1,6 @@ /* * Copyright 2000 Computing Research Labs, New Mexico State University - * Copyright 2001, 2002 Francesco Zappa Nardelli + * Copyright 2001, 2002, 2003, 2004 Francesco Zappa Nardelli * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -163,7 +163,7 @@ { (char *)"_MULE_RELATIVE_COMPOSE", BDF_INTEGER, 1, { 0 } }, }; - static unsigned long + static const unsigned long _num_bdf_properties = sizeof ( _bdf_properties ) / sizeof ( _bdf_properties[0] ); @@ -183,10 +183,10 @@ (*hash_free_func)( hashnode node ); static hashnode* - hash_bucket( char* key, - hashtable* ht ) + hash_bucket( const char* key, + hashtable* ht ) { - char* kp = key; + const char* kp = key; unsigned long res = 0; hashnode* bp = ht->table, *ndp; @@ -317,7 +317,7 @@ static hashnode - hash_lookup( char* key, + hash_lookup( const char* key, hashtable* ht ) { hashnode *np = hash_bucket( key, ht ); @@ -391,7 +391,7 @@ /* An empty string for empty fields. */ - static char empty[1] = { 0 }; /* XXX eliminate this */ + static const char empty[1] = { 0 }; /* XXX eliminate this */ /* Assume the line is NULL-terminated and that the `list' parameter */ @@ -468,7 +468,7 @@ } /* Assign the field appropriately. */ - list->field[list->used++] = ( ep > sp ) ? sp : empty; + list->field[list->used++] = ( ep > sp ) ? sp : (char*)empty; sp = ep; @@ -511,7 +511,7 @@ } if ( final_empty ) - list->field[list->used++] = empty; + list->field[list->used++] = (char*)empty; if ( list->used == list->size ) { @@ -641,7 +641,7 @@ { _bdf_line_func_t cb; unsigned long lineno; - int n, res, done, refill, bytes, hold; + int n, done, refill, bytes, hold; char *ls, *le, *pp, *pe, *hp; char *buf = 0; FT_Memory memory = stream->memory; @@ -661,7 +661,7 @@ lineno = 1; buf[0] = 0; - res = done = 0; + done = 0; pp = ls = le = buf; bytes = 65536L; @@ -696,7 +696,7 @@ le -= n; n = pe - pp; - FT_MEM_COPY( buf, pp, n ); + FT_MEM_MOVE( buf, pp, n ); pp = buf + n; bytes = 65536L - n; @@ -1443,7 +1443,6 @@ unsigned char* bp; unsigned long i, slen, nibbles; - _bdf_line_func_t* next; _bdf_parse_t* p; bdf_glyph_t* glyph; bdf_font_t* font; @@ -1451,11 +1450,11 @@ FT_Memory memory; FT_Error error = BDF_Err_Ok; + FT_UNUSED( call_data ); FT_UNUSED( lineno ); /* only used in debug mode */ - next = (_bdf_line_func_t *)call_data; - p = (_bdf_parse_t *) client_data; + p = (_bdf_parse_t *)client_data; font = p->font; memory = font->memory; @@ -1771,14 +1770,14 @@ /* Determine the overall font bounding box as the characters are */ /* loaded so corrections can be done later if indicated. */ - p->maxas = (short)MAX( glyph->bbx.ascent, p->maxas ); - p->maxds = (short)MAX( glyph->bbx.descent, p->maxds ); + p->maxas = (short)FT_MAX( glyph->bbx.ascent, p->maxas ); + p->maxds = (short)FT_MAX( glyph->bbx.descent, p->maxds ); p->rbearing = (short)( glyph->bbx.width + glyph->bbx.x_offset ); - p->maxrb = (short)MAX( p->rbearing, p->maxrb ); - p->minlb = (short)MIN( glyph->bbx.x_offset, p->minlb ); - p->maxlb = (short)MAX( glyph->bbx.x_offset, p->maxlb ); + p->maxrb = (short)FT_MAX( p->rbearing, p->maxrb ); + p->minlb = (short)FT_MIN( glyph->bbx.x_offset, p->minlb ); + p->maxlb = (short)FT_MAX( glyph->bbx.x_offset, p->maxlb ); if ( !( p->flags & _BDF_DWIDTH ) ) { @@ -1883,7 +1882,7 @@ /* */ /* This is *always* done regardless of the options, because X11 */ /* requires these two fields to compile fonts. */ - if ( bdf_get_font_property( p->font, (char *)"FONT_ASCENT" ) == 0 ) + if ( bdf_get_font_property( p->font, "FONT_ASCENT" ) == 0 ) { p->font->font_ascent = p->font->bbx.ascent; ft_sprintf( nbuf, "%hd", p->font->bbx.ascent ); @@ -1895,7 +1894,7 @@ p->font->modified = 1; } - if ( bdf_get_font_property( p->font, (char *)"FONT_DESCENT" ) == 0 ) + if ( bdf_get_font_property( p->font, "FONT_DESCENT" ) == 0 ) { p->font->font_descent = p->font->bbx.descent; ft_sprintf( nbuf, "%hd", p->font->bbx.descent ); @@ -2419,7 +2418,7 @@ FT_LOCAL_DEF( bdf_property_t * ) bdf_get_font_property( bdf_font_t* font, - char* name ) + const char* name ) { hashnode hn; @@ -2433,4 +2432,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/bdf/descrip.mms b/src/libs/freetype2/bdf/descrip.mms index 834ae7819d..4c32dc4499 100644 --- a/src/libs/freetype2/bdf/descrip.mms +++ b/src/libs/freetype2/bdf/descrip.mms @@ -20,4 +20,4 @@ OBJS=bdf.obj all : $(OBJS) library [--.lib]freetype.olb $(OBJS) -# EOF +# EOF diff --git a/src/libs/freetype2/bdf/module.mk b/src/libs/freetype2/bdf/module.mk index db0c262e1b..24115e75d0 100644 --- a/src/libs/freetype2/bdf/module.mk +++ b/src/libs/freetype2/bdf/module.mk @@ -28,4 +28,4 @@ make_module_list: add_bdf_driver add_bdf_driver: $(OPEN_DRIVER)bdf_driver_class$(CLOSE_DRIVER) $(ECHO_DRIVER)bdf $(ECHO_DRIVER_DESC)bdf bitmap fonts$(ECHO_DRIVER_DONE) - + diff --git a/src/libs/freetype2/bdf/rules.mk b/src/libs/freetype2/bdf/rules.mk index eacaea768a..25d98e55b0 100644 --- a/src/libs/freetype2/bdf/rules.mk +++ b/src/libs/freetype2/bdf/rules.mk @@ -3,7 +3,7 @@ # -# Copyright (C) 2001, 2002 by +# Copyright (C) 2001, 2002, 2003 by # Francesco Zappa Nardelli # # Permission is hereby granted, free of charge, to any person obtaining a copy @@ -29,46 +29,46 @@ # bdf driver directory # -BDF_DIR := $(SRC_)bdf -BDF_DIR_ := $(BDF_DIR)$(SEP) +BDF_DIR := $(SRC_DIR)/bdf -BDF_COMPILE := $(FT_COMPILE) $I$(BDF_DIR) +BDF_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(BDF_DIR)) # bdf driver sources (i.e., C files) # -BDF_DRV_SRC := $(BDF_DIR_)bdflib.c $(BDF_DIR_)bdfdrivr.c +BDF_DRV_SRC := $(BDF_DIR)/bdflib.c \ + $(BDF_DIR)/bdfdrivr.c # bdf driver headers # -BDF_DRV_H := $(BDF_DIR_)bdf.h \ - $(BDF_DIR_)bdfdrivr.h +BDF_DRV_H := $(BDF_DIR)/bdf.h \ + $(BDF_DIR)/bdfdrivr.h # bdf driver object(s) # # BDF_DRV_OBJ_M is used during `multi' builds # BDF_DRV_OBJ_S is used during `single' builds # -BDF_DRV_OBJ_M := $(BDF_DRV_SRC:$(BDF_DIR_)%.c=$(OBJ_)%.$O) -BDF_DRV_OBJ_S := $(OBJ_)bdf.$O +BDF_DRV_OBJ_M := $(BDF_DRV_SRC:$(BDF_DIR)/%.c=$(OBJ_DIR)/%.$O) +BDF_DRV_OBJ_S := $(OBJ_DIR)/bdf.$O # bdf driver source file for single build # -BDF_DRV_SRC_S := $(BDF_DIR_)bdf.c +BDF_DRV_SRC_S := $(BDF_DIR)/bdf.c # bdf driver - single object # $(BDF_DRV_OBJ_S): $(BDF_DRV_SRC_S) $(BDF_DRV_SRC) $(FREETYPE_H) $(BDF_DRV_H) - $(BDF_COMPILE) $T$@ $(BDF_DRV_SRC_S) + $(BDF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(BDF_DRV_SRC_S)) # bdf driver - multiple objects # -$(OBJ_)%.$O: $(BDF_DIR_)%.c $(FREETYPE_H) $(BDF_DRV_H) - $(BDF_COMPILE) $T$@ $< +$(OBJ_DIR)/%.$O: $(BDF_DIR)/%.c $(FREETYPE_H) $(BDF_DRV_H) + $(BDF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) # update main driver object lists @@ -76,4 +76,5 @@ $(OBJ_)%.$O: $(BDF_DIR_)%.c $(FREETYPE_H) $(BDF_DRV_H) DRV_OBJS_S += $(BDF_DRV_OBJ_S) DRV_OBJS_M += $(BDF_DRV_OBJ_M) -# EOF + +# EOF diff --git a/src/libs/freetype2/cache/descrip.mms b/src/libs/freetype2/cache/descrip.mms index c3e71ff3f3..4d967dc181 100644 --- a/src/libs/freetype2/cache/descrip.mms +++ b/src/libs/freetype2/cache/descrip.mms @@ -3,7 +3,7 @@ # -# Copyright 2001, 2002 by +# Copyright 2001, 2002, 2003, 2004 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -20,7 +20,6 @@ OBJS=ftcache.obj all : $(OBJS) library [--.lib]freetype.olb $(OBJS) -ftcache.obj : ftcache.c ftlru.c ftcmanag.c ftccache.c ftcglyph.c ftcimage.c \ - ftcsbits.c ftccmap.c +ftcache.obj : ftcache.c -# EOF +# EOF diff --git a/src/libs/freetype2/cache/ftcache.c b/src/libs/freetype2/cache/ftcache.c index f6b4b2a73b..d41e91e5ec 100644 --- a/src/libs/freetype2/cache/ftcache.c +++ b/src/libs/freetype2/cache/ftcache.c @@ -4,7 +4,7 @@ /* */ /* The FreeType Caching sub-system (body only). */ /* */ -/* Copyright 2000-2001 by */ +/* Copyright 2000-2001, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,13 +19,13 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT #include <ft2build.h> -#include "ftlru.c" +#include "ftcmru.c" #include "ftcmanag.c" #include "ftccache.c" +#include "ftccmap.c" #include "ftcglyph.c" #include "ftcimage.c" #include "ftcsbits.c" -#include "ftccmap.c" +#include "ftcbasic.c" - -/* END */ +/* END */ diff --git a/src/libs/freetype2/cache/ftcbasic.c b/src/libs/freetype2/cache/ftcbasic.c new file mode 100644 index 0000000000..5d5061cfb2 --- /dev/null +++ b/src/libs/freetype2/cache/ftcbasic.c @@ -0,0 +1,425 @@ +/***************************************************************************/ +/* */ +/* ftcbasic.c */ +/* */ +/* The FreeType basic cache interface (body). */ +/* */ +/* Copyright 2003, 2004 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. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_CACHE_H +#include FT_CACHE_INTERNAL_GLYPH_H +#include FT_CACHE_INTERNAL_IMAGE_H +#include FT_CACHE_INTERNAL_SBITS_H +#include FT_INTERNAL_MEMORY_H + +#include "ftccback.h" +#include "ftcerror.h" + + + /* + * Basic Families + * + */ + typedef struct FTC_BasicAttrRec_ + { + FTC_ScalerRec scaler; + FT_UInt load_flags; + + } FTC_BasicAttrRec, *FTC_BasicAttrs; + +#define FTC_BASIC_ATTR_COMPARE( a, b ) \ + ( FTC_SCALER_COMPARE( &(a)->scaler, &(b)->scaler ) && \ + (a)->load_flags == (b)->load_flags ) + +#define FTC_BASIC_ATTR_HASH( a ) \ + ( FTC_SCALER_HASH( &(a)->scaler ) + 31*(a)->load_flags ) + + + typedef struct FTC_BasicQueryRec_ + { + FTC_GQueryRec gquery; + FTC_BasicAttrRec attrs; + + } FTC_BasicQueryRec, *FTC_BasicQuery; + + + typedef struct FTC_BasicFamilyRec_ + { + FTC_FamilyRec family; + FTC_BasicAttrRec attrs; + + } FTC_BasicFamilyRec, *FTC_BasicFamily; + + + FT_CALLBACK_DEF( FT_Bool ) + ftc_basic_family_compare( FTC_BasicFamily family, + FTC_BasicQuery query ) + { + return FT_BOOL( FTC_BASIC_ATTR_COMPARE( &family->attrs, &query->attrs ) ); + } + + + FT_CALLBACK_DEF( FT_Error ) + ftc_basic_family_init( FTC_BasicFamily family, + FTC_BasicQuery query, + FTC_Cache cache ) + { + FTC_Family_Init( FTC_FAMILY( family ), cache ); + family->attrs = query->attrs; + return 0; + } + + + FT_CALLBACK_DEF( FT_UInt ) + ftc_basic_family_get_count( FTC_BasicFamily family, + FTC_Manager manager ) + { + FT_Error error; + FT_Face face; + FT_UInt result = 0; + + + error = FTC_Manager_LookupFace( manager, family->attrs.scaler.face_id, + &face ); + if ( !error ) + result = face->num_glyphs; + + return result; + } + + + FT_CALLBACK_DEF( FT_Error ) + ftc_basic_family_load_bitmap( FTC_BasicFamily family, + FT_UInt gindex, + FTC_Manager manager, + FT_Face *aface ) + { + FT_Error error; + FT_Size size; + + + error = FTC_Manager_LookupSize( manager, &family->attrs.scaler, &size ); + if ( !error ) + { + FT_Face face = size->face; + + + error = FT_Load_Glyph( face, gindex, + family->attrs.load_flags | FT_LOAD_RENDER ); + if ( !error ) + *aface = face; + } + + return error; + } + + + FT_CALLBACK_DEF( FT_Error ) + ftc_basic_family_load_glyph( FTC_BasicFamily family, + FT_UInt gindex, + FTC_Cache cache, + FT_Glyph *aglyph ) + { + FT_Error error; + FTC_Scaler scaler = &family->attrs.scaler; + FT_Face face; + FT_Size size; + + + /* we will now load the glyph image */ + error = FTC_Manager_LookupSize( cache->manager, + scaler, + &size ); + if ( !error ) + { + face = size->face; + + error = FT_Load_Glyph( face, gindex, family->attrs.load_flags ); + if ( !error ) + { + if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP || + face->glyph->format == FT_GLYPH_FORMAT_OUTLINE ) + { + /* ok, copy it */ + FT_Glyph glyph; + + + error = FT_Get_Glyph( face->glyph, &glyph ); + if ( !error ) + { + *aglyph = glyph; + goto Exit; + } + } + else + error = FTC_Err_Invalid_Argument; + } + } + + Exit: + return error; + } + + + FT_CALLBACK_DEF( FT_Bool ) + ftc_basic_gnode_compare_faceid( FTC_GNode gnode, + FTC_FaceID face_id, + FTC_Cache cache ) + { + FTC_BasicFamily family = (FTC_BasicFamily)gnode->family; + FT_Bool result; + + + result = FT_BOOL( family->attrs.scaler.face_id == face_id ); + if ( result ) + { + /* we must call this function to avoid this node from appearing + * in later lookups with the same face_id! + */ + FTC_GNode_UnselectFamily( gnode, cache ); + } + return result; + } + + + /* + * + * basic image cache + * + */ + + FT_CALLBACK_TABLE_DEF + const FTC_IFamilyClassRec ftc_basic_image_family_class = + { + { + sizeof( FTC_BasicFamilyRec ), + (FTC_MruNode_CompareFunc)ftc_basic_family_compare, + (FTC_MruNode_InitFunc) ftc_basic_family_init, + (FTC_MruNode_ResetFunc) NULL, + (FTC_MruNode_DoneFunc) NULL + }, + (FTC_IFamily_LoadGlyphFunc)ftc_basic_family_load_glyph + }; + + + FT_CALLBACK_TABLE_DEF + const FTC_GCacheClassRec ftc_basic_image_cache_class = + { + { + (FTC_Node_NewFunc) ftc_inode_new, + (FTC_Node_WeightFunc) ftc_inode_weight, + (FTC_Node_CompareFunc)ftc_gnode_compare, + (FTC_Node_CompareFunc)ftc_basic_gnode_compare_faceid, + (FTC_Node_FreeFunc) ftc_inode_free, + + sizeof( FTC_GCacheRec ), + (FTC_Cache_InitFunc) ftc_gcache_init, + (FTC_Cache_DoneFunc) ftc_gcache_done + }, + (FTC_MruListClass)&ftc_basic_image_family_class + }; + + + FT_EXPORT_DEF( FT_Error ) + FTC_ImageCache_New( FTC_Manager manager, + FTC_ImageCache *acache ) + { + return FTC_GCache_New( manager, &ftc_basic_image_cache_class, + (FTC_GCache*)acache ); + } + + + /* documentation is in ftcimage.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_ImageCache_Lookup( FTC_ImageCache cache, + FTC_ImageType type, + FT_UInt gindex, + FT_Glyph *aglyph, + FTC_Node *anode ) + { + FTC_BasicQueryRec query; + FTC_INode node; + FT_Error error; + FT_UInt32 hash; + + + /* some argument checks are delayed to FTC_Cache_Lookup */ + if ( !aglyph ) + { + error = FTC_Err_Invalid_Argument; + goto Exit; + } + + *aglyph = NULL; + if ( anode ) + *anode = NULL; + + query.attrs.scaler.face_id = type->face_id; + query.attrs.scaler.width = type->width; + query.attrs.scaler.height = type->height; + query.attrs.scaler.pixel = 1; + query.attrs.load_flags = type->flags; + + query.attrs.scaler.x_res = 0; /* make compilers happy */ + query.attrs.scaler.y_res = 0; + + hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + gindex; + +#if 1 /* inlining is about 50% faster! */ + FTC_GCACHE_LOOKUP_CMP( cache, + ftc_basic_family_compare, + FTC_GNode_Compare, + hash, gindex, + &query, + node, + error ); +#else + error = FTC_GCache_Lookup( FTC_GCACHE( cache ), + hash, gindex, + FTC_GQUERY( &query ), + (FTC_Node*) &node ); +#endif + if ( !error ) + { + *aglyph = FTC_INODE( node )->glyph; + + if ( anode ) + { + *anode = FTC_NODE( node ); + FTC_NODE( node )->ref_count++; + } + } + + Exit: + return error; + } + + + /* + * + * basic small bitmap cache + * + */ + + + FT_CALLBACK_TABLE_DEF + const FTC_SFamilyClassRec ftc_basic_sbit_family_class = + { + { + sizeof( FTC_BasicFamilyRec ), + (FTC_MruNode_CompareFunc)ftc_basic_family_compare, + (FTC_MruNode_InitFunc) ftc_basic_family_init, + (FTC_MruNode_ResetFunc) NULL, + (FTC_MruNode_DoneFunc) NULL + }, + (FTC_SFamily_GetCountFunc) ftc_basic_family_get_count, + (FTC_SFamily_LoadGlyphFunc)ftc_basic_family_load_bitmap + }; + + + FT_CALLBACK_TABLE_DEF + const FTC_GCacheClassRec ftc_basic_sbit_cache_class = + { + { + (FTC_Node_NewFunc) ftc_snode_new, + (FTC_Node_WeightFunc) ftc_snode_weight, + (FTC_Node_CompareFunc)ftc_snode_compare, + (FTC_Node_CompareFunc)ftc_basic_gnode_compare_faceid, + (FTC_Node_FreeFunc) ftc_snode_free, + + sizeof( FTC_GCacheRec ), + (FTC_Cache_InitFunc) ftc_gcache_init, + (FTC_Cache_DoneFunc) ftc_gcache_done + }, + (FTC_MruListClass)&ftc_basic_sbit_family_class + }; + + + FT_EXPORT_DEF( FT_Error ) + FTC_SBitCache_New( FTC_Manager manager, + FTC_SBitCache *acache ) + { + return FTC_GCache_New( manager, &ftc_basic_sbit_cache_class, + (FTC_GCache*)acache ); + } + + + FT_EXPORT_DEF( FT_Error ) + FTC_SBitCache_Lookup( FTC_SBitCache cache, + FTC_ImageType type, + FT_UInt gindex, + FTC_SBit *ansbit, + FTC_Node *anode ) + { + FT_Error error; + FTC_BasicQueryRec query; + FTC_SNode node; + FT_UInt32 hash; + + + if ( anode ) + *anode = NULL; + + /* other argument checks delayed to FTC_Cache_Lookup */ + if ( !ansbit ) + return FTC_Err_Invalid_Argument; + + *ansbit = NULL; + + query.attrs.scaler.face_id = type->face_id; + query.attrs.scaler.width = type->width; + query.attrs.scaler.height = type->height; + query.attrs.scaler.pixel = 1; + query.attrs.load_flags = type->flags; + + query.attrs.scaler.x_res = 0; /* make compilers happy */ + query.attrs.scaler.y_res = 0; + + /* beware, the hash must be the same for all glyph ranges! */ + hash = FTC_BASIC_ATTR_HASH( &query.attrs ) + + gindex / FTC_SBIT_ITEMS_PER_NODE; + +#if 1 /* inlining is about 50% faster! */ + FTC_GCACHE_LOOKUP_CMP( cache, + ftc_basic_family_compare, + FTC_SNode_Compare, + hash, gindex, + &query, + node, + error ); +#else + error = FTC_GCache_Lookup( FTC_GCACHE( cache ), + hash, + gindex, + FTC_GQUERY( &query ), + (FTC_Node*)&node ); +#endif + if ( error ) + goto Exit; + + *ansbit = node->sbits + ( gindex - FTC_GNODE( node )->gindex ); + + if ( anode ) + { + *anode = FTC_NODE( node ); + FTC_NODE( node )->ref_count++; + } + + Exit: + return error; + } + + +/* END */ diff --git a/src/libs/freetype2/cache/ftccache.c b/src/libs/freetype2/cache/ftccache.c index 6f273c1655..2b6bee9cfe 100644 --- a/src/libs/freetype2/cache/ftccache.c +++ b/src/libs/freetype2/cache/ftccache.c @@ -4,7 +4,7 @@ /* */ /* The FreeType internal cache interface (body). */ /* */ -/* Copyright 2000-2001, 2002 by */ +/* Copyright 2000-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,10 +17,11 @@ #include <ft2build.h> -#include FT_CACHE_MANAGER_H +#include FT_CACHE_INTERNAL_MANAGER_H #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H +#include "ftccback.h" #include "ftcerror.h" @@ -40,53 +41,13 @@ /*************************************************************************/ /*************************************************************************/ - FT_EXPORT_DEF( void ) - ftc_node_done( FTC_Node node, - FTC_Cache cache ) - { - FTC_Family family; - FTC_FamilyEntry entry; - - - entry = cache->manager->families.entries + node->fam_index; - family = entry->family; - - /* remove from parent set table - eventually destroy the set */ - if ( --family->num_nodes == 0 ) - FT_LruList_Remove( cache->families, (FT_LruNode) family ); - } - - /* add a new node to the head of the manager's circular MRU list */ static void ftc_node_mru_link( FTC_Node node, FTC_Manager manager ) { - FTC_Node first = manager->nodes_list; - - - if ( first ) - { - FTC_Node last = first->mru_prev; - - - FT_ASSERT( last->mru_next == first ); - - node->mru_prev = last; - node->mru_next = first; - - last->mru_next = node; - first->mru_prev = node; - } - else - { - FT_ASSERT( manager->num_nodes == 0 ); - - node->mru_next = node; - node->mru_prev = node; - } - - manager->nodes_list = node; + FTC_MruNode_Prepend( (FTC_MruNode*)&manager->nodes_list, + (FTC_MruNode)node ); manager->num_nodes++; } @@ -96,29 +57,8 @@ ftc_node_mru_unlink( FTC_Node node, FTC_Manager manager ) { - FTC_Node first = manager->nodes_list; - FTC_Node prev = node->mru_prev; - FTC_Node next = node->mru_next; - - - FT_ASSERT( first != NULL && manager->num_nodes > 0 ); - FT_ASSERT( next->mru_prev == node ); - FT_ASSERT( prev->mru_next == node ); - - next->mru_prev = prev; - prev->mru_next = next; - - if ( node == first ) - { - /* this is the last node in the list; update its head pointer */ - if ( node == next ) - manager->nodes_list = NULL; - else - manager->nodes_list = next; - } - - node->mru_next = NULL; - node->mru_prev = NULL; + FTC_MruNode_Remove( (FTC_MruNode*)&manager->nodes_list, + (FTC_MruNode)node ); manager->num_nodes--; } @@ -128,120 +68,167 @@ ftc_node_mru_up( FTC_Node node, FTC_Manager manager ) { - FTC_Node first = manager->nodes_list; + FTC_MruNode_Up( (FTC_MruNode*)&manager->nodes_list, + (FTC_MruNode)node ); + } - if ( node != first ) + /* Note that this function cannot fail. If we cannot re-size the + * buckets array appropriately, we simply degrade the hash table's + * performance! + */ + static void + ftc_cache_resize( FTC_Cache cache ) + { + for (;;) { - FTC_Node prev = node->mru_prev; - FTC_Node next = node->mru_next; - FTC_Node last; + FTC_Node node, *pnode; + FT_UInt p = cache->p; + FT_UInt mask = cache->mask; + FT_UInt count = mask + p + 1; /* number of buckets */ - prev->mru_next = next; - next->mru_prev = prev; + /* do we need to shrink the buckets array? */ + if ( cache->slack < 0 ) + { + FTC_Node new_list = NULL; - last = first->mru_prev; - node->mru_next = first; - node->mru_prev = last; - first->mru_prev = node; - last->mru_next = node; - manager->nodes_list = node; + /* try to expand the buckets array _before_ splitting + * the bucket lists + */ + if ( p >= mask ) + { + FT_Memory memory = cache->memory; + + + /* if we can't expand the array, leave immediately */ + if ( FT_MEM_RENEW_ARRAY( cache->buckets, (mask+1)*2, (mask+1)*4 ) ) + break; + } + + /* split a single bucket */ + pnode = cache->buckets + p; + + for (;;) + { + node = *pnode; + if ( node == NULL ) + break; + + if ( node->hash & ( mask + 1 ) ) + { + *pnode = node->link; + node->link = new_list; + new_list = node; + } + else + pnode = &node->link; + } + + cache->buckets[p + mask + 1] = new_list; + + cache->slack += FTC_HASH_MAX_LOAD; + + if ( p >= mask ) + { + cache->mask = 2 * mask + 1; + cache->p = 0; + } + else + cache->p = p + 1; + } + + /* do we need to expand the buckets array? */ + else if ( cache->slack > (FT_Long)count * FTC_HASH_SUB_LOAD ) + { + FT_UInt old_index = p + mask; + FTC_Node* pold; + + + if ( old_index + 1 <= FTC_HASH_INITIAL_SIZE ) + break; + + if ( p == 0 ) + { + FT_Memory memory = cache->memory; + + + /* if we can't shrink the array, leave immediately */ + if ( FT_MEM_RENEW_ARRAY( cache->buckets, + ( mask + 1 ) * 2, mask + 1 ) ) + break; + + cache->mask >>= 1; + p = cache->mask; + } + else + p--; + + pnode = cache->buckets + p; + while ( *pnode ) + pnode = &(*pnode)->link; + + pold = cache->buckets + old_index; + *pnode = *pold; + *pold = NULL; + + cache->slack -= FTC_HASH_MAX_LOAD; + cache->p = p; + } + else /* the hash table is balanced */ + break; } } /* remove a node from its cache's hash table */ - static FT_Error - ftc_node_hash_unlink( FTC_Node node, + static void + ftc_node_hash_unlink( FTC_Node node0, FTC_Cache cache ) { - FT_Error error = 0; FTC_Node *pnode; - FT_UInt idx, num_buckets; + FT_UInt idx; - idx = (FT_UInt)( node->hash & cache->mask ); + idx = (FT_UInt)( node0->hash & cache->mask ); if ( idx < cache->p ) - idx = (FT_UInt)( node->hash & ( 2 * cache->mask + 1 ) ); + idx = (FT_UInt)( node0->hash & ( 2 * cache->mask + 1 ) ); pnode = cache->buckets + idx; for (;;) { - if ( *pnode == NULL ) + FTC_Node node = *pnode; + + + if ( node == NULL ) { FT_ERROR(( "ftc_node_hash_unlink: unknown node!\n" )); - return FT_Err_Ok; + return; } - if ( *pnode == node ) - { - *pnode = node->link; - node->link = NULL; + if ( node == node0 ) break; - } pnode = &(*pnode)->link; } - num_buckets = ( cache->p + cache->mask + 1 ); + *pnode = node0->link; + node0->link = NULL; - if ( ++cache->slack > (FT_Long)num_buckets * FTC_HASH_SUB_LOAD ) - { - FT_UInt p = cache->p; - FT_UInt mask = cache->mask; - FT_UInt old_index = p + mask; - FTC_Node* pold; - - - if ( old_index+1 <= FTC_HASH_INITIAL_SIZE ) - goto Exit; - - if ( p == 0 ) - { - FT_Memory memory = cache->memory; - - - cache->mask >>= 1; - p = cache->mask; - - if ( FT_RENEW_ARRAY( cache->buckets, ( mask + 1 ) * 2, (mask+1) ) ) - { - FT_ERROR(( "ftc_node_hash_unlink: couldn't shunk buckets!\n" )); - goto Exit; - } - } - else - p--; - - pnode = cache->buckets + p; - while ( *pnode ) - pnode = &(*pnode)->link; - - pold = cache->buckets + old_index; - *pnode = *pold; - *pold = NULL; - - cache->slack -= FTC_HASH_MAX_LOAD; - cache->p = p; - } - - Exit: - return error; + cache->slack++; + ftc_cache_resize( cache ); } - - /* add a node to the "top" of its cache's hash table */ - static FT_Error + /* add a node to the `top' of its cache's hash table */ + static void ftc_node_hash_link( FTC_Node node, FTC_Cache cache ) { FTC_Node *pnode; FT_UInt idx; - FT_Error error = 0; idx = (FT_UInt)( node->hash & cache->mask ); @@ -253,85 +240,29 @@ node->link = *pnode; *pnode = node; - if ( --cache->slack < 0 ) - { - FT_UInt p = cache->p; - FT_UInt mask = cache->mask; - FTC_Node new_list; - - - /* split a single bucket */ - new_list = NULL; - pnode = cache->buckets + p; - - for (;;) - { - node = *pnode; - if ( node == NULL ) - break; - - if ( node->hash & ( mask + 1 ) ) - { - *pnode = node->link; - node->link = new_list; - new_list = node; - } - else - pnode = &node->link; - } - - cache->buckets[p + mask + 1] = new_list; - - cache->slack += FTC_HASH_MAX_LOAD; - - if ( p >= mask ) - { - FT_Memory memory = cache->memory; - - - if ( FT_RENEW_ARRAY( cache->buckets, - ( mask + 1 ) * 2, ( mask + 1 ) * 4 ) ) - { - FT_ERROR(( "ftc_node_hash_link: couldn't expand buckets!\n" )); - goto Exit; - } - - cache->mask = 2 * mask + 1; - cache->p = 0; - } - else - cache->p = p + 1; - } - - Exit: - return error; + cache->slack--; + ftc_cache_resize( cache ); } - - /* remove a node from the cache manager */ FT_EXPORT_DEF( void ) ftc_node_destroy( FTC_Node node, FTC_Manager manager ) { - FT_Memory memory = manager->library->memory; - FTC_Cache cache; - FTC_FamilyEntry entry; - FTC_Cache_Class clazz; + FTC_Cache cache; #ifdef FT_DEBUG_ERROR /* find node's cache */ - if ( node->fam_index >= manager->families.count ) + if ( node->cache_index >= manager->num_caches ) { FT_ERROR(( "ftc_node_destroy: invalid node handle\n" )); return; } #endif - entry = manager->families.entries + node->fam_index; - cache = entry->cache; + cache = manager->caches[node->cache_index]; #ifdef FT_DEBUG_ERROR if ( cache == NULL ) @@ -341,9 +272,7 @@ } #endif - clazz = cache->clazz; - - manager->cur_weight -= clazz->node_weight( node, cache ); + manager->cur_weight -= cache->clazz.node_weight( node, cache ); /* remove node from mru list */ ftc_node_mru_unlink( node, manager ); @@ -352,10 +281,7 @@ ftc_node_hash_unlink( node, cache ); /* now finalize it */ - if ( clazz->node_done ) - clazz->node_done( node, cache ); - - FT_FREE( node ); + cache->clazz.node_free( node, cache ); #if 0 /* check, just in case of general corruption :-) */ @@ -366,58 +292,6 @@ } - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** CACHE FAMILY DEFINITIONS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - FT_EXPORT_DEF( FT_Error ) - ftc_family_init( FTC_Family family, - FTC_Query query, - FTC_Cache cache ) - { - FT_Error error; - FTC_Manager manager = cache->manager; - FT_Memory memory = manager->library->memory; - FTC_FamilyEntry entry; - - - family->cache = cache; - family->num_nodes = 0; - - /* now add to manager's family table */ - error = ftc_family_table_alloc( &manager->families, memory, &entry ); - if ( !error ) - { - entry->cache = cache; - entry->family = family; - family->fam_index = entry->index; - - query->family = family; /* save family in query */ - } - - return error; - } - - - FT_EXPORT_DEF( void ) - ftc_family_done( FTC_Family family ) - { - if ( family && family->cache ) - { - FTC_Manager manager = family->cache->manager; - - - /* remove from manager's family table */ - ftc_family_table_free( &manager->families, family->fam_index ); - } - } - - /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -427,62 +301,36 @@ /*************************************************************************/ - FT_EXPORT_DEF( FT_Error ) - ftc_cache_init( FTC_Cache cache ) + FTC_Cache_Init( FTC_Cache cache ) { - FT_Memory memory = cache->memory; - FTC_Cache_Class clazz = cache->clazz; - FT_Error error; + FT_Memory memory = cache->memory; cache->p = 0; cache->mask = FTC_HASH_INITIAL_SIZE - 1; cache->slack = FTC_HASH_INITIAL_SIZE * FTC_HASH_MAX_LOAD; - if ( FT_NEW_ARRAY( cache->buckets, FTC_HASH_INITIAL_SIZE * 2 ) ) - goto Exit; - - /* now, initialize the lru list of families for this cache */ - if ( clazz->family_size > 0 ) - { - FT_LruList_ClassRec* lru_class = &cache->family_class; + return ( FT_MEM_NEW_ARRAY( cache->buckets, FTC_HASH_INITIAL_SIZE * 2 ) ); + } - lru_class->list_size = sizeof( FT_LruListRec ); - lru_class->list_init = NULL; - lru_class->list_done = NULL; - - lru_class->node_size = clazz->family_size; - lru_class->node_init = (FT_LruNode_InitFunc) clazz->family_init; - lru_class->node_done = (FT_LruNode_DoneFunc) clazz->family_done; - lru_class->node_flush = (FT_LruNode_FlushFunc) NULL; - lru_class->node_compare = (FT_LruNode_CompareFunc)clazz->family_compare; - - error = FT_LruList_New( (FT_LruList_Class) lru_class, - 0, /* max items == 0 => unbounded list */ - cache, - memory, - &cache->families ); - if ( error ) - FT_FREE( cache->buckets ); - } - - Exit: - return error; + FT_LOCAL_DEF( FT_Error ) + ftc_cache_init( FTC_Cache cache ) + { + return FTC_Cache_Init( cache ); } FT_EXPORT_DEF( void ) - ftc_cache_clear( FTC_Cache cache ) + FTC_Cache_Clear( FTC_Cache cache ) { if ( cache ) { - FT_Memory memory = cache->memory; - FTC_Cache_Class clazz = cache->clazz; - FTC_Manager manager = cache->manager; - FT_UFast i; - FT_UInt count; + FTC_Manager manager = cache->manager; + FT_UFast i; + FT_UInt count; + count = cache->p + cache->mask + 1; @@ -500,308 +348,257 @@ ftc_node_mru_unlink( node, manager ); /* now finalize it */ - manager->cur_weight -= clazz->node_weight( node, cache ); + manager->cur_weight -= cache->clazz.node_weight( node, cache ); - if ( clazz->node_done ) - clazz->node_done( node, cache ); - - FT_FREE( node ); + cache->clazz.node_free( node, cache ); node = next; } cache->buckets[i] = NULL; } - - cache->p = 0; - - /* destroy the families */ - if ( cache->families ) - FT_LruList_Reset( cache->families ); + ftc_cache_resize( cache ); } } FT_EXPORT_DEF( void ) - ftc_cache_done( FTC_Cache cache ) + FTC_Cache_Done( FTC_Cache cache ) { - if ( cache ) + if ( cache->memory ) { FT_Memory memory = cache->memory; - ftc_cache_clear( cache ); + FTC_Cache_Clear( cache ); FT_FREE( cache->buckets ); cache->mask = 0; + cache->p = 0; cache->slack = 0; - if ( cache->families ) + cache->memory = NULL; + } + } + + + FT_LOCAL_DEF( void ) + ftc_cache_done( FTC_Cache cache ) + { + FTC_Cache_Done( cache ); + } + + + static void + ftc_cache_add( FTC_Cache cache, + FT_UInt32 hash, + FTC_Node node ) + { + node->hash = hash; + node->cache_index = (FT_UInt16) cache->index; + node->ref_count = 0; + + ftc_node_hash_link( node, cache ); + ftc_node_mru_link( node, cache->manager ); + + { + FTC_Manager manager = cache->manager; + + + manager->cur_weight += cache->clazz.node_weight( node, cache ); + + if ( manager->cur_weight >= manager->max_weight ) { - FT_LruList_Destroy( cache->families ); - cache->families = NULL; + node->ref_count++; + FTC_Manager_Compress( manager ); + node->ref_count--; } } } - /* Look up a node in "top" of its cache's hash table. */ - /* If not found, create a new node. */ - /* */ FT_EXPORT_DEF( FT_Error ) - ftc_cache_lookup( FTC_Cache cache, - FTC_Query query, - FTC_Node *anode ) + FTC_Cache_NewNode( FTC_Cache cache, + FT_UInt32 hash, + FT_Pointer query, + FTC_Node *anode ) { - FT_Error error = FT_Err_Ok; - FTC_Manager manager; - FT_LruNode lru; - FT_UInt free_count = 0; + FT_Error error; + FTC_Node node; + /* + * Try to allocate a new cache node. Note that in case of + * out-of-memory error (OOM), we'll flush the cache a bit, + * then try again. + * + * On each try, the `tries' variable gives the number + * of old nodes we want to flush from the manager's global list + * before the next allocation attempt. It barely doubles on + * each iteration. + * + */ + error = cache->clazz.node_new( &node, query, cache ); + if ( error ) + goto FlushCache; - if ( !cache || !query || !anode ) - return FTC_Err_Invalid_Argument; - - *anode = NULL; - - query->hash = 0; - query->family = NULL; - - manager = cache->manager; - - /* here's a small note explaining what's hapenning in the code below. - * - * we need to deal intelligently with out-of-memory (OOM) conditions - * when trying to create a new family or cache node during the lookup. - * - * when an OOM is detected, we'll try to free one or more "old" nodes - * from the cache, then try again. it may be necessary to do that several - * times, so a loop is needed. - * - * the local variable "free_count" holds the number of "old" nodes to - * discard on each attempt. it starts at 1 and doubles on each iteration. - * the loop stops when: - * - * - a non-OOM error is detected - * - a succesful lookup is performed - * - there are no more unused nodes in the cache - * - * for the record, remember that all used nodes appear _before_ - * unused ones in the manager's MRU node list. - */ - - for (;;) - { - { - /* first of all, find the relevant family */ - FT_LruList list = cache->families; - FT_LruNode fam, *pfam; - FT_LruNode_CompareFunc compare = list->clazz->node_compare; - - pfam = &list->nodes; - for (;;) - { - fam = *pfam; - if ( fam == NULL ) - { - error = FT_LruList_Lookup( list, query, &lru ); - if ( error ) - goto Fail; - - goto Skip; - } - - if ( compare( fam, query, list->data ) ) - break; - - pfam = &fam->next; - } - - FT_ASSERT( fam != NULL ); - - /* move to top of list when needed */ - if ( fam != list->nodes ) - { - *pfam = fam->next; - fam->next = list->nodes; - list->nodes = fam; - } - - lru = fam; - - Skip: - ; - } - - { - FTC_Manager manager = cache->manager; - FTC_Family family = (FTC_Family) lru; - FT_UFast hash = query->hash; - FTC_Node* bucket; - FT_UInt idx; - - - idx = hash & cache->mask; - if ( idx < cache->p ) - idx = hash & ( cache->mask * 2 + 1 ); - - bucket = cache->buckets + idx; - - - if ( query->family != family || - family->fam_index >= manager->families.size ) - { - FT_ERROR(( - "ftc_cache_lookup: invalid query (bad 'family' field)\n" )); - error = FTC_Err_Invalid_Argument; - goto Exit; - } - - if ( *bucket ) - { - FTC_Node* pnode = bucket; - FTC_Node_CompareFunc compare = cache->clazz->node_compare; - - - for ( ;; ) - { - FTC_Node node; - - - node = *pnode; - if ( node == NULL ) - break; - - if ( node->hash == hash && - (FT_UInt)node->fam_index == family->fam_index && - compare( node, query, cache ) ) - { - /* move to head of bucket list */ - if ( pnode != bucket ) - { - *pnode = node->link; - node->link = *bucket; - *bucket = node; - } - - /* move to head of MRU list */ - if ( node != manager->nodes_list ) - ftc_node_mru_up( node, manager ); - - *anode = node; - goto Exit; - } - - pnode = &node->link; - } - } - - /* didn't find a node, create a new one */ - { - FTC_Cache_Class clazz = cache->clazz; - FT_Memory memory = cache->memory; - FTC_Node node; - - - if ( FT_ALLOC( node, clazz->node_size ) ) - goto Fail; - - node->fam_index = (FT_UShort) family->fam_index; - node->hash = query->hash; - node->ref_count = 0; - - error = clazz->node_init( node, query, cache ); - if ( error ) - { - FT_FREE( node ); - goto Fail; - } - - error = ftc_node_hash_link( node, cache ); - if ( error ) - { - clazz->node_done( node, cache ); - FT_FREE( node ); - goto Fail; - } - - ftc_node_mru_link( node, cache->manager ); - - cache->manager->cur_weight += clazz->node_weight( node, cache ); - - /* now try to compress the node pool when necessary */ - if ( manager->cur_weight >= manager->max_weight ) - { - node->ref_count++; - FTC_Manager_Compress( manager ); - node->ref_count--; - } - - *anode = node; - } - - /* all is well, exit now - */ - goto Exit; - } - - Fail: - if ( error != FT_Err_Out_Of_Memory ) - goto Exit; - - /* there is not enough memory, try to release some unused nodes - * from the cache to make room for a new one. - */ - { - FT_UInt new_count; - - new_count = 1 + free_count*2; - - /* check overflow and bounds */ - if ( new_count < free_count || free_count > manager->num_nodes ) - goto Exit; - - free_count = new_count; - - /* try to remove "new_count" nodes from the list */ - { - FTC_Node first = manager->nodes_list; - FTC_Node node; - - if ( first == NULL ) /* empty list ! */ - goto Exit; - - /* go to last node - it's a circular list */ - node = first->mru_prev; - for ( ; node && new_count > 0; new_count-- ) - { - FTC_Node prev = node->mru_prev; - - /* used nodes always appear before unused one in the MRU - * list. if we find one here, we'd better stop right now - * our iteration - */ - if ( node->ref_count > 0 ) - { - /* if there are no unused nodes in the list, we'd better exit */ - if ( new_count == free_count ) - goto Exit; - - break; - } - - ftc_node_destroy( node, manager ); - - if ( node == first ) - break; - - node = prev; - } - } - } - } + AddNode: + /* don't assume that the cache has the same number of buckets, since + * our allocation request might have triggered global cache flushing + */ + ftc_cache_add( cache, hash, node ); Exit: + *anode = node; return error; + + FlushCache: + node = NULL; + if ( error != FT_Err_Out_Of_Memory ) + goto Exit; + + { + FTC_Manager manager = cache->manager; + FT_UInt count, tries = 1; + + + for (;;) + { + error = cache->clazz.node_new( &node, query, cache ); + if ( !error ) + break; + + node = NULL; + if ( error != FT_Err_Out_Of_Memory ) + goto Exit; + + count = FTC_Manager_FlushN( manager, tries ); + if ( count == 0 ) + goto Exit; + + if ( count == tries ) + { + count = tries * 2; + if ( count < tries || count > manager->num_nodes ) + count = manager->num_nodes; + } + tries = count; + } + } + goto AddNode; } -/* END */ + FT_EXPORT_DEF( FT_Error ) + FTC_Cache_Lookup( FTC_Cache cache, + FT_UInt32 hash, + FT_Pointer query, + FTC_Node *anode ) + { + FT_UFast idx; + FTC_Node* bucket; + FTC_Node* pnode; + FTC_Node node; + FT_Error error = 0; + + FTC_Node_CompareFunc compare = cache->clazz.node_compare; + + + if ( cache == NULL || anode == NULL ) + return FT_Err_Invalid_Argument; + + idx = hash & cache->mask; + if ( idx < cache->p ) + idx = hash & ( cache->mask * 2 + 1 ); + + bucket = cache->buckets + idx; + pnode = bucket; + for (;;) + { + node = *pnode; + if ( node == NULL ) + goto NewNode; + + if ( node->hash == hash && compare( node, query, cache ) ) + break; + + pnode = &node->link; + } + + if ( node != *bucket ) + { + *pnode = node->link; + node->link = *bucket; + *bucket = node; + } + + /* move to head of MRU list */ + { + FTC_Manager manager = cache->manager; + + + if ( node != manager->nodes_list ) + ftc_node_mru_up( node, manager ); + } + *anode = node; + return error; + + NewNode: + return FTC_Cache_NewNode( cache, hash, query, anode ); + } + + + FT_EXPORT_DEF( void ) + FTC_Cache_RemoveFaceID( FTC_Cache cache, + FTC_FaceID face_id ) + { + FT_UFast i, count; + FTC_Manager manager = cache->manager; + FTC_Node frees = NULL; + + + count = cache->p + cache->mask; + for ( i = 0; i < count; i++ ) + { + FTC_Node* bucket = cache->buckets + i; + FTC_Node* pnode = bucket; + + + for ( ;; ) + { + FTC_Node node = *pnode; + + + if ( node == NULL ) + break; + + if ( cache->clazz.node_remove_faceid( node, face_id, cache ) ) + { + *pnode = node->link; + node->link = frees; + frees = node; + } + else + pnode = &node->link; + } + } + + /* remove all nodes in the free list */ + while ( frees ) + { + FTC_Node node; + + + node = frees; + frees = node->link; + + manager->cur_weight -= cache->clazz.node_weight( node, cache ); + ftc_node_mru_unlink( node, manager ); + + cache->clazz.node_free( node, cache ); + + cache->slack++; + } + + ftc_cache_resize( cache ); + } + + +/* END */ diff --git a/src/libs/freetype2/cache/ftccache.i b/src/libs/freetype2/cache/ftccache.i deleted file mode 100644 index bf61450021..0000000000 --- a/src/libs/freetype2/cache/ftccache.i +++ /dev/null @@ -1,157 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftccache.i */ -/* */ -/* FreeType template for generic cache. */ -/* */ -/* Copyright 2002 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. */ -/* */ -/***************************************************************************/ - - -#ifndef GEN_CACHE_FAMILY_COMPARE -#error "GEN_CACHE_FAMILY_COMPARE not defined in template instantiation" -#endif - -#ifndef GEN_CACHE_NODE_COMPARE -#error "GEN_CACHE_NODE_COMPARE not defined in template instantiation" -#endif - - - static FT_Error - GEN_CACHE_LOOKUP( FTC_Cache cache, - FTC_Query query, - FTC_Node *anode ) - { - FT_LruNode lru; - FTC_Family family; - FT_UFast hash; - - - query->hash = 0; - query->family = NULL; - - /* XXX: we break encapsulation for the sake of speed! */ - { - /* first of all, find the relevant family */ - FT_LruList list = cache->families; - FT_LruNode fam, *pfam; - - - pfam = &list->nodes; - for (;;) - { - fam = *pfam; - if ( fam == NULL ) - goto Normal; - - if ( GEN_CACHE_FAMILY_COMPARE( fam, query, list->data ) ) - break; - - pfam = &fam->next; - } - - FT_ASSERT( fam != NULL ); - - /* move to top of list when needed */ - if ( fam != list->nodes ) - { - *pfam = fam->next; - fam->next = list->nodes; - list->nodes = fam; - } - - lru = fam; - } - - { - FTC_Node node, *pnode, *bucket; - - - family = (FTC_Family)lru; - hash = query->hash; - - { - FT_UInt idx; - - - idx = hash & cache->mask; - if ( idx < cache->p ) - idx = hash & ( cache->mask * 2 + 1 ); - - bucket = cache->buckets + idx; - } - - pnode = bucket; - - for ( ;; ) - { - node = *pnode; - if ( node == NULL ) - goto Normal; - - if ( node->hash == hash && - (FT_UInt)node->fam_index == family->fam_index && - GEN_CACHE_NODE_COMPARE( node, query, cache ) ) - { - /* we place the following out of the loop to make it */ - /* as small as possible... */ - goto Found; - } - - pnode = &node->link; - } - - Normal: - return ftc_cache_lookup( cache, query, anode ); - - Found: - /* move to head of bucket list */ - if ( pnode != bucket ) - { - *pnode = node->link; - node->link = *bucket; - *bucket = node; - } - - /* move to head of MRU list */ - if ( node != cache->manager->nodes_list ) - { - /* XXX: again, this is an inlined version of ftc_node_mru_up */ - FTC_Manager manager = cache->manager; - FTC_Node first = manager->nodes_list; - FTC_Node prev = node->mru_prev; - FTC_Node next = node->mru_next; - FTC_Node last; - - - prev->mru_next = next; - next->mru_prev = prev; - - last = first->mru_prev; - node->mru_next = first; - node->mru_prev = last; - first->mru_prev = node; - last->mru_next = node; - - manager->nodes_list = node; - } - - *anode = node; - return 0; - } - } - -#undef GEN_CACHE_NODE_COMPARE -#undef GEN_CACHE_FAMILY_COMPARE -#undef GEN_CACHE_LOOKUP - - -/* END */ diff --git a/src/libs/freetype2/cache/ftccback.h b/src/libs/freetype2/cache/ftccback.h new file mode 100644 index 0000000000..68be913850 --- /dev/null +++ b/src/libs/freetype2/cache/ftccback.h @@ -0,0 +1,82 @@ +/***************************************************************************/ +/* */ +/* ftccback.h */ +/* */ +/* Callback functions of the caching sub-system (specification only). */ +/* */ +/* Copyright 2004 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. */ +/* */ +/***************************************************************************/ + +#ifndef __FTCCBACK_H__ +#define __FTCCBACK_H__ + +#include <ft2build.h> +#include FT_CACHE_H +#include FT_CACHE_INTERNAL_MRU_H +#include FT_CACHE_INTERNAL_IMAGE_H +#include FT_CACHE_INTERNAL_MANAGER_H +#include FT_CACHE_INTERNAL_GLYPH_H +#include FT_CACHE_INTERNAL_SBITS_H + + + FT_LOCAL( void ) + ftc_inode_free( FTC_INode inode, + FTC_Cache cache ); + + FT_LOCAL( FT_Error ) + ftc_inode_new( FTC_INode *pinode, + FTC_GQuery gquery, + FTC_Cache cache ); + + FT_LOCAL( FT_ULong ) + ftc_inode_weight( FTC_INode inode ); + + + FT_LOCAL( void ) + ftc_snode_free( FTC_SNode snode, + FTC_Cache cache ); + + FT_LOCAL( FT_Error ) + ftc_snode_new( FTC_SNode *psnode, + FTC_GQuery gquery, + FTC_Cache cache ); + + FT_LOCAL( FT_ULong ) + ftc_snode_weight( FTC_SNode snode ); + + FT_LOCAL( FT_Bool ) + ftc_snode_compare( FTC_SNode snode, + FTC_GQuery gquery, + FTC_Cache cache ); + + + FT_LOCAL( FT_Bool ) + ftc_gnode_compare( FTC_GNode gnode, + FTC_GQuery gquery ); + + + FT_LOCAL( FT_Error ) + ftc_gcache_init( FTC_GCache cache ); + + FT_LOCAL( void ) + ftc_gcache_done( FTC_GCache cache ); + + + FT_LOCAL( FT_Error ) + ftc_cache_init( FTC_Cache cache ); + + FT_LOCAL( void ) + ftc_cache_done( FTC_Cache cache ); + + +#endif /* __FTCCBACK_H__ */ + +/* END */ diff --git a/src/libs/freetype2/cache/ftccmap.c b/src/libs/freetype2/cache/ftccmap.c index bdf61ed6e7..dfdbb488bc 100644 --- a/src/libs/freetype2/cache/ftccmap.c +++ b/src/libs/freetype2/cache/ftccmap.c @@ -4,7 +4,7 @@ /* */ /* FreeType CharMap cache (body) */ /* */ -/* Copyright 2000-2001, 2002 by */ +/* Copyright 2000-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,17 +19,18 @@ #include <ft2build.h> #include FT_FREETYPE_H #include FT_CACHE_H -#include FT_CACHE_CHARMAP_H -#include FT_CACHE_MANAGER_H +#include FT_CACHE_INTERNAL_MANAGER_H #include FT_INTERNAL_MEMORY_H #include FT_INTERNAL_DEBUG_H #include FT_TRUETYPE_IDS_H +#include "ftccback.h" #include "ftcerror.h" #undef FT_COMPONENT #define FT_COMPONENT trace_cache + /*************************************************************************/ /* */ /* Each FTC_CMapNode contains a simple array to map a range of character */ @@ -47,56 +48,44 @@ /* number of glyph indices / character code per node */ #define FTC_CMAP_INDICES_MAX 128 + /* compute a query/node hash */ +#define FTC_CMAP_HASH( faceid, index, charcode ) \ + ( FTC_FACE_ID_HASH( faceid ) + 211 * ( index ) + \ + ( (char_code) / FTC_CMAP_INDICES_MAX ) ) + /* the charmap query */ + typedef struct FTC_CMapQueryRec_ + { + FTC_FaceID face_id; + FT_UInt cmap_index; + FT_UInt32 char_code; + + } FTC_CMapQueryRec, *FTC_CMapQuery; + +#define FTC_CMAP_QUERY( x ) ((FTC_CMapQuery)(x)) +#define FTC_CMAP_QUERY_HASH( x ) \ + FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->char_code ) + + /* the cmap cache node */ typedef struct FTC_CMapNodeRec_ { FTC_NodeRec node; + FTC_FaceID face_id; + FT_UInt cmap_index; FT_UInt32 first; /* first character in node */ FT_UInt16 indices[FTC_CMAP_INDICES_MAX]; /* array of glyph indices */ } FTC_CMapNodeRec, *FTC_CMapNode; - #define FTC_CMAP_NODE( x ) ( (FTC_CMapNode)( x ) ) - - - /* compute node hash value from cmap family and "requested" glyph index */ -#define FTC_CMAP_HASH( cfam, cquery ) \ - ( (cfam)->hash + ( (cquery)->char_code / FTC_CMAP_INDICES_MAX ) ) +#define FTC_CMAP_NODE_HASH( x ) \ + FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->first ) /* if (indices[n] == FTC_CMAP_UNKNOWN), we assume that the corresponding */ /* glyph indices haven't been queried through FT_Get_Glyph_Index() yet */ #define FTC_CMAP_UNKNOWN ( (FT_UInt16)-1 ) - /* the charmap query */ - typedef struct FTC_CMapQueryRec_ - { - FTC_QueryRec query; - FTC_CMapDesc desc; - FT_UInt32 char_code; - - } FTC_CMapQueryRec, *FTC_CMapQuery; - - -#define FTC_CMAP_QUERY( x ) ( (FTC_CMapQuery)( x ) ) - - - /* the charmap family */ - typedef struct FTC_CMapFamilyRec_ - { - FTC_FamilyRec family; - FT_UInt32 hash; - FTC_CMapDescRec desc; - FT_UInt index; - - } FTC_CMapFamilyRec, *FTC_CMapFamily; - - -#define FTC_CMAP_FAMILY( x ) ( (FTC_CMapFamily)( x ) ) -#define FTC_CMAP_FAMILY_MEMORY( x ) FTC_FAMILY( x )->memory - - /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -106,27 +95,44 @@ /*************************************************************************/ - /* no need for specific finalizer; we use "ftc_node_done" directly */ + /* no need for specific finalizer; we use `ftc_node_done' directly */ + + FT_CALLBACK_DEF( void ) + ftc_cmap_node_free( FTC_CMapNode node, + FTC_Cache cache ) + { + FT_Memory memory = cache->memory; + + + FT_FREE( node ); + } + /* initialize a new cmap node */ FT_CALLBACK_DEF( FT_Error ) - ftc_cmap_node_init( FTC_CMapNode cnode, - FTC_CMapQuery cquery, - FTC_Cache cache ) + ftc_cmap_node_new( FTC_CMapNode *anode, + FTC_CMapQuery query, + FTC_Cache cache ) { - FT_UInt32 first; - FT_UInt n; - FT_UNUSED( cache ); + FT_Error error; + FT_Memory memory = cache->memory; + FTC_CMapNode node; + FT_UInt nn; - first = ( cquery->char_code / FTC_CMAP_INDICES_MAX ) * - FTC_CMAP_INDICES_MAX; + if ( !FT_NEW( node ) ) + { + node->face_id = query->face_id; + node->cmap_index = query->cmap_index; + node->first = (query->char_code / FTC_CMAP_INDICES_MAX) * + FTC_CMAP_INDICES_MAX; - cnode->first = first; - for ( n = 0; n < FTC_CMAP_INDICES_MAX; n++ ) - cnode->indices[n] = FTC_CMAP_UNKNOWN; + for ( nn = 0; nn < FTC_CMAP_INDICES_MAX; nn++ ) + node->indices[nn] = FTC_CMAP_UNKNOWN; + } - return 0; + *anode = node; + return error; } @@ -142,184 +148,27 @@ /* compare a cmap node to a given query */ FT_CALLBACK_DEF( FT_Bool ) - ftc_cmap_node_compare( FTC_CMapNode cnode, - FTC_CMapQuery cquery ) + ftc_cmap_node_compare( FTC_CMapNode node, + FTC_CMapQuery query ) { - FT_UInt32 offset = (FT_UInt32)( cquery->char_code - cnode->first ); - - - return FT_BOOL( offset < FTC_CMAP_INDICES_MAX ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** CHARMAP FAMILY *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - FT_CALLBACK_DEF( FT_Error ) - ftc_cmap_family_init( FTC_CMapFamily cfam, - FTC_CMapQuery cquery, - FTC_Cache cache ) - { - FTC_Manager manager = cache->manager; - FTC_CMapDesc desc = cquery->desc; - FT_UInt32 hash = 0; - FT_Error error; - FT_Face face; - - - /* setup charmap descriptor */ - cfam->desc = *desc; - - /* let's see whether the rest is correct too */ - error = FTC_Manager_Lookup_Face( manager, desc->face_id, &face ); - if ( !error ) + if ( node->face_id == query->face_id && + node->cmap_index == query->cmap_index ) { - FT_UInt count = face->num_charmaps; - FT_UInt idx = count; - FT_CharMap* cur = face->charmaps; + FT_UInt32 offset = (FT_UInt32)( query->char_code - node->first ); - switch ( desc->type ) - { - case FTC_CMAP_BY_INDEX: - idx = desc->u.index; - hash = idx * 33; - break; - - case FTC_CMAP_BY_ENCODING: - if (desc->u.encoding == FT_ENCODING_UNICODE) - { - /* since the `interesting' table, with id's 3,10, is normally the - * last one, we loop backwards. This looses with type1 fonts with - * non-BMP characters (<.0001%), this wins with .ttf with non-BMP - * chars (.01% ?), and this is the same about 99.99% of the time! - */ - - FT_UInt unicmap_idx = count; /* some UCS-2 map, if we found it */ - - cur += count - 1; - - for ( idx = 0; idx < count; idx++, cur-- ) - { - if ( cur[0]->encoding == FT_ENCODING_UNICODE ) - { - unicmap_idx = idx; /* record we found a Unicode charmap */ - - /* XXX If some new encodings to represent UCS-4 are added, - * they should be added here. - */ - if ( ( cur[0]->platform_id == TT_PLATFORM_MICROSOFT && - cur[0]->encoding_id == TT_MS_ID_UCS_4 ) || - ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE && - cur[0]->encoding_id == TT_APPLE_ID_UNICODE_32 ) ) - - /* Hurray! We found a UCS-4 charmap. We can stop the scan! */ - { - idx = count - 1 - idx; - goto Found_idx_for_FTC_CMAP_BY_ENCODING; - } - } - } - - /* We do not have any UCS-4 charmap. Sigh. - * Let's see if we have some other kind of Unicode charmap, though. - */ - if ( unicmap_idx < count ) - idx = count - 1 - unicmap_idx; - } - else - { - for ( idx = 0; idx < count; idx++, cur++ ) - if ( cur[0]->encoding == desc->u.encoding ) - break; - } - - Found_idx_for_FTC_CMAP_BY_ENCODING: - hash = idx * 67; - break; - - case FTC_CMAP_BY_ID: - for ( idx = 0; idx < count; idx++, cur++ ) - { - if ( (FT_UInt)cur[0]->platform_id == desc->u.id.platform && - (FT_UInt)cur[0]->encoding_id == desc->u.id.encoding ) - { - hash = ( ( desc->u.id.platform << 8 ) | desc->u.id.encoding ) * 7; - break; - } - } - break; - - default: - ; - } - - if ( idx >= count ) - goto Bad_Descriptor; - - /* compute hash value, both in family and query */ - cfam->index = idx; - cfam->hash = hash ^ FTC_FACE_ID_HASH( desc->face_id ); - FTC_QUERY( cquery )->hash = FTC_CMAP_HASH( cfam, cquery ); - - error = ftc_family_init( FTC_FAMILY( cfam ), - FTC_QUERY( cquery ), cache ); + return FT_BOOL( offset < FTC_CMAP_INDICES_MAX ); } - return error; - - Bad_Descriptor: - FT_TRACE1(( "ftp_cmap_family_init: invalid charmap descriptor\n" )); - return FTC_Err_Invalid_Argument; + return 0; } FT_CALLBACK_DEF( FT_Bool ) - ftc_cmap_family_compare( FTC_CMapFamily cfam, - FTC_CMapQuery cquery ) + ftc_cmap_node_remove_faceid( FTC_CMapNode node, + FTC_FaceID face_id ) { - FT_Int result = 0; - - - /* first, compare face id and type */ - if ( cfam->desc.face_id != cquery->desc->face_id || - cfam->desc.type != cquery->desc->type ) - goto Exit; - - switch ( cfam->desc.type ) - { - case FTC_CMAP_BY_INDEX: - result = ( cfam->desc.u.index == cquery->desc->u.index ); - break; - - case FTC_CMAP_BY_ENCODING: - result = ( cfam->desc.u.encoding == cquery->desc->u.encoding ); - break; - - case FTC_CMAP_BY_ID: - result = ( cfam->desc.u.id.platform == cquery->desc->u.id.platform && - cfam->desc.u.id.encoding == cquery->desc->u.id.encoding ); - break; - - default: - ; - } - - if ( result ) - { - /* when found, update the 'family' and 'hash' field of the query */ - FTC_QUERY( cquery )->family = FTC_FAMILY( cfam ); - FTC_QUERY( cquery )->hash = FTC_CMAP_HASH( cfam, cquery ); - } - - Exit: - return FT_BOOL( result ); + return FT_BOOL( node->face_id == face_id ); } @@ -333,23 +182,17 @@ FT_CALLBACK_TABLE_DEF - const FTC_Cache_ClassRec ftc_cmap_cache_class = + const FTC_CacheClassRec ftc_cmap_cache_class = { - sizeof ( FTC_CacheRec ), - (FTC_Cache_InitFunc) ftc_cache_init, - (FTC_Cache_ClearFunc)ftc_cache_clear, - (FTC_Cache_DoneFunc) ftc_cache_done, - - sizeof ( FTC_CMapFamilyRec ), - (FTC_Family_InitFunc) ftc_cmap_family_init, - (FTC_Family_CompareFunc)ftc_cmap_family_compare, - (FTC_Family_DoneFunc) ftc_family_done, - - sizeof ( FTC_CMapNodeRec ), - (FTC_Node_InitFunc) ftc_cmap_node_init, + (FTC_Node_NewFunc) ftc_cmap_node_new, (FTC_Node_WeightFunc) ftc_cmap_node_weight, (FTC_Node_CompareFunc)ftc_cmap_node_compare, - (FTC_Node_DoneFunc) ftc_node_done + (FTC_Node_CompareFunc)ftc_cmap_node_remove_faceid, + (FTC_Node_FreeFunc) ftc_cmap_node_free, + + sizeof ( FTC_CacheRec ), + (FTC_Cache_InitFunc) ftc_cache_init, + (FTC_Cache_DoneFunc) ftc_cache_done, }; @@ -359,101 +202,86 @@ FTC_CMapCache_New( FTC_Manager manager, FTC_CMapCache *acache ) { - return FTC_Manager_Register_Cache( - manager, - (FTC_Cache_Class)&ftc_cmap_cache_class, - FTC_CACHE_P( acache ) ); + return FTC_Manager_RegisterCache( manager, + &ftc_cmap_cache_class, + FTC_CACHE_P( acache ) ); } -#ifdef FTC_CACHE_USE_INLINE - -#define GEN_CACHE_FAMILY_COMPARE( f, q, c ) \ - ftc_cmap_family_compare( (FTC_CMapFamily)(f), (FTC_CMapQuery)(q) ) - -#define GEN_CACHE_NODE_COMPARE( n, q, c ) \ - ftc_cmap_node_compare( (FTC_CMapNode)(n), (FTC_CMapQuery)(q) ) - -#define GEN_CACHE_LOOKUP ftc_cmap_cache_lookup - -#include "ftccache.i" - -#else /* !FTC_CACHE_USE_INLINE */ - -#define ftc_cmap_cache_lookup ftc_cache_lookup - -#endif /* !FTC_CACHE_USE_INLINE */ - - /* documentation is in ftccmap.h */ FT_EXPORT_DEF( FT_UInt ) - FTC_CMapCache_Lookup( FTC_CMapCache cache, - FTC_CMapDesc desc, + FTC_CMapCache_Lookup( FTC_CMapCache cmap_cache, + FTC_FaceID face_id, + FT_Int cmap_index, FT_UInt32 char_code ) { - FTC_CMapQueryRec cquery; + FTC_Cache cache = FTC_CACHE( cmap_cache ); + FTC_CMapQueryRec query; FTC_CMapNode node; FT_Error error; FT_UInt gindex = 0; + FT_UInt32 hash; - if ( !cache || !desc ) + if ( !cache ) { FT_ERROR(( "FTC_CMapCache_Lookup: bad arguments, returning 0!\n" )); return 0; } - cquery.desc = desc; - cquery.char_code = char_code; + query.face_id = face_id; + query.cmap_index = (FT_UInt)cmap_index; + query.char_code = char_code; - error = ftc_cmap_cache_lookup( FTC_CACHE( cache ), - FTC_QUERY( &cquery ), - (FTC_Node*)&node ); - if ( !error ) + hash = FTC_CMAP_HASH( face_id, cmap_index, char_code ); + +#if 1 + FTC_CACHE_LOOKUP_CMP( cache, ftc_cmap_node_compare, hash, &query, + node, error ); +#else + error = FTC_Cache_Lookup( cache, hash, &query, (FTC_Node*) &node ); +#endif + if ( error ) + goto Exit; + + FT_ASSERT( (FT_UInt)( char_code - node->first ) < FTC_CMAP_INDICES_MAX ); + + gindex = node->indices[char_code - node->first]; + if ( gindex == FTC_CMAP_UNKNOWN ) { - FT_UInt offset = (FT_UInt)( char_code - node->first ); + FT_Face face; - FT_ASSERT( offset < FTC_CMAP_INDICES_MAX ); + gindex = 0; - gindex = node->indices[offset]; - if ( gindex == FTC_CMAP_UNKNOWN ) + error = FTC_Manager_LookupFace( cache->manager, node->face_id, &face ); + if ( error ) + goto Exit; + + if ( (FT_UInt)cmap_index < (FT_UInt)face->num_charmaps ) { - FT_Face face; + FT_CharMap old, cmap = NULL; - /* we need to use FT_Get_Char_Index */ - gindex = 0; - - error = FTC_Manager_Lookup_Face( FTC_CACHE(cache)->manager, - desc->face_id, - &face ); - if ( !error ) - { - FT_CharMap old, cmap = NULL; - FT_UInt cmap_index; - - - /* save old charmap, select new one */ - old = face->charmap; - cmap_index = FTC_CMAP_FAMILY( FTC_QUERY( &cquery )->family )->index; - cmap = face->charmaps[cmap_index]; + old = face->charmap; + cmap = face->charmaps[cmap_index]; + if ( old != cmap ) FT_Set_Charmap( face, cmap ); - /* perform lookup */ - gindex = FT_Get_Char_Index( face, char_code ); - node->indices[offset] = (FT_UInt16)gindex; + gindex = FT_Get_Char_Index( face, char_code ); - /* restore old charmap */ + if ( old != cmap ) FT_Set_Charmap( face, old ); - } } + + node->indices[char_code - node->first] = gindex; } + Exit: return gindex; } -/* END */ +/* END */ diff --git a/src/libs/freetype2/cache/ftcerror.h b/src/libs/freetype2/cache/ftcerror.h index df381f5218..5998d42daf 100644 --- a/src/libs/freetype2/cache/ftcerror.h +++ b/src/libs/freetype2/cache/ftcerror.h @@ -37,4 +37,4 @@ #endif /* __FTCERROR_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/cache/ftcglyph.c b/src/libs/freetype2/cache/ftcglyph.c index 27cb80db37..5e6c9771af 100644 --- a/src/libs/freetype2/cache/ftcglyph.c +++ b/src/libs/freetype2/cache/ftcglyph.c @@ -4,7 +4,7 @@ /* */ /* FreeType Glyph Image (FT_Glyph) cache (body). */ /* */ -/* Copyright 2000-2001 by */ +/* Copyright 2000-2001, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,54 +20,64 @@ #include FT_CACHE_H #include FT_CACHE_INTERNAL_GLYPH_H #include FT_ERRORS_H -#include FT_LIST_H #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H +#include "ftccback.h" #include "ftcerror.h" /* create a new chunk node, setting its cache index and ref count */ FT_EXPORT_DEF( void ) - ftc_glyph_node_init( FTC_GlyphNode gnode, - FT_UInt gindex, - FTC_GlyphFamily gfam ) + FTC_GNode_Init( FTC_GNode gnode, + FT_UInt gindex, + FTC_Family family ) { - FT_UInt len; - FT_UInt start = FTC_GLYPH_FAMILY_START( gfam, gindex ); - - - gnode->item_start = (FT_UShort)start; - - len = gfam->item_total - start; - if ( len > gfam->item_count ) - len = gfam->item_count; - - gnode->item_count = (FT_UShort)len; - gfam->family.num_nodes++; + gnode->family = family; + gnode->gindex = gindex; + family->num_nodes++; } FT_EXPORT_DEF( void ) - ftc_glyph_node_done( FTC_GlyphNode gnode, - FTC_Cache cache ) + FTC_GNode_UnselectFamily( FTC_GNode gnode, + FTC_Cache cache ) + { + FTC_Family family = gnode->family; + + + gnode->family = NULL; + if ( family && --family->num_nodes <= 0 ) + FTC_MruList_Remove( &FTC_GCACHE( cache )->families, + (FTC_MruNode)family ); + } + + + FT_EXPORT_DEF( void ) + FTC_GNode_Done( FTC_GNode gnode, + FTC_Cache cache ) { /* finalize the node */ - gnode->item_count = 0; - gnode->item_start = 0; + gnode->gindex = 0; - ftc_node_done( FTC_NODE( gnode ), cache ); + FTC_GNode_UnselectFamily( gnode, cache ); } FT_EXPORT_DEF( FT_Bool ) - ftc_glyph_node_compare( FTC_GlyphNode gnode, - FTC_GlyphQuery gquery ) + FTC_GNode_Compare( FTC_GNode gnode, + FTC_GQuery gquery ) { - FT_UInt start = (FT_UInt)gnode->item_start; - FT_UInt count = (FT_UInt)gnode->item_count; + return FT_BOOL( gnode->family == gquery->family && + gnode->gindex == gquery->gindex ); + } - return FT_BOOL( (FT_UInt)( gquery->gindex - start ) < count ); + + FT_LOCAL_DEF( FT_Bool ) + ftc_gnode_compare( FTC_GNode gnode, + FTC_GQuery gquery ) + { + return FTC_GNode_Compare( gnode, gquery ); } @@ -79,37 +89,90 @@ /*************************************************************************/ /*************************************************************************/ + FT_EXPORT_DEF( void ) + FTC_Family_Init( FTC_Family family, + FTC_Cache cache ) + { + FTC_GCacheClass clazz = FTC_CACHE__GCACHE_CLASS( cache ); + + + family->clazz = clazz->family_class; + family->num_nodes = 0; + family->cache = cache; + } + FT_EXPORT_DEF( FT_Error ) - ftc_glyph_family_init( FTC_GlyphFamily gfam, - FT_UInt32 hash, - FT_UInt item_count, - FT_UInt item_total, - FTC_GlyphQuery gquery, - FTC_Cache cache ) + FTC_GCache_Init( FTC_GCache cache ) { - FT_Error error; + FT_Error error; - - error = ftc_family_init( FTC_FAMILY( gfam ), FTC_QUERY( gquery ), cache ); + error = FTC_Cache_Init( FTC_CACHE( cache ) ); if ( !error ) { - gfam->hash = hash; - gfam->item_total = item_total; - gfam->item_count = item_count; - - FTC_GLYPH_FAMILY_FOUND( gfam, gquery ); + FTC_GCacheClass clazz = (FTC_GCacheClass)FTC_CACHE( cache )->org_class; + + FTC_MruList_Init( &cache->families, + clazz->family_class, + 0, /* no maximum here! */ + cache, + FTC_CACHE( cache )->memory ); } return error; } - FT_EXPORT_DEF( void ) - ftc_glyph_family_done( FTC_GlyphFamily gfam ) + FT_LOCAL_DEF( FT_Error ) + ftc_gcache_init( FTC_GCache cache ) { - ftc_family_done( FTC_FAMILY( gfam ) ); + return FTC_GCache_Init( cache ); } -/* END */ + FT_EXPORT_DEF( void ) + FTC_GCache_Done( FTC_GCache cache ) + { + FTC_Cache_Done( (FTC_Cache)cache ); + FTC_MruList_Done( &cache->families ); + } + + + FT_LOCAL_DEF( void ) + ftc_gcache_done( FTC_GCache cache ) + { + FTC_GCache_Done( cache ); + } + + + FT_EXPORT_DEF( FT_Error ) + FTC_GCache_New( FTC_Manager manager, + FTC_GCacheClass clazz, + FTC_GCache *acache ) + { + return FTC_Manager_RegisterCache( manager, (FTC_CacheClass)clazz, + (FTC_Cache*)acache ); + } + + + FT_EXPORT_DEF( FT_Error ) + FTC_GCache_Lookup( FTC_GCache cache, + FT_UInt32 hash, + FT_UInt gindex, + FTC_GQuery query, + FTC_Node *anode ) + { + FT_Error error; + + + query->gindex = gindex; + + FTC_MRULIST_LOOKUP( &cache->families, query, query->family, error ); + if ( !error ) + error = FTC_Cache_Lookup( FTC_CACHE( cache ), hash, query, anode ); + + return error; + } + + +/* END */ diff --git a/src/libs/freetype2/cache/ftcimage.c b/src/libs/freetype2/cache/ftcimage.c index 47af4f5bda..22a26ac47c 100644 --- a/src/libs/freetype2/cache/ftcimage.c +++ b/src/libs/freetype2/cache/ftcimage.c @@ -4,7 +4,7 @@ /* */ /* FreeType Image cache (body). */ /* */ -/* Copyright 2000-2001 by */ +/* Copyright 2000-2001, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,133 +18,83 @@ #include <ft2build.h> #include FT_CACHE_H -#include FT_CACHE_IMAGE_H -#include FT_CACHE_INTERNAL_GLYPH_H +#include FT_CACHE_INTERNAL_IMAGE_H #include FT_INTERNAL_MEMORY_H +#include "ftccback.h" #include "ftcerror.h" - /* the FT_Glyph image node type */ - typedef struct FTC_ImageNodeRec_ - { - FTC_GlyphNodeRec gnode; - FT_Glyph glyph; - - } FTC_ImageNodeRec, *FTC_ImageNode; - - -#define FTC_IMAGE_NODE( x ) ( (FTC_ImageNode)( x ) ) -#define FTC_IMAGE_NODE_GINDEX( x ) FTC_GLYPH_NODE_GINDEX( x ) - - - /* the glyph image query */ - typedef struct FTC_ImageQueryRec_ - { - FTC_GlyphQueryRec gquery; - FTC_ImageTypeRec type; - - } FTC_ImageQueryRec, *FTC_ImageQuery; - - -#define FTC_IMAGE_QUERY( x ) ( (FTC_ImageQuery)( x ) ) - - - /* the glyph image set type */ - typedef struct FTC_ImageFamilyRec_ - { - FTC_GlyphFamilyRec gfam; - FTC_ImageTypeRec type; - - } FTC_ImageFamilyRec, *FTC_ImageFamily; - - -#define FTC_IMAGE_FAMILY( x ) ( (FTC_ImageFamily)( x ) ) -#define FTC_IMAGE_FAMILY_MEMORY( x ) FTC_GLYPH_FAMILY_MEMORY( &(x)->gfam ) - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GLYPH IMAGE NODES *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* finalize a given glyph image node */ - FT_CALLBACK_DEF( void ) - ftc_image_node_done( FTC_ImageNode inode, - FTC_Cache cache ) + FT_EXPORT_DEF( void ) + FTC_INode_Free( FTC_INode inode, + FTC_Cache cache ) { + FT_Memory memory = cache->memory; + + if ( inode->glyph ) { FT_Done_Glyph( inode->glyph ); inode->glyph = NULL; } - ftc_glyph_node_done( FTC_GLYPH_NODE( inode ), cache ); + FTC_GNode_Done( FTC_GNODE( inode ), cache ); + FT_FREE( inode ); + } + + + FT_LOCAL_DEF( void ) + ftc_inode_free( FTC_INode inode, + FTC_Cache cache ) + { + FTC_INode_Free( inode, cache ); } /* initialize a new glyph image node */ - FT_CALLBACK_DEF( FT_Error ) - ftc_image_node_init( FTC_ImageNode inode, - FTC_GlyphQuery gquery, - FTC_Cache cache ) + FT_EXPORT_DEF( FT_Error ) + FTC_INode_New( FTC_INode *pinode, + FTC_GQuery gquery, + FTC_Cache cache ) { - FTC_ImageFamily ifam = FTC_IMAGE_FAMILY( gquery->query.family ); - FT_Error error; - FT_Face face; - FT_Size size; + FT_Memory memory = cache->memory; + FT_Error error; + FTC_INode inode; - /* initialize its inner fields */ - ftc_glyph_node_init( FTC_GLYPH_NODE( inode ), - gquery->gindex, - FTC_GLYPH_FAMILY( ifam ) ); - - /* we will now load the glyph image */ - error = FTC_Manager_Lookup_Size( FTC_FAMILY( ifam )->cache->manager, - &ifam->type.font, - &face, &size ); - if ( !error ) + if ( !FT_NEW( inode ) ) { - FT_UInt gindex = FTC_GLYPH_NODE_GINDEX( inode ); + FTC_GNode gnode = FTC_GNODE( inode ); + FTC_Family family = gquery->family; + FT_UInt gindex = gquery->gindex; + FTC_IFamilyClass clazz = FTC_CACHE__IFAMILY_CLASS( cache ); - error = FT_Load_Glyph( face, gindex, ifam->type.flags ); - if ( !error ) - { - if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP || - face->glyph->format == FT_GLYPH_FORMAT_OUTLINE ) - { - /* ok, copy it */ - FT_Glyph glyph; + /* initialize its inner fields */ + FTC_GNode_Init( gnode, gindex, family ); - - error = FT_Get_Glyph( face->glyph, &glyph ); - if ( !error ) - { - inode->glyph = glyph; - goto Exit; - } - } - else - error = FTC_Err_Invalid_Argument; - } + /* we will now load the glyph image */ + error = clazz->family_load_glyph( family, gindex, cache, + &inode->glyph ); } - /* in case of error */ - ftc_glyph_node_done( FTC_GLYPH_NODE(inode), cache ); - - Exit: + *pinode = inode; return error; } - FT_CALLBACK_DEF( FT_ULong ) - ftc_image_node_weight( FTC_ImageNode inode ) + FT_LOCAL_DEF( FT_Error ) + ftc_inode_new( FTC_INode *pinode, + FTC_GQuery gquery, + FTC_Cache cache ) + { + return FTC_INode_New( pinode, gquery, cache ); + } + + + FT_EXPORT_DEF( FT_ULong ) + FTC_INode_Weight( FTC_INode inode ) { FT_ULong size = 0; FT_Glyph glyph = inode->glyph; @@ -185,215 +135,11 @@ } - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GLYPH IMAGE SETS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - FT_CALLBACK_DEF( FT_Error ) - ftc_image_family_init( FTC_ImageFamily ifam, - FTC_ImageQuery iquery, - FTC_Cache cache ) + FT_LOCAL_DEF( FT_ULong ) + ftc_inode_weight( FTC_INode inode ) { - FTC_Manager manager = cache->manager; - FT_Error error; - FT_Face face; - - - ifam->type = iquery->type; - - /* we need to compute "iquery.item_total" now */ - error = FTC_Manager_Lookup_Face( manager, - iquery->type.font.face_id, - &face ); - if ( !error ) - { - error = ftc_glyph_family_init( FTC_GLYPH_FAMILY( ifam ), - FTC_IMAGE_TYPE_HASH( &ifam->type ), - 1, - face->num_glyphs, - FTC_GLYPH_QUERY( iquery ), - cache ); - } - - return error; + return FTC_INode_Weight( inode ); } - FT_CALLBACK_DEF( FT_Bool ) - ftc_image_family_compare( FTC_ImageFamily ifam, - FTC_ImageQuery iquery ) - { - FT_Bool result; - - - result = FT_BOOL( FTC_IMAGE_TYPE_COMPARE( &ifam->type, &iquery->type ) ); - if ( result ) - FTC_GLYPH_FAMILY_FOUND( ifam, iquery ); - - return result; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** GLYPH IMAGE CACHE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - - FT_CALLBACK_TABLE_DEF - const FTC_Cache_ClassRec ftc_image_cache_class = - { - sizeof ( FTC_CacheRec ), - (FTC_Cache_InitFunc) ftc_cache_init, - (FTC_Cache_ClearFunc)ftc_cache_clear, - (FTC_Cache_DoneFunc) ftc_cache_done, - - sizeof ( FTC_ImageFamilyRec ), - (FTC_Family_InitFunc) ftc_image_family_init, - (FTC_Family_CompareFunc)ftc_image_family_compare, - (FTC_Family_DoneFunc) ftc_glyph_family_done, - - sizeof ( FTC_ImageNodeRec ), - (FTC_Node_InitFunc) ftc_image_node_init, - (FTC_Node_WeightFunc) ftc_image_node_weight, - (FTC_Node_CompareFunc)ftc_glyph_node_compare, - (FTC_Node_DoneFunc) ftc_image_node_done - }; - - - /* documentation is in ftcimage.h */ - - FT_EXPORT_DEF( FT_Error ) - FTC_ImageCache_New( FTC_Manager manager, - FTC_ImageCache *acache ) - { - return FTC_Manager_Register_Cache( - manager, - (FTC_Cache_Class)&ftc_image_cache_class, - FTC_CACHE_P( acache ) ); - } - - - /* documentation is in ftcimage.h */ - - FT_EXPORT_DEF( FT_Error ) - FTC_ImageCache_Lookup( FTC_ImageCache cache, - FTC_ImageType type, - FT_UInt gindex, - FT_Glyph *aglyph, - FTC_Node *anode ) - { - FTC_ImageQueryRec iquery; - FTC_ImageNode node; - FT_Error error; - - - /* some argument checks are delayed to ftc_cache_lookup */ - if ( !aglyph ) - return FTC_Err_Invalid_Argument; - - if ( anode ) - *anode = NULL; - - iquery.gquery.gindex = gindex; - iquery.type = *type; - - error = ftc_cache_lookup( FTC_CACHE( cache ), - FTC_QUERY( &iquery ), - (FTC_Node*)&node ); - if ( !error ) - { - *aglyph = node->glyph; - - if ( anode ) - { - *anode = (FTC_Node)node; - FTC_NODE( node )->ref_count++; - } - } - - return error; - } - - - /* backwards-compatibility functions */ - - FT_EXPORT_DEF( FT_Error ) - FTC_Image_Cache_New( FTC_Manager manager, - FTC_Image_Cache *acache ) - { - return FTC_ImageCache_New( manager, (FTC_ImageCache*)acache ); - } - - - FT_EXPORT_DEF( FT_Error ) - FTC_Image_Cache_Lookup( FTC_Image_Cache icache, - FTC_Image_Desc* desc, - FT_UInt gindex, - FT_Glyph *aglyph ) - { - FTC_ImageTypeRec type0; - - - if ( !desc ) - return FTC_Err_Invalid_Argument; - - type0.font = desc->font; - - /* convert image type flags to load flags */ - { - FT_UInt load_flags = FT_LOAD_DEFAULT; - FT_UInt type = desc->image_type; - - - /* determine load flags, depending on the font description's */ - /* image type */ - - if ( ftc_image_format( type ) == ftc_image_format_bitmap ) - { - if ( type & ftc_image_flag_monochrome ) - load_flags |= FT_LOAD_MONOCHROME; - - /* disable embedded bitmaps loading if necessary */ - if ( type & ftc_image_flag_no_sbits ) - load_flags |= FT_LOAD_NO_BITMAP; - } - else - { - /* we want an outline, don't load embedded bitmaps */ - load_flags |= FT_LOAD_NO_BITMAP; - - if ( type & ftc_image_flag_unscaled ) - load_flags |= FT_LOAD_NO_SCALE; - } - - /* always render glyphs to bitmaps */ - load_flags |= FT_LOAD_RENDER; - - if ( type & ftc_image_flag_unhinted ) - load_flags |= FT_LOAD_NO_HINTING; - - if ( type & ftc_image_flag_autohinted ) - load_flags |= FT_LOAD_FORCE_AUTOHINT; - - type0.flags = load_flags; - } - - return FTC_ImageCache_Lookup( (FTC_ImageCache)icache, - &type0, - gindex, - aglyph, - NULL ); - } - - -/* END */ +/* END */ diff --git a/src/libs/freetype2/cache/ftcmanag.c b/src/libs/freetype2/cache/ftcmanag.c index 4250a70963..9cc64891c4 100644 --- a/src/libs/freetype2/cache/ftcmanag.c +++ b/src/libs/freetype2/cache/ftcmanag.c @@ -4,7 +4,7 @@ /* */ /* FreeType Cache Manager (body). */ /* */ -/* Copyright 2000-2001, 2002 by */ +/* Copyright 2000-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,8 +18,7 @@ #include <ft2build.h> #include FT_CACHE_H -#include FT_CACHE_MANAGER_H -#include FT_CACHE_INTERNAL_LRU_H +#include FT_CACHE_INTERNAL_MANAGER_H #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H #include FT_SIZES_H @@ -33,32 +32,171 @@ #define FTC_LRU_GET_MANAGER( lru ) ( (FTC_Manager)(lru)->user_data ) - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** FACE LRU IMPLEMENTATION *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - typedef struct FTC_FaceNodeRec_* FTC_FaceNode; - typedef struct FTC_SizeNodeRec_* FTC_SizeNode; - - - typedef struct FTC_FaceNodeRec_ + static FT_Error + ftc_scaler_lookup_size( FTC_Manager manager, + FTC_Scaler scaler, + FT_Size *asize ) { - FT_LruNodeRec lru; - FT_Face face; + FT_Face face; + FT_Size size = NULL; + FT_Error error; - } FTC_FaceNodeRec; + + error = FTC_Manager_LookupFace( manager, scaler->face_id, &face ); + if ( error ) + goto Exit; + + error = FT_New_Size( face, &size ); + if ( error ) + goto Exit; + + FT_Activate_Size( size ); + + if ( scaler->pixel ) + error = FT_Set_Pixel_Sizes( face, scaler->width, scaler->height ); + else + error = FT_Set_Char_Size( face, scaler->width, scaler->height, + scaler->x_res, scaler->y_res ); + if ( error ) + { + FT_Done_Size( size ); + size = NULL; + } + + Exit: + *asize = size; + return error; + } typedef struct FTC_SizeNodeRec_ { - FT_LruNodeRec lru; - FT_Size size; + FTC_MruNodeRec node; + FT_Size size; + FTC_ScalerRec scaler; - } FTC_SizeNodeRec; + } FTC_SizeNodeRec, *FTC_SizeNode; + + + FT_CALLBACK_DEF( void ) + ftc_size_node_done( FTC_SizeNode node ) + { + FT_Size size = node->size; + + + if ( size ) + FT_Done_Size( size ); + } + + + FT_CALLBACK_DEF( FT_Bool ) + ftc_size_node_compare( FTC_SizeNode node, + FTC_Scaler scaler ) + { + FTC_Scaler scaler0 = &node->scaler; + + + if ( FTC_SCALER_COMPARE( scaler0, scaler ) ) + { + FT_Activate_Size( node->size ); + return 1; + } + return 0; + } + + + FT_CALLBACK_DEF( FT_Error ) + ftc_size_node_init( FTC_SizeNode node, + FTC_Scaler scaler, + FTC_Manager manager ) + { + node->scaler = scaler[0]; + + return ftc_scaler_lookup_size( manager, scaler, &node->size ); + } + + + FT_CALLBACK_DEF( FT_Error ) + ftc_size_node_reset( FTC_SizeNode node, + FTC_Scaler scaler, + FTC_Manager manager ) + { + FT_Done_Size( node->size ); + + node->scaler = scaler[0]; + + return ftc_scaler_lookup_size( manager, scaler, &node->size ); + } + + + FT_CALLBACK_TABLE_DEF + const FTC_MruListClassRec ftc_size_list_class = + { + sizeof( FTC_SizeNodeRec ), + (FTC_MruNode_CompareFunc)ftc_size_node_compare, + (FTC_MruNode_InitFunc) ftc_size_node_init, + (FTC_MruNode_ResetFunc) ftc_size_node_reset, + (FTC_MruNode_DoneFunc) ftc_size_node_done + }; + + + /* helper function used by ftc_face_node_done */ + static FT_Bool + ftc_size_node_compare_faceid( FTC_SizeNode node, + FTC_FaceID face_id ) + { + return FT_BOOL( node->scaler.face_id == face_id ); + } + + + FT_EXPORT_DEF( FT_Error ) + FTC_Manager_LookupSize( FTC_Manager manager, + FTC_Scaler scaler, + FT_Size *asize ) + { + FT_Error error; + FTC_SizeNode node; + + + if ( asize == NULL ) + return FTC_Err_Bad_Argument; + + *asize = NULL; + + if ( !manager ) + return FTC_Err_Invalid_Cache_Handle; + +#ifdef FTC_INLINE + + FTC_MRULIST_LOOKUP_CMP( &manager->sizes, scaler, ftc_size_node_compare, + node, error ); + +#else + error = FTC_MruList_Lookup( &manager->sizes, scaler, (FTC_MruNode*)&node ); +#endif + + if ( !error ) + *asize = node->size; + + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FACE MRU IMPLEMENTATION *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct FTC_FaceNodeRec_ + { + FTC_MruNodeRec node; + FTC_FaceID face_id; + FT_Face face; + + } FTC_FaceNodeRec, *FTC_FaceNode; FT_CALLBACK_DEF( FT_Error ) @@ -69,6 +207,8 @@ FT_Error error; + node->face_id = face_id; + error = manager->request_face( face_id, manager->library, manager->request_data, @@ -84,55 +224,50 @@ } - /* helper function for ftc_face_node_done() */ - FT_CALLBACK_DEF( FT_Bool ) - ftc_size_node_select( FTC_SizeNode node, - FT_Face face ) - { - return FT_BOOL( node->size->face == face ); - } - - FT_CALLBACK_DEF( void ) ftc_face_node_done( FTC_FaceNode node, FTC_Manager manager ) { - FT_Face face = node->face; - - - /* we must begin by removing all sizes for the target face */ - /* from the manager's list */ - FT_LruList_Remove_Selection( manager->sizes_list, - (FT_LruNode_SelectFunc)ftc_size_node_select, - face ); + /* we must begin by removing all scalers for the target face */ + /* from the manager's list */ + FTC_MruList_RemoveSelection( + & manager->sizes, + (FTC_MruNode_CompareFunc)ftc_size_node_compare_faceid, + node->face_id ); /* all right, we can discard the face now */ - FT_Done_Face( face ); - node->face = NULL; + FT_Done_Face( node->face ); + node->face = NULL; + node->face_id = NULL; + } + + + FT_CALLBACK_DEF( FT_Bool ) + ftc_face_node_compare( FTC_FaceNode node, + FTC_FaceID face_id ) + { + return FT_BOOL( node->face_id == face_id ); } FT_CALLBACK_TABLE_DEF - const FT_LruList_ClassRec ftc_face_list_class = + const FTC_MruListClassRec ftc_face_list_class = { - sizeof ( FT_LruListRec ), - (FT_LruList_InitFunc)0, - (FT_LruList_DoneFunc)0, + sizeof( FTC_FaceNodeRec), - sizeof ( FTC_FaceNodeRec ), - (FT_LruNode_InitFunc) ftc_face_node_init, - (FT_LruNode_DoneFunc) ftc_face_node_done, - (FT_LruNode_FlushFunc) 0, /* no flushing needed */ - (FT_LruNode_CompareFunc)0, /* direct comparison of FTC_FaceID handles */ + (FTC_MruNode_CompareFunc)ftc_face_node_compare, + (FTC_MruNode_InitFunc) ftc_face_node_init, + (FTC_MruNode_ResetFunc) NULL, + (FTC_MruNode_DoneFunc) ftc_face_node_done }; /* documentation is in ftcache.h */ FT_EXPORT_DEF( FT_Error ) - FTC_Manager_Lookup_Face( FTC_Manager manager, - FTC_FaceID face_id, - FT_Face *aface ) + FTC_Manager_LookupFace( FTC_Manager manager, + FTC_FaceID face_id, + FT_Face *aface ) { FT_Error error; FTC_FaceNode node; @@ -146,9 +281,16 @@ if ( !manager ) return FTC_Err_Invalid_Cache_Handle; - error = FT_LruList_Lookup( manager->faces_list, - (FT_LruKey)face_id, - (FT_LruNode*)&node ); + /* we break encapsulation for the sake of speed */ +#ifdef FTC_INLINE + + FTC_MRULIST_LOOKUP_CMP( &manager->faces, face_id, ftc_face_node_compare, + node, error ); + +#else + error = FTC_MruList_Lookup( &manager->faces, face_id, (FTC_MruNode*)&node ); +#endif + if ( !error ) *aface = node->face; @@ -156,283 +298,6 @@ } - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** SIZES LRU IMPLEMENTATION *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - typedef struct FTC_SizeQueryRec_ - { - FT_Face face; - FT_UInt width; - FT_UInt height; - - } FTC_SizeQueryRec, *FTC_SizeQuery; - - - FT_CALLBACK_DEF( FT_Error ) - ftc_size_node_init( FTC_SizeNode node, - FTC_SizeQuery query ) - { - FT_Face face = query->face; - FT_Size size; - FT_Error error; - - - node->size = NULL; - error = FT_New_Size( face, &size ); - if ( !error ) - { - FT_Activate_Size( size ); - error = FT_Set_Pixel_Sizes( query->face, - query->width, - query->height ); - if ( error ) - FT_Done_Size( size ); - else - node->size = size; - } - return error; - } - - - FT_CALLBACK_DEF( void ) - ftc_size_node_done( FTC_SizeNode node ) - { - if ( node->size ) - { - FT_Done_Size( node->size ); - node->size = NULL; - } - } - - - FT_CALLBACK_DEF( FT_Error ) - ftc_size_node_flush( FTC_SizeNode node, - FTC_SizeQuery query ) - { - FT_Size size = node->size; - FT_Error error; - - - if ( size->face == query->face ) - { - FT_Activate_Size( size ); - error = FT_Set_Pixel_Sizes( query->face, query->width, query->height ); - if ( error ) - { - FT_Done_Size( size ); - node->size = NULL; - } - } - else - { - FT_Done_Size( size ); - node->size = NULL; - - error = ftc_size_node_init( node, query ); - } - return error; - } - - - FT_CALLBACK_DEF( FT_Bool ) - ftc_size_node_compare( FTC_SizeNode node, - FTC_SizeQuery query ) - { - FT_Size size = node->size; - - - return FT_BOOL( size->face == query->face && - (FT_UInt)size->metrics.x_ppem == query->width && - (FT_UInt)size->metrics.y_ppem == query->height ); - } - - - FT_CALLBACK_TABLE_DEF - const FT_LruList_ClassRec ftc_size_list_class = - { - sizeof ( FT_LruListRec ), - (FT_LruList_InitFunc)0, - (FT_LruList_DoneFunc)0, - - sizeof ( FTC_SizeNodeRec ), - (FT_LruNode_InitFunc) ftc_size_node_init, - (FT_LruNode_DoneFunc) ftc_size_node_done, - (FT_LruNode_FlushFunc) ftc_size_node_flush, - (FT_LruNode_CompareFunc)ftc_size_node_compare - }; - - - /* documentation is in ftcache.h */ - - FT_EXPORT_DEF( FT_Error ) - FTC_Manager_Lookup_Size( FTC_Manager manager, - FTC_Font font, - FT_Face *aface, - FT_Size *asize ) - { - FT_Error error; - - - /* check for valid `manager' delayed to FTC_Manager_Lookup_Face() */ - if ( aface ) - *aface = 0; - - if ( asize ) - *asize = 0; - - error = FTC_Manager_Lookup_Face( manager, font->face_id, aface ); - if ( !error ) - { - FTC_SizeQueryRec query; - FTC_SizeNode node; - - - query.face = *aface; - query.width = font->pix_width; - query.height = font->pix_height; - - error = FT_LruList_Lookup( manager->sizes_list, - (FT_LruKey)&query, - (FT_LruNode*)&node ); - if ( !error ) - { - /* select the size as the current one for this face */ - FT_Activate_Size( node->size ); - - if ( asize ) - *asize = node->size; - } - } - - return error; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** SET TABLE MANAGEMENT *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static void - ftc_family_table_init( FTC_FamilyTable table ) - { - table->count = 0; - table->size = 0; - table->entries = NULL; - table->free = FTC_FAMILY_ENTRY_NONE; - } - - - static void - ftc_family_table_done( FTC_FamilyTable table, - FT_Memory memory ) - { - FT_FREE( table->entries ); - table->free = 0; - table->count = 0; - table->size = 0; - } - - - FT_EXPORT_DEF( FT_Error ) - ftc_family_table_alloc( FTC_FamilyTable table, - FT_Memory memory, - FTC_FamilyEntry *aentry ) - { - FTC_FamilyEntry entry; - FT_Error error = 0; - - - /* re-allocate table size when needed */ - if ( table->free == FTC_FAMILY_ENTRY_NONE && table->count >= table->size ) - { - FT_UInt old_size = table->size; - FT_UInt new_size, idx; - - - if ( old_size == 0 ) - new_size = 8; - else - { - new_size = old_size * 2; - - /* check for (unlikely) overflow */ - if ( new_size < old_size ) - new_size = 65534; - } - - if ( FT_RENEW_ARRAY( table->entries, old_size, new_size ) ) - return error; - - table->size = new_size; - - entry = table->entries + old_size; - table->free = old_size; - - for ( idx = old_size; idx + 1 < new_size; idx++, entry++ ) - { - entry->link = idx + 1; - entry->index = idx; - } - - entry->link = FTC_FAMILY_ENTRY_NONE; - entry->index = idx; - } - - if ( table->free != FTC_FAMILY_ENTRY_NONE ) - { - entry = table->entries + table->free; - table->free = entry->link; - } - else if ( table->count < table->size ) - { - entry = table->entries + table->count++; - } - else - { - FT_ERROR(( "ftc_family_table_alloc: internal bug!" )); - return FTC_Err_Invalid_Argument; - } - - entry->link = FTC_FAMILY_ENTRY_NONE; - table->count++; - - *aentry = entry; - return error; - } - - - FT_EXPORT_DEF( void ) - ftc_family_table_free( FTC_FamilyTable table, - FT_UInt idx ) - { - /* simply add it to the linked list of free entries */ - if ( idx < table->count ) - { - FTC_FamilyEntry entry = table->entries + idx; - - - if ( entry->link != FTC_FAMILY_ENTRY_NONE ) - FT_ERROR(( "ftc_family_table_free: internal bug!\n" )); - else - { - entry->link = table->free; - table->free = entry->index; - table->count--; - } - } - } - - /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -475,41 +340,28 @@ if ( max_bytes == 0 ) max_bytes = FTC_MAX_BYTES_DEFAULT; - error = FT_LruList_New( &ftc_face_list_class, - max_faces, - manager, - memory, - &manager->faces_list ); - if ( error ) - goto Exit; - - error = FT_LruList_New( &ftc_size_list_class, - max_sizes, - manager, - memory, - &manager->sizes_list ); - if ( error ) - goto Exit; - manager->library = library; + manager->memory = memory; manager->max_weight = max_bytes; - manager->cur_weight = 0; manager->request_face = requester; manager->request_data = req_data; - ftc_family_table_init( &manager->families ); + FTC_MruList_Init( &manager->faces, + &ftc_face_list_class, + max_faces, + manager, + memory ); + + FTC_MruList_Init( &manager->sizes, + &ftc_size_list_class, + max_sizes, + manager, + memory ); *amanager = manager; Exit: - if ( error && manager ) - { - FT_LruList_Destroy( manager->faces_list ); - FT_LruList_Destroy( manager->sizes_list ); - FT_FREE( manager ); - } - return error; } @@ -526,31 +378,29 @@ if ( !manager || !manager->library ) return; - memory = manager->library->memory; + memory = manager->memory; /* now discard all caches */ - for (idx = 0; idx < FTC_MAX_CACHES; idx++ ) + for (idx = manager->num_caches; idx-- > 0; ) { FTC_Cache cache = manager->caches[idx]; if ( cache ) { - cache->clazz->cache_done( cache ); + cache->clazz.cache_done( cache ); FT_FREE( cache ); - manager->caches[idx] = 0; + manager->caches[idx] = NULL; } } - - /* discard families table */ - ftc_family_table_done( &manager->families, memory ); + manager->num_caches = 0; /* discard faces and sizes */ - FT_LruList_Destroy( manager->faces_list ); - manager->faces_list = 0; + FTC_MruList_Done( &manager->sizes ); + FTC_MruList_Done( &manager->faces ); - FT_LruList_Destroy( manager->sizes_list ); - manager->sizes_list = 0; + manager->library = NULL; + manager->memory = NULL; FT_FREE( manager ); } @@ -563,8 +413,8 @@ { if ( manager ) { - FT_LruList_Reset( manager->sizes_list ); - FT_LruList_Reset( manager->faces_list ); + FTC_MruList_Reset( &manager->sizes ); + FTC_MruList_Reset( &manager->faces ); } /* XXX: FIXME: flush the caches? */ } @@ -576,7 +426,7 @@ FTC_Manager_Check( FTC_Manager manager ) { FTC_Node node, first; - + first = manager->nodes_list; @@ -584,26 +434,22 @@ if ( first ) { FT_ULong weight = 0; - + node = first; do { - FTC_FamilyEntry entry = manager->families.entries + node->fam_index; - FTC_Cache cache; + FTC_Cache cache = manager->caches[node->cache_index]; - if ( (FT_UInt)node->fam_index >= manager->families.count || - entry->link != FTC_FAMILY_ENTRY_NONE ) - FT_ERROR(( "FTC_Manager_Check: invalid node (family index = %ld\n", - node->fam_index )); + + if ( (FT_UInt)node->cache_index >= manager->num_caches ) + FT_ERROR(( "FTC_Manager_Check: invalid node (cache index = %ld\n", + node->cache_index )); else - { - cache = entry->cache; - weight += cache->clazz->node_weight( node, cache ); - } + weight += cache->clazz.node_weight( node, cache ); - node = node->mru_next; + node = FTC_NODE__NEXT( node ); } while ( node != first ); @@ -622,7 +468,7 @@ do { count++; - node = node->mru_next; + node = FTC_NODE__NEXT( node ); } while ( node != first ); @@ -664,14 +510,14 @@ if ( manager->cur_weight < manager->max_weight || first == NULL ) return; - /* go to last node - it's a circular list */ - node = first->mru_prev; + /* go to last node -- it's a circular list */ + node = FTC_NODE__PREV( first ); do { - FTC_Node prev = node->mru_prev; + FTC_Node prev; - prev = ( node == first ) ? NULL : node->mru_prev; + prev = ( node == first ) ? NULL : FTC_NODE__PREV( node ); if ( node->ref_count <= 0 ) ftc_node_destroy( node, manager ); @@ -685,9 +531,9 @@ /* documentation is in ftcmanag.h */ FT_EXPORT_DEF( FT_Error ) - FTC_Manager_Register_Cache( FTC_Manager manager, - FTC_Cache_Class clazz, - FTC_Cache *acache ) + FTC_Manager_RegisterCache( FTC_Manager manager, + FTC_CacheClass clazz, + FTC_Cache *acache ) { FT_Error error = FTC_Err_Invalid_Argument; FTC_Cache cache = NULL; @@ -695,50 +541,37 @@ if ( manager && clazz && acache ) { - FT_Memory memory = manager->library->memory; - FT_UInt idx = 0; + FT_Memory memory = manager->memory; - /* check for an empty cache slot in the manager's table */ - for ( idx = 0; idx < FTC_MAX_CACHES; idx++ ) - { - if ( manager->caches[idx] == 0 ) - break; - } - - /* return an error if there are too many registered caches */ - if ( idx >= FTC_MAX_CACHES ) + if ( manager->num_caches >= FTC_MAX_CACHES ) { error = FTC_Err_Too_Many_Caches; - FT_ERROR(( "FTC_Manager_Register_Cache:" )); - FT_ERROR(( " too many registered caches\n" )); + FT_ERROR(( "%s: too many registered caches\n", + "FTC_Manager_Register_Cache" )); goto Exit; } if ( !FT_ALLOC( cache, clazz->cache_size ) ) { - cache->manager = manager; - cache->memory = memory; - cache->clazz = clazz; + cache->manager = manager; + cache->memory = memory; + cache->clazz = clazz[0]; + cache->org_class = clazz; /* THIS IS VERY IMPORTANT! IT WILL WRETCH THE MANAGER */ /* IF IT IS NOT SET CORRECTLY */ - cache->cache_index = idx; + cache->index = manager->num_caches; - if ( clazz->cache_init ) + error = clazz->cache_init( cache ); + if ( error ) { - error = clazz->cache_init( cache ); - if ( error ) - { - if ( clazz->cache_done ) - clazz->cache_done( cache ); - - FT_FREE( cache ); - goto Exit; - } + clazz->cache_done( cache ); + FT_FREE( cache ); + goto Exit; } - manager->caches[idx] = cache; + manager->caches[manager->num_caches++] = cache; } } @@ -748,18 +581,67 @@ } + FT_EXPORT_DEF( FT_UInt ) + FTC_Manager_FlushN( FTC_Manager manager, + FT_UInt count ) + { + FTC_Node first = manager->nodes_list; + FTC_Node node; + FT_UInt result; + + + /* try to remove `count' nodes from the list */ + if ( first == NULL ) /* empty list! */ + return 0; + + /* go to last node - it's a circular list */ + node = FTC_NODE__PREV(first); + for ( result = 0; result < count; ) + { + FTC_Node prev = FTC_NODE__PREV( node ); + + + /* don't touch locked nodes */ + if ( node->ref_count <= 0 ) + { + ftc_node_destroy( node, manager ); + result++; + } + + if ( prev == manager->nodes_list ) + break; + + node = prev; + } + return result; + } + + + FT_EXPORT_DEF( void ) + FTC_Manager_RemoveFaceID( FTC_Manager manager, + FTC_FaceID face_id ) + { + FT_UInt nn; + + /* this will remove all FTC_SizeNode that correspond to + * the face_id as well + */ + FTC_MruList_RemoveSelection( &manager->faces, NULL, face_id ); + + for ( nn = 0; nn < manager->num_caches; nn++ ) + FTC_Cache_RemoveFaceID( manager->caches[nn], face_id ); + } + + /* documentation is in ftcmanag.h */ FT_EXPORT_DEF( void ) FTC_Node_Unref( FTC_Node node, FTC_Manager manager ) { - if ( node && (FT_UInt)node->fam_index < manager->families.count && - manager->families.entries[node->fam_index].cache ) - { + if ( node && (FT_UInt)node->cache_index < manager->num_caches ) node->ref_count--; - } } -/* END */ +/* END */ diff --git a/src/libs/freetype2/cache/ftcmru.c b/src/libs/freetype2/cache/ftcmru.c new file mode 100644 index 0000000000..d4f733a110 --- /dev/null +++ b/src/libs/freetype2/cache/ftcmru.c @@ -0,0 +1,355 @@ +/***************************************************************************/ +/* */ +/* ftcmru.c */ +/* */ +/* FreeType MRU support (body). */ +/* */ +/* Copyright 2003, 2004 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. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_CACHE_H +#include FT_CACHE_INTERNAL_MRU_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H + +#include "ftcerror.h" + + + FT_EXPORT_DEF( void ) + FTC_MruNode_Prepend( FTC_MruNode *plist, + FTC_MruNode node ) + { + FTC_MruNode first = *plist; + + + if ( first ) + { + FTC_MruNode last = first->prev; + + +#ifdef FT_DEBUG_ERROR + { + FTC_MruNode cnode = first; + + + do + { + if ( cnode == node ) + { + fprintf( stderr, "FTC_MruNode_Prepend: invalid action!\n" ); + exit( 2 ); + } + cnode = cnode->next; + + } while ( cnode != first ); + } +#endif + + first->prev = node; + last->next = node; + node->next = first; + node->prev = last; + } + else + { + node->next = node; + node->prev = node; + } + *plist = node; + } + + + FT_EXPORT_DEF( void ) + FTC_MruNode_Up( FTC_MruNode *plist, + FTC_MruNode node ) + { + FTC_MruNode first = *plist; + + + FT_ASSERT( first != NULL ); + + if ( first != node ) + { + FTC_MruNode prev, next, last; + + +#ifdef FT_DEBUG_ERROR + { + FTC_MruNode cnode = first; + do + { + if ( cnode == node ) + goto Ok; + cnode = cnode->next; + + } while ( cnode != first ); + + fprintf( stderr, "FTC_MruNode_Up: invalid action!\n" ); + exit( 2 ); + Ok: + } +#endif + prev = node->prev; + next = node->next; + + prev->next = next; + next->prev = prev; + + last = first->prev; + + last->next = node; + first->prev = node; + + node->next = first; + node->prev = last; + + *plist = node; + } + } + + + FT_EXPORT_DEF( void ) + FTC_MruNode_Remove( FTC_MruNode *plist, + FTC_MruNode node ) + { + FTC_MruNode first = *plist; + FTC_MruNode prev, next; + + + FT_ASSERT( first != NULL ); + +#ifdef FT_DEBUG_ERROR + { + FTC_MruNode cnode = first; + + + do + { + if ( cnode == node ) + goto Ok; + cnode = cnode->next; + + } while ( cnode != first ); + + fprintf( stderr, "FTC_MruNode_Remove: invalid action!\n" ); + exit( 2 ); + Ok: + } +#endif + + prev = node->prev; + next = node->next; + + prev->next = next; + next->prev = prev; + + if ( node == next ) + { + FT_ASSERT( first == node ); + FT_ASSERT( prev == node ); + + *plist = NULL; + } + else if ( node == first ) + *plist = next; + } + + + FT_EXPORT_DEF( void ) + FTC_MruList_Init( FTC_MruList list, + FTC_MruListClass clazz, + FT_UInt max_nodes, + FT_Pointer data, + FT_Memory memory ) + { + list->num_nodes = 0; + list->max_nodes = max_nodes; + list->nodes = NULL; + list->clazz = *clazz; + list->data = data; + list->memory = memory; + } + + + FT_EXPORT( void ) + FTC_MruList_Reset( FTC_MruList list ) + { + while ( list->nodes ) + FTC_MruList_Remove( list, list->nodes ); + + FT_ASSERT( list->num_nodes == 0 ); + } + + + FT_EXPORT( void ) + FTC_MruList_Done( FTC_MruList list ) + { + FTC_MruList_Reset( list ); + } + + + FT_EXPORT_DEF( FTC_MruNode ) + FTC_MruList_Find( FTC_MruList list, + FT_Pointer key ) + { + FTC_MruNode_CompareFunc compare = list->clazz.node_compare; + FTC_MruNode first, node; + + + first = list->nodes; + node = NULL; + + if ( first ) + { + node = first; + do + { + if ( compare( node, key ) ) + { + if ( node != first ) + FTC_MruNode_Up( &list->nodes, node ); + + return node; + } + + node = node->next; + + } while ( node != first); + } + + return NULL; + } + + + FT_EXPORT_DEF( FT_Error ) + FTC_MruList_New( FTC_MruList list, + FT_Pointer key, + FTC_MruNode *anode ) + { + FT_Error error; + FTC_MruNode node; + FT_Memory memory = list->memory; + + + if ( list->num_nodes >= list->max_nodes && list->max_nodes > 0 ) + { + node = list->nodes->prev; + + FT_ASSERT( node ); + + if ( list->clazz.node_reset ) + { + FTC_MruNode_Up( &list->nodes, node ); + + error = list->clazz.node_reset( node, key, list->data ); + if ( !error ) + goto Exit; + } + + FTC_MruNode_Remove( &list->nodes, node ); + list->num_nodes--; + + if ( list->clazz.node_done ) + list->clazz.node_done( node, list->data ); + } + else if ( FT_ALLOC( node, list->clazz.node_size ) ) + goto Exit; + + error = list->clazz.node_init( node, key, list->data ); + if ( error ) + goto Fail; + + FTC_MruNode_Prepend( &list->nodes, node ); + list->num_nodes++; + + Exit: + *anode = node; + return error; + + Fail: + if ( list->clazz.node_done ) + list->clazz.node_done( node, list->data ); + + FT_FREE( node ); + goto Exit; + } + + + FT_EXPORT( FT_Error ) + FTC_MruList_Lookup( FTC_MruList list, + FT_Pointer key, + FTC_MruNode *anode ) + { + FTC_MruNode node; + + + node = FTC_MruList_Find( list, key ); + if ( node == NULL ) + return FTC_MruList_New( list, key, anode ); + + *anode = node; + return 0; + } + + + FT_EXPORT_DEF( void ) + FTC_MruList_Remove( FTC_MruList list, + FTC_MruNode node ) + { + FTC_MruNode_Remove( &list->nodes, node ); + list->num_nodes--; + + { + FT_Memory memory = list->memory; + + + if ( list->clazz.node_done ) + list->clazz.node_done( node, list->data ); + + FT_FREE( node ); + } + } + + + FT_EXPORT_DEF( void ) + FTC_MruList_RemoveSelection( FTC_MruList list, + FTC_MruNode_CompareFunc selection, + FT_Pointer key ) + { + FTC_MruNode first, node, next; + + + first = list->nodes; + while ( first && ( selection == NULL || selection( first, key ) ) ) + { + FTC_MruList_Remove( list, first ); + first = list->nodes; + } + + if ( first ) + { + node = first->next; + while ( node != first ) + { + next = node->next; + + if ( selection( node, key ) ) + FTC_MruList_Remove( list, node ); + + node = next; + } + } + } + + +/* END */ diff --git a/src/libs/freetype2/cache/ftcsbits.c b/src/libs/freetype2/cache/ftcsbits.c index f3b4603571..6af5c7ee6b 100644 --- a/src/libs/freetype2/cache/ftcsbits.c +++ b/src/libs/freetype2/cache/ftcsbits.c @@ -4,7 +4,7 @@ /* */ /* FreeType sbits manager (body). */ /* */ -/* Copyright 2000-2001, 2002 by */ +/* Copyright 2000-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,57 +18,15 @@ #include <ft2build.h> #include FT_CACHE_H -#include FT_CACHE_SMALL_BITMAPS_H -#include FT_CACHE_INTERNAL_GLYPH_H +#include FT_CACHE_INTERNAL_SBITS_H #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H #include FT_ERRORS_H +#include "ftccback.h" #include "ftcerror.h" -#define FTC_SBIT_ITEMS_PER_NODE 16 - - - typedef struct FTC_SBitNodeRec_* FTC_SBitNode; - - typedef struct FTC_SBitNodeRec_ - { - FTC_GlyphNodeRec gnode; - FTC_SBitRec sbits[FTC_SBIT_ITEMS_PER_NODE]; - - } FTC_SBitNodeRec; - - -#define FTC_SBIT_NODE( x ) ( (FTC_SBitNode)( x ) ) - - - typedef struct FTC_SBitQueryRec_ - { - FTC_GlyphQueryRec gquery; - FTC_ImageTypeRec type; - - } FTC_SBitQueryRec, *FTC_SBitQuery; - - -#define FTC_SBIT_QUERY( x ) ( (FTC_SBitQuery)( x ) ) - - - typedef struct FTC_SBitFamilyRec_* FTC_SBitFamily; - - /* sbit family structure */ - typedef struct FTC_SBitFamilyRec_ - { - FTC_GlyphFamilyRec gfam; - FTC_ImageTypeRec type; - - } FTC_SBitFamilyRec; - - -#define FTC_SBIT_FAMILY( x ) ( (FTC_SBitFamily)( x ) ) -#define FTC_SBIT_FAMILY_MEMORY( x ) FTC_GLYPH_FAMILY_MEMORY( &( x )->cset ) - - /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -100,174 +58,210 @@ } - FT_CALLBACK_DEF( void ) - ftc_sbit_node_done( FTC_SBitNode snode, - FTC_Cache cache ) + FT_EXPORT_DEF( void ) + FTC_SNode_Free( FTC_SNode snode, + FTC_Cache cache ) { FTC_SBit sbit = snode->sbits; - FT_UInt count = FTC_GLYPH_NODE( snode )->item_count; + FT_UInt count = snode->count; FT_Memory memory = cache->memory; for ( ; count > 0; sbit++, count-- ) FT_FREE( sbit->buffer ); - ftc_glyph_node_done( FTC_GLYPH_NODE( snode ), cache ); + FTC_GNode_Done( FTC_GNODE( snode ), cache ); + + FT_FREE( snode ); + } + + + FT_LOCAL_DEF( void ) + ftc_snode_free( FTC_SNode snode, + FTC_Cache cache ) + { + FTC_SNode_Free( snode, cache ); } static FT_Error - ftc_sbit_node_load( FTC_SBitNode snode, - FTC_Manager manager, - FTC_SBitFamily sfam, - FT_UInt gindex, - FT_ULong *asize ) + ftc_snode_load( FTC_SNode snode, + FTC_Manager manager, + FT_UInt gindex, + FT_ULong *asize ) { - FT_Error error; - FTC_GlyphNode gnode = FTC_GLYPH_NODE( snode ); - FT_Memory memory; - FT_Face face; - FT_Size size; - FTC_SBit sbit; + FT_Error error; + FTC_GNode gnode = FTC_GNODE( snode ); + FTC_Family family = gnode->family; + FT_Memory memory = manager->memory; + FT_Face face; + FTC_SBit sbit; + FTC_SFamilyClass clazz; - if ( gindex < (FT_UInt)gnode->item_start || - gindex >= (FT_UInt)gnode->item_start + gnode->item_count ) + if ( (FT_UInt)(gindex - gnode->gindex) >= snode->count ) { - FT_ERROR(( "ftc_sbit_node_load: invalid glyph index" )); + FT_ERROR(( "ftc_snode_load: invalid glyph index" )); return FTC_Err_Invalid_Argument; } - memory = manager->library->memory; + sbit = snode->sbits + ( gindex - gnode->gindex ); + clazz = (FTC_SFamilyClass)family->clazz; - sbit = snode->sbits + ( gindex - gnode->item_start ); + sbit->buffer = 0; + + error = clazz->family_load_glyph( family, gindex, manager, &face ); + if ( error ) + goto BadGlyph; - error = FTC_Manager_Lookup_Size( manager, &sfam->type.font, - &face, &size ); - if ( !error ) { - /* by default, indicates a `missing' glyph */ - sbit->buffer = 0; + FT_Int temp; + FT_GlyphSlot slot = face->glyph; + FT_Bitmap* bitmap = &slot->bitmap; + FT_Int xadvance, yadvance; - error = FT_Load_Glyph( face, gindex, sfam->type.flags | FT_LOAD_RENDER ); - if ( !error ) + + if ( slot->format != FT_GLYPH_FORMAT_BITMAP ) { - FT_Int temp; - FT_GlyphSlot slot = face->glyph; - FT_Bitmap* bitmap = &slot->bitmap; - FT_Int xadvance, yadvance; + FT_ERROR(( "%s: glyph loaded didn't return a bitmap!\n", + "ftc_snode_load" )); + goto BadGlyph; + } - - /* check that our values fit into 8-bit containers! */ - /* If this is not the case, our bitmap is too large */ - /* and we will leave it as `missing' with sbit.buffer = 0 */ + /* Check that our values fit into 8-bit containers! */ + /* If this is not the case, our bitmap is too large */ + /* and we will leave it as `missing' with sbit.buffer = 0 */ #define CHECK_CHAR( d ) ( temp = (FT_Char)d, temp == d ) #define CHECK_BYTE( d ) ( temp = (FT_Byte)d, temp == d ) - /* XXX: FIXME: add support for vertical layouts maybe */ + /* horizontal advance in pixels */ + xadvance = ( slot->metrics.horiAdvance + 32 ) >> 6; + yadvance = ( slot->metrics.vertAdvance + 32 ) >> 6; - /* horizontal advance in pixels */ - xadvance = ( slot->metrics.horiAdvance + 32 ) >> 6; - yadvance = ( slot->metrics.vertAdvance + 32 ) >> 6; + if ( !CHECK_BYTE( bitmap->rows ) || + !CHECK_BYTE( bitmap->width ) || + !CHECK_CHAR( bitmap->pitch ) || + !CHECK_CHAR( slot->bitmap_left ) || + !CHECK_CHAR( slot->bitmap_top ) || + !CHECK_CHAR( xadvance ) || + !CHECK_CHAR( yadvance ) ) + goto BadGlyph; - if ( CHECK_BYTE( bitmap->rows ) && - CHECK_BYTE( bitmap->width ) && - CHECK_CHAR( bitmap->pitch ) && - CHECK_CHAR( slot->bitmap_left ) && - CHECK_CHAR( slot->bitmap_top ) && - CHECK_CHAR( xadvance ) && - CHECK_CHAR( yadvance ) ) - { - sbit->width = (FT_Byte)bitmap->width; - sbit->height = (FT_Byte)bitmap->rows; - sbit->pitch = (FT_Char)bitmap->pitch; - sbit->left = (FT_Char)slot->bitmap_left; - sbit->top = (FT_Char)slot->bitmap_top; - sbit->xadvance = (FT_Char)xadvance; - sbit->yadvance = (FT_Char)yadvance; - sbit->format = (FT_Byte)bitmap->pixel_mode; - sbit->max_grays = (FT_Byte)(bitmap->num_grays - 1); + sbit->width = (FT_Byte)bitmap->width; + sbit->height = (FT_Byte)bitmap->rows; + sbit->pitch = (FT_Char)bitmap->pitch; + sbit->left = (FT_Char)slot->bitmap_left; + sbit->top = (FT_Char)slot->bitmap_top; + sbit->xadvance = (FT_Char)xadvance; + sbit->yadvance = (FT_Char)yadvance; + sbit->format = (FT_Byte)bitmap->pixel_mode; + sbit->max_grays = (FT_Byte)(bitmap->num_grays - 1); -#if 0 /* this doesn't work well with embedded bitmaps !! */ + /* copy the bitmap into a new buffer -- ignore error */ + error = ftc_sbit_copy_bitmap( sbit, bitmap, memory ); - /* grab the bitmap when possible - this is a hack! */ - if ( slot->flags & FT_GLYPH_OWN_BITMAP ) - { - slot->flags &= ~FT_GLYPH_OWN_BITMAP; - sbit->buffer = bitmap->buffer; - } - else -#endif - { - /* copy the bitmap into a new buffer -- ignore error */ - error = ftc_sbit_copy_bitmap( sbit, bitmap, memory ); - } + /* now, compute size */ + if ( asize ) + *asize = FT_ABS( sbit->pitch ) * sbit->height; - /* now, compute size */ - if ( asize ) - *asize = ABS( sbit->pitch ) * sbit->height; + } /* glyph loading successful */ - } /* glyph dimensions ok */ - - } /* glyph loading successful */ - - /* ignore the errors that might have occurred -- */ - /* we mark unloaded glyphs with `sbit.buffer == 0' */ - /* and 'width == 255', 'height == 0' */ - /* */ - if ( error && error != FT_Err_Out_Of_Memory ) - { - sbit->width = 255; - error = 0; - /* sbit->buffer == NULL too! */ - } + /* ignore the errors that might have occurred -- */ + /* we mark unloaded glyphs with `sbit.buffer == 0' */ + /* and `width == 255', `height == 0' */ + /* */ + if ( error && error != FTC_Err_Out_Of_Memory ) + { + BadGlyph: + sbit->width = 255; + sbit->height = 0; + sbit->buffer = NULL; + error = 0; + if ( asize ) + *asize = 0; } return error; } - FT_CALLBACK_DEF( FT_Error ) - ftc_sbit_node_init( FTC_SBitNode snode, - FTC_GlyphQuery gquery, - FTC_Cache cache ) + FT_EXPORT_DEF( FT_Error ) + FTC_SNode_New( FTC_SNode *psnode, + FTC_GQuery gquery, + FTC_Cache cache ) { - FT_Error error; + FT_Memory memory = cache->memory; + FT_Error error; + FTC_SNode snode = NULL; + FT_UInt gindex = gquery->gindex; + FTC_Family family = gquery->family; + + FTC_SFamilyClass clazz = FTC_CACHE__SFAMILY_CLASS( cache ); + FT_UInt total; - ftc_glyph_node_init( FTC_GLYPH_NODE( snode ), - gquery->gindex, - FTC_GLYPH_FAMILY( gquery->query.family ) ); + total = clazz->family_get_count( family, cache->manager ); + if ( total == 0 || gindex >= total ) + { + error = FT_Err_Invalid_Argument; + goto Exit; + } - error = ftc_sbit_node_load( snode, - cache->manager, - FTC_SBIT_FAMILY( FTC_QUERY( gquery )->family ), - gquery->gindex, - NULL ); - if ( error ) - ftc_glyph_node_done( FTC_GLYPH_NODE( snode ), cache ); + if ( !FT_NEW( snode ) ) + { + FT_UInt count, start; + + start = gindex - ( gindex % FTC_SBIT_ITEMS_PER_NODE ); + count = total - start; + if ( count > FTC_SBIT_ITEMS_PER_NODE ) + count = FTC_SBIT_ITEMS_PER_NODE; + + FTC_GNode_Init( FTC_GNODE( snode ), start, family ); + + snode->count = count; + + error = ftc_snode_load( snode, + cache->manager, + gindex, + NULL ); + if ( error ) + { + FTC_SNode_Free( snode, cache ); + snode = NULL; + } + } + + Exit: + *psnode = snode; return error; } - FT_CALLBACK_DEF( FT_ULong ) - ftc_sbit_node_weight( FTC_SBitNode snode ) + FT_LOCAL_DEF( FT_Error ) + ftc_snode_new( FTC_SNode *psnode, + FTC_GQuery gquery, + FTC_Cache cache ) { - FTC_GlyphNode gnode = FTC_GLYPH_NODE( snode ); - FT_UInt count = gnode->item_count; - FTC_SBit sbit = snode->sbits; - FT_Int pitch; - FT_ULong size; + return FTC_SNode_New( psnode, gquery, cache ); + } + FT_EXPORT_DEF( FT_ULong ) + FTC_SNode_Weight( FTC_SNode snode ) + { + FT_UInt count = snode->count; + FTC_SBit sbit = snode->sbits; + FT_Int pitch; + FT_ULong size; + + + FT_ASSERT( snode->count <= FTC_SBIT_ITEMS_PER_NODE ); + /* the node itself */ size = sizeof ( *snode ); - /* the sbit records */ - size += FTC_GLYPH_NODE( snode )->item_count * sizeof ( FTC_SBitRec ); - for ( ; count > 0; count--, sbit++ ) { if ( sbit->buffer ) @@ -285,22 +279,29 @@ } - FT_CALLBACK_DEF( FT_Bool ) - ftc_sbit_node_compare( FTC_SBitNode snode, - FTC_SBitQuery squery, - FTC_Cache cache ) + FT_LOCAL_DEF( FT_ULong ) + ftc_snode_weight( FTC_SNode snode ) { - FTC_GlyphQuery gquery = FTC_GLYPH_QUERY( squery ); - FTC_GlyphNode gnode = FTC_GLYPH_NODE( snode ); - FT_Bool result; + return FTC_SNode_Weight( snode ); + } - result = ftc_glyph_node_compare( gnode, gquery ); + FT_EXPORT_DEF( FT_Bool ) + FTC_SNode_Compare( FTC_SNode snode, + FTC_GQuery gquery, + FTC_Cache cache ) + { + FTC_GNode gnode = FTC_GNODE( snode ); + FT_UInt gindex = gquery->gindex; + FT_Bool result; + + + result = FT_BOOL( gnode->family == gquery->family && + (FT_UInt)( gindex - gnode->gindex ) < snode->count ); if ( result ) { /* check if we need to load the glyph bitmap now */ - FT_UInt gindex = gquery->gindex; - FTC_SBit sbit = snode->sbits + ( gindex - gnode->item_start ); + FTC_SBit sbit = snode->sbits + ( gindex - gnode->gindex ); if ( sbit->buffer == NULL && sbit->width != 255 ) @@ -308,14 +309,11 @@ FT_ULong size; - /* yes, it's safe to ignore errors here */ - ftc_sbit_node_load( snode, - cache->manager, - FTC_SBIT_FAMILY( FTC_QUERY( squery )->family ), - gindex, - &size ); - - cache->manager->cur_weight += size; + if ( !ftc_snode_load( snode, cache->manager, + gindex, &size ) ) + { + cache->manager->cur_weight += size; + } } } @@ -323,235 +321,13 @@ } - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** SBITS FAMILIES *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - FT_CALLBACK_DEF( FT_Error ) - ftc_sbit_family_init( FTC_SBitFamily sfam, - FTC_SBitQuery squery, - FTC_Cache cache ) + FT_LOCAL_DEF( FT_Bool ) + ftc_snode_compare( FTC_SNode snode, + FTC_GQuery gquery, + FTC_Cache cache ) { - FTC_Manager manager = cache->manager; - FT_Error error; - FT_Face face; - - - sfam->type = squery->type; - - /* we need to compute "cquery.item_total" now */ - error = FTC_Manager_Lookup_Face( manager, - squery->type.font.face_id, - &face ); - if ( !error ) - { - error = ftc_glyph_family_init( FTC_GLYPH_FAMILY( sfam ), - FTC_IMAGE_TYPE_HASH( &sfam->type ), - FTC_SBIT_ITEMS_PER_NODE, - face->num_glyphs, - FTC_GLYPH_QUERY( squery ), - cache ); - } - - return error; + return FTC_SNode_Compare( snode, gquery, cache ); } - FT_CALLBACK_DEF( FT_Bool ) - ftc_sbit_family_compare( FTC_SBitFamily sfam, - FTC_SBitQuery squery ) - { - FT_Bool result; - - - /* we need to set the "cquery.cset" field or our query for */ - /* faster glyph comparisons in ftc_sbit_node_compare */ - /* */ - result = FT_BOOL( FTC_IMAGE_TYPE_COMPARE( &sfam->type, &squery->type ) ); - if ( result ) - FTC_GLYPH_FAMILY_FOUND( sfam, squery ); - - return result; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** SBITS CACHE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - FT_CALLBACK_TABLE_DEF - const FTC_Cache_ClassRec ftc_sbit_cache_class = - { - sizeof ( FTC_CacheRec ), - (FTC_Cache_InitFunc) ftc_cache_init, - (FTC_Cache_ClearFunc)ftc_cache_clear, - (FTC_Cache_DoneFunc) ftc_cache_done, - - sizeof ( FTC_SBitFamilyRec ), - (FTC_Family_InitFunc) ftc_sbit_family_init, - (FTC_Family_CompareFunc)ftc_sbit_family_compare, - (FTC_Family_DoneFunc) ftc_glyph_family_done, - - sizeof ( FTC_SBitNodeRec ), - (FTC_Node_InitFunc) ftc_sbit_node_init, - (FTC_Node_WeightFunc) ftc_sbit_node_weight, - (FTC_Node_CompareFunc)ftc_sbit_node_compare, - (FTC_Node_DoneFunc) ftc_sbit_node_done - }; - - - /* documentation is in ftcsbits.h */ - - FT_EXPORT_DEF( FT_Error ) - FTC_SBitCache_New( FTC_Manager manager, - FTC_SBitCache *acache ) - { - return FTC_Manager_Register_Cache( manager, - &ftc_sbit_cache_class, - (FTC_Cache*)acache ); - } - - - /* documentation is in ftcsbits.h */ - -#ifdef FTC_CACHE_USE_INLINE - -#define GEN_CACHE_FAMILY_COMPARE( f, q, c ) \ - ftc_sbit_family_compare( (FTC_SBitFamily)(f), (FTC_SBitQuery)(q) ) - -#define GEN_CACHE_NODE_COMPARE( n, q, c ) \ - ftc_sbit_node_compare( (FTC_SBitNode)(n), (FTC_SBitQuery)(q), c ) - -#define GEN_CACHE_LOOKUP ftc_sbit_cache_lookup -#include "ftccache.i" - -#else /* !FTC_CACHE_USE_INLINE */ - -#define ftc_sbit_cache_lookup ftc_cache_lookup - -#endif /* !FTC_CACHE_USE_INLINE */ - - FT_EXPORT_DEF( FT_Error ) - FTC_SBitCache_Lookup( FTC_SBitCache cache, - FTC_ImageType type, - FT_UInt gindex, - FTC_SBit *ansbit, - FTC_Node *anode ) - { - FT_Error error; - FTC_SBitQueryRec squery; - FTC_SBitNode node; - - - /* other argument checks delayed to ftc_cache_lookup */ - if ( !ansbit ) - return FTC_Err_Invalid_Argument; - - *ansbit = NULL; - - if ( anode ) - *anode = NULL; - - squery.gquery.gindex = gindex; - squery.type = *type; - - error = ftc_sbit_cache_lookup( FTC_CACHE( cache ), - FTC_QUERY( &squery ), - (FTC_Node*)&node ); - if ( !error ) - { - *ansbit = node->sbits + ( gindex - FTC_GLYPH_NODE( node )->item_start ); - - if ( anode ) - { - *anode = FTC_NODE( node ); - FTC_NODE( node )->ref_count++; - } - } - return error; - } - - - /* backwards-compatibility functions */ - - FT_EXPORT_DEF( FT_Error ) - FTC_SBit_Cache_New( FTC_Manager manager, - FTC_SBit_Cache *acache ) - { - return FTC_SBitCache_New( manager, (FTC_SBitCache*)acache ); - } - - - FT_EXPORT_DEF( FT_Error ) - FTC_SBit_Cache_Lookup( FTC_SBit_Cache cache, - FTC_Image_Desc* desc, - FT_UInt gindex, - FTC_SBit *ansbit ) - { - FTC_ImageTypeRec type0; - - - if ( !desc ) - return FTC_Err_Invalid_Argument; - - type0.font = desc->font; - type0.flags = 0; - - /* convert image type flags to load flags */ - { - FT_UInt load_flags = FT_LOAD_DEFAULT; - FT_UInt type = desc->image_type; - - - /* determine load flags, depending on the font description's */ - /* image type */ - - if ( ftc_image_format( type ) == ftc_image_format_bitmap ) - { - if ( type & ftc_image_flag_monochrome ) - load_flags |= FT_LOAD_MONOCHROME; - - /* disable embedded bitmaps loading if necessary */ - if ( type & ftc_image_flag_no_sbits ) - load_flags |= FT_LOAD_NO_BITMAP; - } - else - { - /* we want an outline, don't load embedded bitmaps */ - load_flags |= FT_LOAD_NO_BITMAP; - - if ( type & ftc_image_flag_unscaled ) - load_flags |= FT_LOAD_NO_SCALE; - } - - /* always render glyphs to bitmaps */ - load_flags |= FT_LOAD_RENDER; - - if ( type & ftc_image_flag_unhinted ) - load_flags |= FT_LOAD_NO_HINTING; - - if ( type & ftc_image_flag_autohinted ) - load_flags |= FT_LOAD_FORCE_AUTOHINT; - - type0.flags = load_flags; - } - - return FTC_SBitCache_Lookup( (FTC_SBitCache)cache, - &type0, - gindex, - ansbit, - NULL ); - } - - -/* END */ +/* END */ diff --git a/src/libs/freetype2/cache/ftlru.c b/src/libs/freetype2/cache/ftlru.c deleted file mode 100644 index feb38ea790..0000000000 --- a/src/libs/freetype2/cache/ftlru.c +++ /dev/null @@ -1,394 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftlru.c */ -/* */ -/* Simple LRU list-cache (body). */ -/* */ -/* Copyright 2000-2001, 2002 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. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_CACHE_H -#include FT_CACHE_INTERNAL_LRU_H -#include FT_LIST_H -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_DEBUG_H - -#include "ftcerror.h" - - - FT_EXPORT_DEF( FT_Error ) - FT_LruList_New( FT_LruList_Class clazz, - FT_UInt max_nodes, - FT_Pointer user_data, - FT_Memory memory, - FT_LruList *alist ) - { - FT_Error error; - FT_LruList list; - - - if ( !alist || !clazz ) - return FTC_Err_Invalid_Argument; - - *alist = NULL; - if ( !FT_ALLOC( list, clazz->list_size ) ) - { - /* initialize common fields */ - list->clazz = clazz; - list->memory = memory; - list->max_nodes = max_nodes; - list->data = user_data; - - if ( clazz->list_init ) - { - error = clazz->list_init( list ); - if ( error ) - { - if ( clazz->list_done ) - clazz->list_done( list ); - - FT_FREE( list ); - } - } - - *alist = list; - } - - return error; - } - - - FT_EXPORT_DEF( void ) - FT_LruList_Destroy( FT_LruList list ) - { - FT_Memory memory; - FT_LruList_Class clazz; - - - if ( !list ) - return; - - memory = list->memory; - clazz = list->clazz; - - FT_LruList_Reset( list ); - - if ( clazz->list_done ) - clazz->list_done( list ); - - FT_FREE( list ); - } - - - FT_EXPORT_DEF( void ) - FT_LruList_Reset( FT_LruList list ) - { - FT_LruNode node; - FT_LruList_Class clazz; - FT_Memory memory; - - - if ( !list ) - return; - - node = list->nodes; - clazz = list->clazz; - memory = list->memory; - - while ( node ) - { - FT_LruNode next = node->next; - - - if ( clazz->node_done ) - clazz->node_done( node, list->data ); - - FT_FREE( node ); - node = next; - } - - list->nodes = NULL; - list->num_nodes = 0; - } - - - FT_EXPORT_DEF( FT_Error ) - FT_LruList_Lookup( FT_LruList list, - FT_LruKey key, - FT_LruNode *anode ) - { - FT_Error error = 0; - FT_LruNode node, *pnode; - FT_LruList_Class clazz; - FT_LruNode* plast; - FT_LruNode result = NULL; - FT_Memory memory; - - - if ( !list || !key || !anode ) - return FTC_Err_Invalid_Argument; - - pnode = &list->nodes; - plast = pnode; - node = NULL; - clazz = list->clazz; - memory = list->memory; - - if ( clazz->node_compare ) - { - for (;;) - { - node = *pnode; - if ( node == NULL ) - break; - - if ( clazz->node_compare( node, key, list->data ) ) - break; - - plast = pnode; - pnode = &(*pnode)->next; - } - } - else - { - for (;;) - { - node = *pnode; - if ( node == NULL ) - break; - - if ( node->key == key ) - break; - - plast = pnode; - pnode = &(*pnode)->next; - } - } - - if ( node ) - { - /* move element to top of list */ - if ( list->nodes != node ) - { - *pnode = node->next; - node->next = list->nodes; - list->nodes = node; - } - result = node; - goto Exit; - } - - /* since we haven't found the relevant element in our LRU list, - * we're going to "create" a new one. - * - * the following code is a bit special, because it tries to handle - * out-of-memory conditions (OOM) in an intelligent way. - * - * more precisely, if not enough memory is available to create a - * new node or "flush" an old one, we need to remove the oldest - * elements from our list, and try again. since several tries may - * be necessary, a loop is needed - * - * this loop will only exit when: - * - * - a new node was succesfully created, or an old node flushed - * - an error other than FT_Err_Out_Of_Memory is detected - * - the list of nodes is empty, and it isn't possible to create - * new nodes - * - * on each unsucesful attempt, one node will be removed from the list - * - */ - - { - FT_Int drop_last = ( list->max_nodes > 0 && - list->num_nodes >= list->max_nodes ); - - for (;;) - { - node = NULL; - - /* when "drop_last" is true, we should free the last node in - * the list to make room for a new one. note that we re-use - * its memory block to save allocation calls. - */ - if ( drop_last ) - { - /* find the last node in the list - */ - pnode = &list->nodes; - node = *pnode; - - if ( node == NULL ) - { - FT_ASSERT( list->nodes == 0 ); - error = FT_Err_Out_Of_Memory; - goto Exit; - } - - FT_ASSERT( list->num_nodes > 0 ); - - while ( node->next ) - { - pnode = &node->next; - node = *pnode; - } - - /* remove it from the list, and try to "flush" it. doing this will - * save a significant number of dynamic allocations compared to - * a classic destroy/create cycle - */ - *pnode = NULL; - list->num_nodes -= 1; - - if ( clazz->node_flush ) - { - error = clazz->node_flush( node, key, list->data ); - if ( !error ) - goto Success; - - /* note that if an error occured during the flush, we need to - * finalize it since it is potentially in incomplete state. - */ - } - - /* we finalize, but do not destroy the last node, we - * simply re-use its memory block ! - */ - if ( clazz->node_done ) - clazz->node_done( node, list->data ); - - FT_MEM_ZERO( node, clazz->node_size ); - } - else - { - /* try to allocate a new node when "drop_last" is not TRUE - * this usually happens on the first pass, when the LRU list - * is not already full. - */ - if ( FT_ALLOC( node, clazz->node_size ) ) - goto Fail; - } - - FT_ASSERT( node != NULL ); - - node->key = key; - error = clazz->node_init( node, key, list->data ); - if ( error ) - { - if ( clazz->node_done ) - clazz->node_done( node, list->data ); - - FT_FREE( node ); - goto Fail; - } - - Success: - result = node; - - node->next = list->nodes; - list->nodes = node; - list->num_nodes++; - goto Exit; - - Fail: - if ( error != FT_Err_Out_Of_Memory ) - goto Exit; - - drop_last = 1; - continue; - } - } - - Exit: - *anode = result; - return error; - } - - - - FT_EXPORT_DEF( void ) - FT_LruList_Remove( FT_LruList list, - FT_LruNode node ) - { - FT_LruNode *pnode; - - - if ( !list || !node ) - return; - - pnode = &list->nodes; - for (;;) - { - if ( *pnode == node ) - { - FT_Memory memory = list->memory; - FT_LruList_Class clazz = list->clazz; - - - *pnode = node->next; - node->next = NULL; - - if ( clazz->node_done ) - clazz->node_done( node, list->data ); - - FT_FREE( node ); - list->num_nodes--; - break; - } - - pnode = &(*pnode)->next; - } - } - - - FT_EXPORT_DEF( void ) - FT_LruList_Remove_Selection( FT_LruList list, - FT_LruNode_SelectFunc select_func, - FT_Pointer select_data ) - { - FT_LruNode *pnode, node; - FT_LruList_Class clazz; - FT_Memory memory; - - - if ( !list || !select_func ) - return; - - memory = list->memory; - clazz = list->clazz; - pnode = &list->nodes; - - for (;;) - { - node = *pnode; - if ( node == NULL ) - break; - - if ( select_func( node, select_data, list->data ) ) - { - *pnode = node->next; - node->next = NULL; - - if ( clazz->node_done ) - clazz->node_done( node, list ); - - FT_FREE( node ); - } - else - pnode = &(*pnode)->next; - } - } - - -/* END */ diff --git a/src/libs/freetype2/cache/rules.mk b/src/libs/freetype2/cache/rules.mk index 41e5e2b2d3..381104ad65 100644 --- a/src/libs/freetype2/cache/rules.mk +++ b/src/libs/freetype2/cache/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2000, 2001 by +# Copyright 2000, 2001, 2003, 2004 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -15,66 +15,66 @@ # Cache driver directory # -CACHE_DIR := $(SRC_)cache -CACHE_DIR_ := $(CACHE_DIR)$(SEP) - -CACHE_H_DIR := $(PUBLIC_)cache -CACHE_H_DIR_ := $(CACHE_H_DIR)$(SEP) +CACHE_DIR := $(SRC_DIR)/cache +CACHE_H_DIR := $(PUBLIC_DIR)/cache # compilation flags for the driver # -Cache_COMPILE := $(FT_COMPILE) $I$(CACHE_DIR) +CACHE_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(CACHE_DIR)) # Cache driver sources (i.e., C files) # -Cache_DRV_SRC := $(CACHE_DIR_)ftlru.c \ - $(CACHE_DIR_)ftcmanag.c \ - $(CACHE_DIR_)ftccache.c \ - $(CACHE_DIR_)ftcglyph.c \ - $(CACHE_DIR_)ftcsbits.c \ - $(CACHE_DIR_)ftcimage.c \ - $(CACHE_DIR_)ftccmap.c +CACHE_DRV_SRC := $(CACHE_DIR)/ftcmru.c \ + $(CACHE_DIR)/ftcmanag.c \ + $(CACHE_DIR)/ftcbasic.c \ + $(CACHE_DIR)/ftccache.c \ + $(CACHE_DIR)/ftcglyph.c \ + $(CACHE_DIR)/ftcsbits.c \ + $(CACHE_DIR)/ftcimage.c \ + $(CACHE_DIR)/ftccmap.c # Cache driver headers # -Cache_DRV_H := $(CACHE_H_DIR_)ftlru.h \ - $(CACHE_H_DIR_)ftcmanag.h \ - $(CACHE_H_DIR_)ftcglyph.h \ - $(CACHE_H_DIR_)ftcimage.h \ - $(CACHE_DIR_)ftcerror.h +CACHE_DRV_H := $(CACHE_H_DIR)/ftcmru.h \ + $(CACHE_H_DIR)/ftcmanag.h \ + $(CACHE_H_DIR)/ftcglyph.h \ + $(CACHE_H_DIR)/ftcimage.h \ + $(CACHE_H_DIR)/ftccmap.h \ + $(CACHE_DIR)/ftcerror.h \ + $(CACHE_DIR)/ftccback.h # Cache driver object(s) # -# Cache_DRV_OBJ_M is used during `multi' builds. -# Cache_DRV_OBJ_S is used during `single' builds. +# CACHE_DRV_OBJ_M is used during `multi' builds. +# CACHE_DRV_OBJ_S is used during `single' builds. # -Cache_DRV_OBJ_M := $(Cache_DRV_SRC:$(CACHE_DIR_)%.c=$(OBJ_)%.$O) -Cache_DRV_OBJ_S := $(OBJ_)ftcache.$O +CACHE_DRV_OBJ_M := $(CACHE_DRV_SRC:$(CACHE_DIR)/%.c=$(OBJ_DIR)/%.$O) +CACHE_DRV_OBJ_S := $(OBJ_DIR)/ftcache.$O # Cache driver source file for single build # -Cache_DRV_SRC_S := $(CACHE_DIR_)ftcache.c +CACHE_DRV_SRC_S := $(CACHE_DIR)/ftcache.c # Cache driver - single object # -$(Cache_DRV_OBJ_S): $(Cache_DRV_SRC_S) $(Cache_DRV_SRC) \ - $(FREETYPE_H) $(Cache_DRV_H) - $(Cache_COMPILE) $T$@ $(Cache_DRV_SRC_S) +$(CACHE_DRV_OBJ_S): $(CACHE_DRV_SRC_S) $(CACHE_DRV_SRC) \ + $(FREETYPE_H) $(CACHE_DRV_H) + $(CACHE_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(CACHE_DRV_SRC_S)) # Cache driver - multiple objects # -$(OBJ_)%.$O: $(CACHE_DIR_)%.c $(FREETYPE_H) $(Cache_DRV_H) - $(Cache_COMPILE) $T$@ $< +$(OBJ_DIR)/%.$O: $(CACHE_DIR)/%.c $(FREETYPE_H) $(CACHE_DRV_H) + $(CACHE_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) # update main driver object lists # -DRV_OBJS_S += $(Cache_DRV_OBJ_S) -DRV_OBJS_M += $(Cache_DRV_OBJ_M) +DRV_OBJS_S += $(CACHE_DRV_OBJ_S) +DRV_OBJS_M += $(CACHE_DRV_OBJ_M) -# EOF +# EOF diff --git a/src/libs/freetype2/cff/cff.c b/src/libs/freetype2/cff/cff.c index 590af6b03b..e6d8954c9a 100644 --- a/src/libs/freetype2/cff/cff.c +++ b/src/libs/freetype2/cff/cff.c @@ -4,7 +4,7 @@ /* */ /* FreeType OpenType driver component (body only). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2001, 2002 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -26,4 +26,4 @@ #include "cffgload.c" #include "cffcmap.c" -/* END */ +/* END */ diff --git a/src/libs/freetype2/cff/cffcmap.c b/src/libs/freetype2/cff/cffcmap.c index 5c0d8f7e2c..82e04d2366 100644 --- a/src/libs/freetype2/cff/cffcmap.c +++ b/src/libs/freetype2/cff/cffcmap.c @@ -4,7 +4,7 @@ /* */ /* CFF character mapping table (cmap) support (body). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,6 +19,8 @@ #include "cffcmap.h" #include "cffload.h" +#include "cfferrs.h" + /*************************************************************************/ /*************************************************************************/ @@ -36,9 +38,8 @@ CFF_Encoding encoding = &cff->encoding; - cmap->count = encoding->count; cmap->gids = encoding->codes; - + return 0; } @@ -46,7 +47,6 @@ FT_CALLBACK_DEF( void ) cff_cmap_encoding_done( CFF_CMapStd cmap ) { - cmap->count = 0; cmap->gids = NULL; } @@ -58,9 +58,9 @@ FT_UInt result = 0; - if ( char_code < cmap->count ) + if ( char_code < 256 ) result = cmap->gids[char_code]; - + return result; } @@ -71,27 +71,27 @@ { FT_UInt result = 0; FT_UInt32 char_code = *pchar_code; - + *pchar_code = 0; - if ( char_code < cmap->count ) + if ( char_code < 255 ) { FT_UInt code = (FT_UInt)(char_code + 1); - + for (;;) { - if ( code >= cmap->count ) + if ( code >= 256 ) break; - + result = cmap->gids[code]; if ( result != 0 ) { *pchar_code = code; break; } - + code++; } } @@ -125,34 +125,34 @@ { FT_UInt32 u1 = ((CFF_CMapUniPair)pair1)->unicode; FT_UInt32 u2 = ((CFF_CMapUniPair)pair2)->unicode; - + if ( u1 < u2 ) return -1; - + if ( u1 > u2 ) return +1; - + return 0; - } + } FT_CALLBACK_DEF( FT_Error ) cff_cmap_unicode_init( CFF_CMapUnicode cmap ) { - FT_Error error; - FT_UInt count; - TT_Face face = (TT_Face)FT_CMAP_FACE( cmap ); - FT_Memory memory = FT_FACE_MEMORY( face ); - CFF_Font cff = (CFF_Font)face->extra.data; - CFF_Charset charset = &cff->charset; - PSNames_Service psnames = (PSNames_Service)cff->psnames; + FT_Error error; + FT_UInt count; + TT_Face face = (TT_Face)FT_CMAP_FACE( cmap ); + FT_Memory memory = FT_FACE_MEMORY( face ); + CFF_Font cff = (CFF_Font)face->extra.data; + CFF_Charset charset = &cff->charset; + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; cmap->num_pairs = 0; cmap->pairs = NULL; - count = (FT_UInt)face->root.num_glyphs; + count = cff->num_glyphs; if ( !FT_NEW_ARRAY( cmap->pairs, count ) ) { @@ -164,12 +164,12 @@ pair = cmap->pairs; for ( n = 0; n < count; n++ ) { - FT_UInt sid = charset->sids[n]; + FT_UInt sid = charset->sids[n]; const char* gname; gname = cff_index_get_sid_string( &cff->string_index, sid, psnames ); - + /* build unsorted pair table by matching glyph names */ if ( gname ) { @@ -181,7 +181,7 @@ pair->gindex = n; pair++; } - + FT_FREE( gname ); } } @@ -191,7 +191,7 @@ { /* there are no unicode characters in here! */ FT_FREE( cmap->pairs ); - error = FT_Err_Invalid_Argument; + error = CFF_Err_Invalid_Argument; } else { @@ -200,7 +200,7 @@ if ( new_count != count && new_count < count / 2 ) { (void)FT_RENEW_ARRAY( cmap->pairs, count, new_count ); - error = 0; + error = CFF_Err_Ok; } /* sort the pairs table to allow efficient binary searches */ @@ -223,7 +223,7 @@ FT_Face face = FT_CMAP_FACE( cmap ); FT_Memory memory = FT_FACE_MEMORY( face ); - + FT_FREE( cmap->pairs ); cmap->num_pairs = 0; } @@ -323,4 +323,4 @@ }; -/* END */ +/* END */ diff --git a/src/libs/freetype2/cff/cffcmap.h b/src/libs/freetype2/cff/cffcmap.h index e03b81454e..ceb32cd3c3 100644 --- a/src/libs/freetype2/cff/cffcmap.h +++ b/src/libs/freetype2/cff/cffcmap.h @@ -4,7 +4,7 @@ /* */ /* CFF character mapping table (cmap) support (specification). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -38,7 +38,6 @@ FT_BEGIN_HEADER typedef struct CFF_CMapStdRec_ { FT_CMapRec cmap; - FT_UInt count; FT_UShort* gids; /* up to 256 elements */ } CFF_CMapStdRec; @@ -85,4 +84,4 @@ FT_END_HEADER #endif /* __CFFCMAP_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/cff/cffdrivr.c b/src/libs/freetype2/cff/cffdrivr.c index 2ca6a873f6..60ee90ae3d 100644 --- a/src/libs/freetype2/cff/cffdrivr.c +++ b/src/libs/freetype2/cff/cffdrivr.c @@ -4,7 +4,7 @@ /* */ /* OpenType font driver implementation (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,14 +22,19 @@ #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_SFNT_H #include FT_TRUETYPE_IDS_H -#include FT_INTERNAL_POSTSCRIPT_NAMES_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H +#include FT_SERVICE_POSTSCRIPT_INFO_H +#include FT_SERVICE_TT_CMAP_H #include "cffdrivr.h" #include "cffgload.h" #include "cffload.h" +#include "cffcmap.h" #include "cfferrs.h" +#include FT_SERVICE_XFREE86_NAME_H +#include FT_SERVICE_GLYPH_DICT_H /*************************************************************************/ /* */ @@ -165,7 +170,7 @@ /* glyph_index :: The index of the glyph in the font file. */ /* */ /* load_flags :: A flag indicating what to load for this glyph. The */ - /* FTLOAD_??? constants can be used to control the */ + /* FT_LOAD_??? constants can be used to control the */ /* glyph loading process (e.g., whether the outline */ /* should be scaled, whether to load bitmaps or not, */ /* whether to hint the outline, etc). */ @@ -196,7 +201,7 @@ if ( size ) { /* these two object must have the same parent */ - if ( size->face != slot->root.face ) + if ( size->root.face != slot->root.face ) return CFF_Err_Invalid_Face_Handle; } @@ -210,17 +215,10 @@ } - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** C H A R A C T E R M A P P I N G S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ + /* + * GLYPH DICT SERVICE + * + */ static FT_Error cff_get_glyph_name( CFF_Face face, @@ -228,21 +226,19 @@ FT_Pointer buffer, FT_UInt buffer_max ) { - CFF_Font font = (CFF_Font)face->extra.data; - FT_Memory memory = FT_FACE_MEMORY( face ); - FT_String* gname; - FT_UShort sid; - PSNames_Service psnames; - FT_Error error; + CFF_Font font = (CFF_Font)face->extra.data; + FT_Memory memory = FT_FACE_MEMORY( face ); + FT_String* gname; + FT_UShort sid; + FT_Service_PsCMaps psnames; + FT_Error error; - psnames = (PSNames_Service)FT_Get_Module_Interface( - face->root.driver->root.library, "psnames" ); - + FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); if ( !psnames ) { FT_ERROR(( "cff_get_glyph_name:" )); - FT_ERROR(( " cannot open CFF & CEF fonts\n" )); + FT_ERROR(( " cannot get glyph name from CFF & CEF fonts\n" )); FT_ERROR(( " " )); FT_ERROR(( " without the `PSNames' module\n" )); error = CFF_Err_Unknown_File_Format; @@ -255,7 +251,7 @@ /* now, lookup the name itself */ gname = cff_index_get_sid_string( &font->string_index, sid, psnames ); - if ( buffer_max > 0 ) + if ( gname && buffer_max > 0 ) { FT_UInt len = (FT_UInt)ft_strlen( gname ); @@ -267,7 +263,7 @@ ((FT_Byte*)buffer)[len] = 0; } - FT_FREE ( gname ); + FT_FREE( gname ); error = CFF_Err_Ok; Exit: @@ -275,43 +271,26 @@ } - - /*************************************************************************/ - /* */ - /* <Function> */ - /* cff_get_name_index */ - /* */ - /* <Description> */ - /* Uses the psnames module and the CFF font's charset to to return a */ - /* a given glyph name's glyph index. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face object. */ - /* */ - /* glyph_name :: The glyph name. */ - /* */ - /* <Return> */ - /* Glyph index. 0 means `undefined character code'. */ - /* */ static FT_UInt cff_get_name_index( CFF_Face face, FT_String* glyph_name ) { - CFF_Font cff; - CFF_Charset charset; - PSNames_Service psnames; - FT_Memory memory = FT_FACE_MEMORY( face ); - FT_String* name; - FT_UShort sid; - FT_UInt i; - FT_Int result; + CFF_Font cff; + CFF_Charset charset; + FT_Service_PsCMaps psnames; + FT_Memory memory = FT_FACE_MEMORY( face ); + FT_String* name; + FT_UShort sid; + FT_UInt i; + FT_Int result; cff = (CFF_FontRec *)face->extra.data; charset = &cff->charset; - psnames = (PSNames_Service)FT_Get_Module_Interface( - face->root.driver->root.library, "psnames" ); + FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); + if ( !psnames ) + return 0; for ( i = 0; i < cff->num_glyphs; i++ ) { @@ -335,6 +314,77 @@ } + static const FT_Service_GlyphDictRec cff_service_glyph_dict = + { + (FT_GlyphDict_GetNameFunc) cff_get_glyph_name, + (FT_GlyphDict_NameIndexFunc)cff_get_name_index, + }; + + + /* + * POSTSCRIPT INFO SERVICE + * + */ + + static FT_Int + cff_ps_has_glyph_names( FT_Face face ) + { + return ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) > 0; + } + + + static const FT_Service_PsInfoRec cff_service_ps_info = + { + (PS_GetFontInfoFunc) NULL, /* unsupported with CFF fonts */ + (PS_HasGlyphNamesFunc)cff_ps_has_glyph_names + }; + + + /* + * TT CMAP INFO + * + * If the charmap is a synthetic Unicode encoding cmap or + * a Type 1 standard (or expert) encoding cmap, hide TT CMAP INFO + * service defined in SFNT module. + * + * Otherwise call the service function in the sfnt module. + * + */ + static FT_Error + cff_get_cmap_info( FT_CharMap charmap, + TT_CMapInfo *cmap_info ) + { + FT_CMap cmap = FT_CMAP( charmap ); + FT_Error error = CFF_Err_Ok; + + + cmap_info->language = 0; + + if ( cmap->clazz != &cff_cmap_encoding_class_rec && + cmap->clazz != &cff_cmap_unicode_class_rec ) + { + FT_Face face = FT_CMAP_FACE( cmap ); + FT_Library library = FT_FACE_LIBRARY( face ); + FT_Module sfnt = FT_Get_Module( library, "sfnt" ); + FT_Service_TTCMaps service = + (FT_Service_TTCMaps)ft_module_get_service( sfnt, + FT_SERVICE_ID_TT_CMAP ); + + + if ( service && service->get_cmap_info ) + error = service->get_cmap_info( charmap, cmap_info ); + } + + return error; + } + + + static const FT_Service_TTCMapsRec cff_service_get_cmap_info = + { + (TT_CMap_Info_GetFunc)cff_get_cmap_info + }; + + /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ @@ -347,24 +397,31 @@ /*************************************************************************/ /*************************************************************************/ + static const FT_ServiceDescRec cff_services[] = + { + { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF }, + { FT_SERVICE_ID_POSTSCRIPT_INFO, &cff_service_ps_info }, +#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES + { FT_SERVICE_ID_GLYPH_DICT, &cff_service_glyph_dict }, +#endif + { FT_SERVICE_ID_TT_CMAP, &cff_service_get_cmap_info }, + { NULL, NULL } + }; + + static FT_Module_Interface cff_get_interface( CFF_Driver driver, const char* module_interface ) { - FT_Module sfnt; + FT_Module sfnt; + FT_Module_Interface result; -#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES + result = ft_service_list_lookup( cff_services, module_interface ); + if ( result != NULL ) + return result; - if ( ft_strcmp( (const char*)module_interface, "glyph_name" ) == 0 ) - return (FT_Module_Interface)cff_get_glyph_name; - - if ( ft_strcmp( (const char*)module_interface, "name_index" ) == 0 ) - return (FT_Module_Interface)cff_get_name_index; - -#endif - - /* we simply pass our request to the `sfnt' module */ + /* we pass our request to the `sfnt' module */ sfnt = FT_Get_Module( driver->root.root.library, "sfnt" ); return sfnt ? sfnt->clazz->get_interface( sfnt, module_interface ) : 0; @@ -378,9 +435,9 @@ { /* begin with the FT_Module_Class fields */ { - ft_module_font_driver | - ft_module_driver_scalable | - ft_module_driver_has_hinter, + FT_MODULE_FONT_DRIVER | + FT_MODULE_DRIVER_SCALABLE | + FT_MODULE_DRIVER_HAS_HINTER, sizeof( CFF_DriverRec ), "cff", @@ -396,7 +453,7 @@ /* now the specific driver fields */ sizeof( TT_FaceRec ), - sizeof( FT_SizeRec ), + sizeof( CFF_SizeRec ), sizeof( CFF_GlyphSlotRec ), (FT_Face_InitFunc) cff_face_init, @@ -417,4 +474,4 @@ }; -/* END */ +/* END */ diff --git a/src/libs/freetype2/cff/cffdrivr.h b/src/libs/freetype2/cff/cffdrivr.h index f5c19d1cf8..553848c0a9 100644 --- a/src/libs/freetype2/cff/cffdrivr.h +++ b/src/libs/freetype2/cff/cffdrivr.h @@ -36,4 +36,4 @@ FT_END_HEADER #endif /* __CFFDRIVER_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/cff/cfferrs.h b/src/libs/freetype2/cff/cfferrs.h index a0c38f641a..1b2a5c95c8 100644 --- a/src/libs/freetype2/cff/cfferrs.h +++ b/src/libs/freetype2/cff/cfferrs.h @@ -38,4 +38,4 @@ #endif /* __CFFERRS_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/cff/cffgload.c b/src/libs/freetype2/cff/cffgload.c index a5a94e6d8f..c1339d82eb 100644 --- a/src/libs/freetype2/cff/cffgload.c +++ b/src/libs/freetype2/cff/cffgload.c @@ -4,7 +4,7 @@ /* */ /* OpenType Glyph Loader (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -246,21 +246,20 @@ builder->current = &loader->current.outline; FT_GlyphLoader_Rewind( loader ); - builder->hint_flags = FT_FACE(face)->internal->hint_flags; builder->hints_globals = 0; builder->hints_funcs = 0; if ( hinting && size ) { - builder->hints_globals = size->internal; + builder->hints_globals = size->root.internal; builder->hints_funcs = glyph->root.internal->glyph_hints; } } if ( size ) { - builder->scale_x = size->metrics.x_scale; - builder->scale_y = size->metrics.y_scale; + builder->scale_x = size->root.metrics.x_scale; + builder->scale_y = size->root.metrics.y_scale; } builder->pos_x = 0; @@ -367,7 +366,7 @@ decoder->num_globals = cff->num_global_subrs; decoder->globals = cff->global_subrs; decoder->globals_bias = cff_compute_bias( decoder->num_globals ); - + decoder->hint_mode = hint_mode; } @@ -399,7 +398,7 @@ } - /* check that there is enough room for `count' more points */ + /* check that there is enough space for `count' more points */ static FT_Error check_points( CFF_Builder* builder, FT_Int count ) @@ -452,7 +451,7 @@ } - /* check room for a new contour, then add it */ + /* check space for a new contour, then add it */ static FT_Error cff_builder_add_contour( CFF_Builder* builder ) { @@ -486,7 +485,7 @@ FT_Pos x, FT_Pos y ) { - FT_Error error = 0; + FT_Error error = CFF_Err_Ok; /* test whether we are building a new contour */ @@ -546,6 +545,10 @@ FT_UShort glyph_sid; + /* CID-keyed fonts don't have glyph names */ + if ( !cff->charset.sids ) + return -1; + /* check range of standard char code */ if ( charcode < 0 || charcode > 255 ) return -1; @@ -641,13 +644,13 @@ FT_Int bchar, FT_Int achar ) { - FT_Error error; - FT_Int bchar_index, achar_index, n_base_points; - FT_Outline* base = decoder->builder.base; - TT_Face face = decoder->builder.face; - FT_Vector left_bearing, advance; - FT_Byte* charstring; - FT_ULong charstring_len; + FT_Error error; + CFF_Builder* builder = &decoder->builder; + FT_Int bchar_index, achar_index; + TT_Face face = decoder->builder.face; + FT_Vector left_bearing, advance; + FT_Byte* charstring; + FT_ULong charstring_len; #ifdef FT_CONFIG_OPTION_INCREMENTAL @@ -677,9 +680,9 @@ /* If we are trying to load a composite glyph, do not load the */ /* accent character and return the array of subglyphs. */ - if ( decoder->builder.no_recurse ) + if ( builder->no_recurse ) { - FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph; + FT_GlyphSlot glyph = (FT_GlyphSlot)builder->glyph; FT_GlyphLoader loader = glyph->internal->loader; FT_SubGlyph subg; @@ -702,8 +705,8 @@ /* subglyph 1 = accent character */ subg->index = achar_index; subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES; - subg->arg1 = (FT_Int)adx; - subg->arg2 = (FT_Int)ady; + subg->arg1 = (FT_Int)( adx >> 16 ); + subg->arg2 = (FT_Int)( ady >> 16 ); /* set up remaining glyph fields */ glyph->num_subglyphs = 2; @@ -713,6 +716,8 @@ loader->current.num_subglyphs = 2; } + FT_GlyphLoader_Prepare( builder->loader ); + /* First load `bchar' in builder */ error = cff_get_glyph_data( face, bchar_index, &charstring, &charstring_len ); @@ -727,16 +732,17 @@ cff_free_glyph_data( face, &charstring, charstring_len ); } - n_base_points = base->n_points; - /* Save the left bearing and width of the base character */ /* as they will be erased by the next load. */ - left_bearing = decoder->builder.left_bearing; - advance = decoder->builder.advance; + left_bearing = builder->left_bearing; + advance = builder->advance; - decoder->builder.left_bearing.x = 0; - decoder->builder.left_bearing.y = 0; + builder->left_bearing.x = 0; + builder->left_bearing.y = 0; + + builder->pos_x = adx; + builder->pos_y = ady; /* Now load `achar' on top of the base outline. */ error = cff_get_glyph_data( face, achar_index, @@ -754,20 +760,11 @@ /* Restore the left side bearing and advance width */ /* of the base character. */ - decoder->builder.left_bearing = left_bearing; - decoder->builder.advance = advance; + builder->left_bearing = left_bearing; + builder->advance = advance; - /* Finally, move the accent. */ - if ( decoder->builder.load_points ) - { - FT_Outline dummy; - - - dummy.n_points = (short)( base->n_points - n_base_points ); - dummy.points = base->points + n_base_points; - - FT_Outline_Translate( &dummy, adx, ady ); - } + builder->pos_x = 0; + builder->pos_y = 0; Exit: return error; @@ -818,7 +815,7 @@ seed = (FT_Fixed)(char*)&seed ^ (FT_Fixed)(char*)&decoder ^ (FT_Fixed)(char*)&charstring_base; - seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFF; + seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL; if ( seed == 0 ) seed = 0x7384; @@ -903,8 +900,8 @@ *decoder->top++ = val; #ifdef FT_DEBUG_LEVEL_TRACE - if ( !( val & 0xFFFF ) ) - FT_TRACE4(( " %d", (FT_Int32)( val >> 16 ) )); + if ( !( val & 0xFFFFL ) ) + FT_TRACE4(( " %ld", (FT_Int32)( val >> 16 ) )); else FT_TRACE4(( " %.2f", val / 65536.0 )); #endif @@ -1111,7 +1108,7 @@ /* `glyph_width' to `nominal_width' plus number on the stack */ /* -- for either case. */ - FT_Int set_width_ok; + FT_Int set_width_ok; switch ( op ) @@ -1126,6 +1123,8 @@ case cff_op_hstemhm: case cff_op_vstemhm: case cff_op_rmoveto: + case cff_op_hintmask: + case cff_op_cntrmask: set_width_ok = num_args & 1; break; @@ -1224,7 +1223,7 @@ for ( maskbyte = 0; maskbyte < (FT_UInt)(( decoder->num_hints + 7 ) >> 3); maskbyte++, ip++ ) - FT_TRACE4(( "%02X", *ip )); + FT_TRACE4(( "0x%02X", *ip )); } #else ip += ( decoder->num_hints + 7 ) >> 3; @@ -1650,11 +1649,11 @@ case cff_op_flex1: { - FT_Pos start_x, start_y; /* record start x, y values for alter */ - /* use */ - FT_Int dx = 0, dy = 0; /* used in horizontal/vertical */ - /* algorithm below */ - FT_Int horizontal, count; + FT_Pos start_x, start_y; /* record start x, y values for */ + /* alter use */ + FT_Fixed dx = 0, dy = 0; /* used in horizontal/vertical */ + /* algorithm below */ + FT_Int horizontal, count; FT_TRACE4(( " flex1" )); @@ -1676,8 +1675,8 @@ /* grab up to the last argument */ for ( count = 5; count > 0; count-- ) { - dx += (FT_Int)args[0]; - dy += (FT_Int)args[1]; + dx += args[0]; + dy += args[1]; args += 2; } @@ -1733,7 +1732,7 @@ x += args[0]; y += args[1]; cff_builder_add_point( builder, x, y, - (FT_Bool)( count == 3 || count == 0 ) ); + (FT_Bool)( count == 4 || count == 1 ) ); args += 2; } @@ -1747,35 +1746,43 @@ /* We are going to emulate the seac operator. */ if ( num_args == 4 ) { + /* Save glyph width so that the subglyphs don't overwrite it. */ + FT_Pos glyph_width = decoder->glyph_width; + + error = cff_operator_seac( decoder, - args[0] >> 16, - args[1] >> 16, + args[0], + args[1], (FT_Int)( args[2] >> 16 ), (FT_Int)( args[3] >> 16 ) ); args += 4; + + decoder->glyph_width = glyph_width; } - - if ( !error ) - error = CFF_Err_Ok; - - cff_builder_close_contour( builder ); - - /* close hints recording session */ - if ( hinter ) + else { - if (hinter->close( hinter->hints, builder->current->n_points ) ) - goto Syntax_Error; + if ( !error ) + error = CFF_Err_Ok; - /* apply hints to the loaded glyph outline now */ - hinter->apply( hinter->hints, - builder->current, - (PSH_Globals)builder->hints_globals, - builder->hint_flags ); + cff_builder_close_contour( builder ); + + /* close hints recording session */ + if ( hinter ) + { + if (hinter->close( hinter->hints, builder->current->n_points ) ) + goto Syntax_Error; + + /* apply hints to the loaded glyph outline now */ + hinter->apply( hinter->hints, + builder->current, + (PSH_Globals)builder->hints_globals, + decoder->hint_mode ); + } + + /* add current outline to the glyph slot */ + FT_GlyphLoader_Add( builder->loader ); } - /* add current outline to the glyph slot */ - FT_GlyphLoader_Add( builder->loader ); - /* return now! */ FT_TRACE4(( "\n\n" )); return error; @@ -1824,7 +1831,7 @@ FT_TRACE4(( " rand" )); Rand = seed; - if ( Rand >= 0x8000 ) + if ( Rand >= 0x8000L ) Rand++; args[0] = Rand; @@ -2212,7 +2219,7 @@ cff_compute_max_advance( TT_Face face, FT_Int* max_advance ) { - FT_Error error = 0; + FT_Error error = CFF_Err_Ok; CFF_Decoder decoder; FT_Int glyph_index; CFF_Font cff = (CFF_Font)face->other; @@ -2248,7 +2255,7 @@ } /* ignore the error if one has occurred -- skip to next glyph */ - error = 0; + error = CFF_Err_Ok; } *max_advance = decoder.builder.advance.x; @@ -2282,14 +2289,14 @@ FT_Int glyph_index, FT_Int32 load_flags ) { - FT_Error error; - CFF_Decoder decoder; - TT_Face face = (TT_Face)glyph->root.face; - FT_Bool hinting; - CFF_Font cff = (CFF_Font)face->extra.data; + FT_Error error; + CFF_Decoder decoder; + TT_Face face = (TT_Face)glyph->root.face; + FT_Bool hinting; + CFF_Font cff = (CFF_Font)face->extra.data; - FT_Matrix font_matrix; - FT_Vector font_offset; + FT_Matrix font_matrix; + FT_Vector font_offset; if ( load_flags & FT_LOAD_NO_RECURSE ) @@ -2299,10 +2306,77 @@ glyph->y_scale = 0x10000L; if ( size ) { - glyph->x_scale = size->metrics.x_scale; - glyph->y_scale = size->metrics.y_scale; + glyph->x_scale = size->root.metrics.x_scale; + glyph->y_scale = size->root.metrics.y_scale; } +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + /* try to load embedded bitmap if any */ + /* */ + /* XXX: The convention should be emphasized in */ + /* the documents because it can be confusing. */ + if ( size ) + { + CFF_Face cff_face = (CFF_Face)size->root.face; + SFNT_Service sfnt = (SFNT_Service)cff_face->sfnt; + FT_Stream stream = cff_face->root.stream; + + + if ( size->strike_index != 0xFFFFU && + sfnt->load_sbits && + ( load_flags & FT_LOAD_NO_BITMAP ) == 0 ) + { + TT_SBit_MetricsRec metrics; + + + error = sfnt->load_sbit_image( face, + (FT_ULong)size->strike_index, + (FT_UInt)glyph_index, + (FT_Int)load_flags, + stream, + &glyph->root.bitmap, + &metrics ); + + if ( !error ) + { + glyph->root.outline.n_points = 0; + glyph->root.outline.n_contours = 0; + + glyph->root.metrics.width = (FT_Pos)metrics.width << 6; + glyph->root.metrics.height = (FT_Pos)metrics.height << 6; + + glyph->root.metrics.horiBearingX = (FT_Pos)metrics.horiBearingX << 6; + glyph->root.metrics.horiBearingY = (FT_Pos)metrics.horiBearingY << 6; + glyph->root.metrics.horiAdvance = (FT_Pos)metrics.horiAdvance << 6; + + glyph->root.metrics.vertBearingX = (FT_Pos)metrics.vertBearingX << 6; + glyph->root.metrics.vertBearingY = (FT_Pos)metrics.vertBearingY << 6; + glyph->root.metrics.vertAdvance = (FT_Pos)metrics.vertAdvance << 6; + + glyph->root.format = FT_GLYPH_FORMAT_BITMAP; + + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) + { + glyph->root.bitmap_left = metrics.vertBearingX; + glyph->root.bitmap_top = metrics.vertBearingY; + } + else + { + glyph->root.bitmap_left = metrics.horiBearingX; + glyph->root.bitmap_top = metrics.horiBearingY; + } + return error; + } + } + } + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + /* return immediately if we only want the embedded bitmaps */ + if ( load_flags & FT_LOAD_SBITS_ONLY ) + return CFF_Err_Invalid_Argument; + glyph->root.outline.n_points = 0; glyph->root.outline.n_contours = 0; @@ -2316,8 +2390,15 @@ FT_ULong charstring_len; + /* in a CID-keyed font, consider `glyph_index' as a CID and map */ + /* it immediately to the real glyph_index -- if it isn't a */ + /* subsetted font, glyph_indices and CIDs are identical, though */ + if ( cff->top_font.font_dict.cid_registry != 0xFFFFU && + cff->charset.cids ) + glyph_index = cff->charset.cids[glyph_index]; + cff_decoder_init( &decoder, face, size, glyph, hinting, - FT_LOAD_TARGET_MODE(load_flags) ); + FT_LOAD_TARGET_MODE( load_flags ) ); decoder.builder.no_recurse = (FT_Bool)( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ); @@ -2363,18 +2444,19 @@ cff_builder_done( &decoder.builder ); } - #ifdef FT_CONFIG_OPTION_INCREMENTAL +#ifdef FT_CONFIG_OPTION_INCREMENTAL /* Incremental fonts can optionally override the metrics. */ - if ( !error && - face->root.internal->incremental_interface && + if ( !error && + face->root.internal->incremental_interface && face->root.internal->incremental_interface->funcs->get_glyph_metrics ) { FT_Incremental_MetricsRec metrics; + metrics.bearing_x = decoder.builder.left_bearing.x; - metrics.bearing_y = decoder.builder.left_bearing.y; - metrics.advance = decoder.builder.advance.x; + metrics.bearing_y = decoder.builder.left_bearing.y; + metrics.advance = decoder.builder.advance.x; error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( face->root.internal->incremental_interface->object, glyph_index, FALSE, &metrics ); @@ -2411,6 +2493,7 @@ { FT_BBox cbox; FT_Glyph_Metrics* metrics = &glyph->root.metrics; + FT_Vector advance; /* copy the _unscaled_ advance width */ @@ -2428,7 +2511,7 @@ glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; glyph->root.outline.flags = 0; - if ( size && size->metrics.y_ppem < 24 ) + if ( size && size->root.metrics.y_ppem < 24 ) glyph->root.outline.flags |= FT_OUTLINE_HIGH_PRECISION; glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL; @@ -2440,6 +2523,15 @@ font_offset.x, font_offset.y ); + advance.x = metrics->horiAdvance; + advance.y = 0; + FT_Vector_Transform( &advance, &font_matrix ); + metrics->horiAdvance = advance.x + font_offset.x; + advance.x = 0; + advance.y = metrics->vertAdvance; + FT_Vector_Transform( &advance, &font_matrix ); + metrics->vertAdvance = advance.y + font_offset.y; + if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) { /* scale the outline and the metrics */ @@ -2469,11 +2561,11 @@ if ( hinting ) { - metrics->horiAdvance = ( metrics->horiAdvance + 32 ) & -64; - metrics->vertAdvance = ( metrics->vertAdvance + 32 ) & -64; + metrics->horiAdvance = FT_PIX_ROUND( metrics->horiAdvance ); + metrics->vertAdvance = FT_PIX_ROUND( metrics->vertAdvance ); - metrics->vertBearingX = ( metrics->vertBearingX + 32 ) & -64; - metrics->vertBearingY = ( metrics->vertBearingY + 32 ) & -64; + metrics->vertBearingX = FT_PIX_ROUND( metrics->vertBearingX ); + metrics->vertBearingY = FT_PIX_ROUND( metrics->vertBearingY ); } } @@ -2501,4 +2593,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/cff/cffgload.h b/src/libs/freetype2/cff/cffgload.h index 6c52621fa3..3adfe7cc65 100644 --- a/src/libs/freetype2/cff/cffgload.h +++ b/src/libs/freetype2/cff/cffgload.h @@ -4,7 +4,7 @@ /* */ /* OpenType Glyph Loader (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -114,8 +114,6 @@ FT_BEGIN_HEADER FT_Error error; /* only used for memory errors */ FT_Bool metrics_only; - FT_UInt32 hint_flags; - void* hints_funcs; /* hinter-specific */ void* hints_globals; /* hinter-specific */ @@ -211,4 +209,4 @@ FT_END_HEADER #endif /* __CFFGLOAD_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/cff/cffload.c b/src/libs/freetype2/cff/cffload.c index 660d87c9f3..44f3254bd8 100644 --- a/src/libs/freetype2/cff/cffload.c +++ b/src/libs/freetype2/cff/cffload.c @@ -4,7 +4,7 @@ /* */ /* OpenType and CFF data/program tables loader (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,7 +20,7 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_POSTSCRIPT_NAMES_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H #include FT_TRUETYPE_TAGS_H #include "cffload.h" @@ -1172,12 +1172,12 @@ } - /* allocate a table containing pointers to an index's elements */ + /* allocate a table containing pointers to an index's elements */ static FT_Error cff_index_get_pointers( CFF_Index idx, FT_Byte*** table ) { - FT_Error error = 0; + FT_Error error = CFF_Err_Ok; FT_Memory memory = idx->stream->memory; FT_ULong n, offset, old_offset; FT_Byte** t; @@ -1211,7 +1211,7 @@ FT_Byte** pbytes, FT_ULong* pbyte_len ) { - FT_Error error = 0; + FT_Error error = CFF_Err_Ok; if ( idx && idx->count > element ) @@ -1312,18 +1312,26 @@ FT_LOCAL_DEF( FT_String* ) - cff_index_get_sid_string( CFF_Index idx, - FT_UInt sid, - PSNames_Service psnames_service ) + cff_index_get_sid_string( CFF_Index idx, + FT_UInt sid, + FT_Service_PsCMaps psnames ) { + /* value 0xFFFFU indicates a missing dictionary entry */ + if ( sid == 0xFFFFU ) + return 0; + /* if it is not a standard string, return it */ if ( sid > 390 ) return cff_index_get_name( idx, sid - 391 ); + /* CID-keyed CFF fonts don't have glyph names */ + if ( !psnames ) + return 0; + /* that's a standard string, fetch a copy from the PSName module */ { FT_String* name = 0; - const char* adobe_name = psnames_service->adobe_std_strings( sid ); + const char* adobe_name = psnames->adobe_std_strings( sid ); FT_UInt len; @@ -1493,6 +1501,7 @@ FT_FREE( charset->sids ); + FT_FREE( charset->cids ); charset->format = 0; charset->offset = 0; } @@ -1503,10 +1512,11 @@ FT_UInt num_glyphs, FT_Stream stream, FT_ULong base_offset, - FT_ULong offset ) + FT_ULong offset, + FT_Bool invert ) { - FT_Memory memory = stream->memory; - FT_Error error = 0; + FT_Memory memory = stream->memory; + FT_Error error = CFF_Err_Ok; FT_UShort glyph_sid; @@ -1557,7 +1567,6 @@ while ( j < num_glyphs ) { - /* Read the first glyph sid of the range. */ if ( FT_READ_USHORT( glyph_sid ) ) goto Exit; @@ -1595,7 +1604,7 @@ /* In order to use a predefined charset, the following must be */ /* true: The charset constructed for the glyphs in the font's */ /* charstrings dictionary must match the predefined charset in */ - /* the first num_glyphs */ + /* the first num_glyphs. */ charset->offset = offset; /* record charset type */ @@ -1604,8 +1613,8 @@ case 0: if ( num_glyphs > 229 ) { - FT_ERROR(("cff_charset_load: implicit charset larger than\n" - "predefined charset (Adobe ISO-Latin)!\n" )); + FT_ERROR(( "cff_charset_load: implicit charset larger than\n" + "predefined charset (Adobe ISO-Latin)!\n" )); error = CFF_Err_Invalid_File_Format; goto Exit; } @@ -1615,8 +1624,7 @@ goto Exit; /* Copy the predefined charset into the allocated memory. */ - FT_MEM_COPY( charset->sids, cff_isoadobe_charset, - num_glyphs * sizeof ( FT_UShort ) ); + FT_ARRAY_COPY( charset->sids, cff_isoadobe_charset, num_glyphs ); break; @@ -1634,8 +1642,7 @@ goto Exit; /* Copy the predefined charset into the allocated memory. */ - FT_MEM_COPY( charset->sids, cff_expert_charset, - num_glyphs * sizeof ( FT_UShort ) ); + FT_ARRAY_COPY( charset->sids, cff_expert_charset, num_glyphs ); break; @@ -1653,8 +1660,7 @@ goto Exit; /* Copy the predefined charset into the allocated memory. */ - FT_MEM_COPY( charset->sids, cff_expertsubset_charset, - num_glyphs * sizeof ( FT_UShort ) ); + FT_ARRAY_COPY( charset->sids, cff_expertsubset_charset, num_glyphs ); break; @@ -1664,23 +1670,41 @@ } } - Exit: + /* we have to invert the `sids' array for subsetted CID-keyed fonts */ + if ( invert ) + { + FT_UInt i; + FT_UShort max_cid = 0; + + for ( i = 0; i < num_glyphs; i++ ) + if ( charset->sids[i] > max_cid ) + max_cid = charset->sids[i]; + max_cid++; + + if ( FT_NEW_ARRAY( charset->cids, max_cid ) ) + goto Exit; + FT_MEM_ZERO( charset->cids, sizeof ( FT_UShort ) * max_cid ); + + for ( i = 0; i < num_glyphs; i++ ) + charset->cids[charset->sids[i]] = i; + } + + Exit: /* Clean up if there was an error. */ if ( error ) - if ( charset->sids ) - { - FT_FREE( charset->sids ); - charset->format = 0; - charset->offset = 0; - charset->sids = 0; - } + { + FT_FREE( charset->sids ); + FT_FREE( charset->cids ); + charset->format = 0; + charset->offset = 0; + charset->sids = 0; + } return error; } - static void cff_encoding_done( CFF_Encoding encoding ) { @@ -1690,7 +1714,6 @@ } - static FT_Error cff_encoding_load( CFF_Encoding encoding, CFF_Charset charset, @@ -1699,11 +1722,11 @@ FT_ULong base_offset, FT_ULong offset ) { - FT_Error error = 0; - FT_UInt count; - FT_UInt j; - FT_UShort glyph_sid; - FT_UInt glyph_code; + FT_Error error = CFF_Err_Ok; + FT_UInt count; + FT_UInt j; + FT_UShort glyph_sid; + FT_UInt glyph_code; /* Check for charset->sids. If we do not have this, we fail. */ @@ -1720,8 +1743,8 @@ encoding->codes[j] = 0; } - /* Note: The encoding table in a CFF font is indexed by glyph index, */ - /* where the first encoded glyph index is 1. Hence, we read the char */ + /* Note: The encoding table in a CFF font is indexed by glyph index; */ + /* the first encoded glyph index is 1. Hence, we read the character */ /* code (`glyph_code') at index j and make the assignment: */ /* */ /* encoding->codes[glyph_code] = j + 1 */ @@ -1734,7 +1757,6 @@ if ( offset > 1 ) { - encoding->offset = base_offset + offset; /* we need to parse the table to determine its size */ @@ -1749,9 +1771,10 @@ { FT_Byte* p; - /* by convention, GID 0 is always ".notdef" and is never */ - /* coded in the font. Hence, the number of codes found */ - /* in the table is 'count+1' */ + + /* By convention, GID 0 is always ".notdef" and is never */ + /* coded in the font. Hence, the number of codes found */ + /* in the table is `count+1'. */ /* */ encoding->count = count + 1; @@ -1781,7 +1804,7 @@ case 1: { - FT_Byte nleft; + FT_UInt nleft; FT_UInt i = 1; FT_UInt k; @@ -1821,7 +1844,7 @@ } } - /* simple check, one never knows what can be found in a font */ + /* simple check; one never knows what can be found in a font */ if ( encoding->count > 256 ) encoding->count = 256; } @@ -1856,13 +1879,13 @@ /* Assign code to SID mapping. */ encoding->sids[glyph_code] = glyph_sid; - /* First, lookup GID which has been assigned to */ - /* SID glyph_sid. */ + /* First, look up GID which has been assigned to */ + /* SID glyph_sid. */ for ( gindex = 0; gindex < num_glyphs; gindex++ ) { if ( charset->sids[gindex] == glyph_sid ) { - encoding->codes[glyph_code] = (FT_UShort) gindex; + encoding->codes[glyph_code] = (FT_UShort)gindex; break; } } @@ -1874,24 +1897,21 @@ FT_UInt i; - /* We take into account the fact a CFF font can use a predefined */ - /* encoding without containing all of the glyphs encoded by this */ - /* encoding (see the note at the end of section 12 in the CFF */ - /* specification). */ + /* We take into account the fact a CFF font can use a predefined */ + /* encoding without containing all of the glyphs encoded by this */ + /* encoding (see the note at the end of section 12 in the CFF */ + /* specification). */ switch ( (FT_UInt)offset ) { case 0: /* First, copy the code to SID mapping. */ - FT_MEM_COPY( encoding->sids, cff_standard_encoding, - 256 * sizeof ( FT_UShort ) ); - + FT_ARRAY_COPY( encoding->sids, cff_standard_encoding, 256 ); goto Populate; case 1: /* First, copy the code to SID mapping. */ - FT_MEM_COPY( encoding->sids, cff_expert_encoding, - 256 * sizeof ( FT_UShort ) ); + FT_ARRAY_COPY( encoding->sids, cff_expert_encoding, 256 ); Populate: /* Construct code to GID mapping from code to SID mapping */ @@ -1899,7 +1919,6 @@ encoding->count = 0; - for ( j = 0; j < 256; j++ ) { /* If j is encoded, find the GID for it. */ @@ -1923,8 +1942,8 @@ encoding->codes[j] = (FT_UShort)i; /* update encoding count */ - if ( encoding->count < j+1 ) - encoding->count = j+1; + if ( encoding->count < j + 1 ) + encoding->count = j + 1; } } } @@ -1953,7 +1972,7 @@ { FT_Error error; CFF_ParserRec parser; - FT_Byte* dict; + FT_Byte* dict = NULL; FT_ULong dict_len; CFF_FontRecDict top = &font->font_dict; CFF_Private priv = &font->private_dict; @@ -1964,13 +1983,27 @@ /* set defaults */ FT_MEM_ZERO( top, sizeof ( *top ) ); - top->underline_position = -100; - top->underline_thickness = 50; + top->underline_position = -100L << 16; + top->underline_thickness = 50L << 16; top->charstring_type = 2; top->font_matrix.xx = 0x10000L; top->font_matrix.yy = 0x10000L; top->cid_count = 8720; + /* we use the implementation specific SID value 0xFFFF to indicate */ + /* missing entries */ + top->version = 0xFFFFU; + top->notice = 0xFFFFU; + top->copyright = 0xFFFFU; + top->full_name = 0xFFFFU; + top->family_name = 0xFFFFU; + top->weight = 0xFFFFU; + top->embedded_postscript = 0xFFFFU; + + top->cid_registry = 0xFFFFU; + top->cid_ordering = 0xFFFFU; + top->cid_font_name = 0xFFFFU; + error = cff_index_access_element( idx, font_index, &dict, &dict_len ) || cff_parser_run( &parser, dict, dict + dict_len ); @@ -1980,7 +2013,7 @@ goto Exit; /* if it is a CID font, we stop there */ - if ( top->cid_registry ) + if ( top->cid_registry != 0xFFFFU ) goto Exit; /* parse the private dictionary, if any */ @@ -1992,8 +2025,8 @@ priv->blue_shift = 7; priv->blue_fuzz = 1; priv->lenIV = -1; - priv->expansion_factor = (FT_Fixed)0.06 * 0x10000L; - priv->blue_scale = (FT_Fixed)0.039625 * 0x10000L; + priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L ); + priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 ); cff_parser_init( &parser, CFF_CODE_PRIVATE, priv ); @@ -2121,8 +2154,15 @@ if ( error ) goto Exit; + if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) ) + goto Exit; + + error = cff_new_index( &font->charstrings_index, stream, 0 ); + if ( error ) + goto Exit; + /* now, check for a CID font */ - if ( dict->cid_registry ) + if ( dict->cid_registry != 0xFFFFU ) { CFF_IndexRec fd_index; CFF_SubFont sub; @@ -2165,7 +2205,7 @@ /* now load the FD Select array */ error = CFF_Load_FD_Select( &font->fd_select, - (FT_UInt)dict->cid_count, + font->charstrings_index.count, stream, base_offset + dict->cid_fd_select_offset ); @@ -2186,13 +2226,6 @@ goto Exit; } - if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) ) - goto Exit; - - error = cff_new_index( &font->charstrings_index, stream, 0 ); - if ( error ) - goto Exit; - /* explicit the global subrs */ font->num_global_subrs = font->global_subrs_index.count; font->num_glyphs = font->charstrings_index.count; @@ -2203,25 +2236,38 @@ if ( error ) goto Exit; - /* read the Charset and Encoding tables when available */ + /* read the Charset and Encoding tables if available */ if ( font->num_glyphs > 0 ) { + FT_Bool invert; + + + invert = dict->cid_registry != 0xFFFFU && + font->charstrings_index.count != dict->cid_count; error = cff_charset_load( &font->charset, font->num_glyphs, stream, - base_offset, dict->charset_offset ); + base_offset, dict->charset_offset, invert ); if ( error ) goto Exit; - error = cff_encoding_load( &font->encoding, - &font->charset, - font->num_glyphs, - stream, - base_offset, - dict->encoding_offset ); - if ( error ) - goto Exit; + /* CID-keyed CFFs don't have an encoding */ + if ( dict->cid_registry == 0xFFFFU ) + { + error = cff_encoding_load( &font->encoding, + &font->charset, + font->num_glyphs, + stream, + base_offset, + dict->encoding_offset ); + if ( error ) + goto Exit; + } + else + /* CID-keyed fonts only need CIDs */ + FT_FREE( font->charset.sids ); } - /* get the font name */ + /* get the font name (/CIDFontName for CID-keyed fonts, */ + /* /FontName otherwise) */ font->font_name = cff_index_get_name( &font->name_index, face_index ); Exit: @@ -2264,4 +2310,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/cff/cffload.h b/src/libs/freetype2/cff/cffload.h index 0bb76be029..ccf8ada1c3 100644 --- a/src/libs/freetype2/cff/cffload.h +++ b/src/libs/freetype2/cff/cffload.h @@ -4,7 +4,7 @@ /* */ /* OpenType & CFF data/program tables loader (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,8 +21,8 @@ #include <ft2build.h> -#include FT_INTERNAL_CFF_TYPES_H -#include FT_INTERNAL_POSTSCRIPT_NAMES_H +#include "cfftypes.h" +#include FT_SERVICE_POSTSCRIPT_CMAPS_H FT_BEGIN_HEADER @@ -36,9 +36,9 @@ FT_BEGIN_HEADER FT_UInt element ); FT_LOCAL( FT_String* ) - cff_index_get_sid_string( CFF_Index idx, - FT_UInt sid, - PSNames_Service psnames_interface ); + cff_index_get_sid_string( CFF_Index idx, + FT_UInt sid, + FT_Service_PsCMaps psnames ); FT_LOCAL( FT_Error ) @@ -62,7 +62,7 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Byte ) - cff_fd_select_get( CFF_FDSelect select, + cff_fd_select_get( CFF_FDSelect fdselect, FT_UInt glyph_index ); @@ -71,4 +71,4 @@ FT_END_HEADER #endif /* __CFFLOAD_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/cff/cffobjs.c b/src/libs/freetype2/cff/cffobjs.c index d34b083c34..bbe1654ee7 100644 --- a/src/libs/freetype2/cff/cffobjs.c +++ b/src/libs/freetype2/cff/cffobjs.c @@ -4,7 +4,7 @@ /* */ /* OpenType objects manager (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,7 +24,7 @@ #include FT_TRUETYPE_IDS_H #include FT_TRUETYPE_TAGS_H #include FT_INTERNAL_SFNT_H -#include FT_INTERNAL_POSTSCRIPT_NAMES_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H #include FT_INTERNAL_POSTSCRIPT_HINTS_H #include "cffobjs.h" #include "cffload.h" @@ -52,16 +52,81 @@ /*************************************************************************/ +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + static FT_Error + sbit_size_reset( CFF_Size size ) + { + CFF_Face face; + FT_Error error = CFF_Err_Ok; + + FT_ULong strike_index; + FT_Size_Metrics* metrics; + FT_Size_Metrics* sbit_metrics; + SFNT_Service sfnt; + + + metrics = &size->root.metrics; + + face = (CFF_Face)size->root.face; + sfnt = (SFNT_Service)face->sfnt; + + sbit_metrics = &size->strike_metrics; + + error = sfnt->set_sbit_strike( face, + metrics->x_ppem, metrics->y_ppem, + &strike_index ); + + if ( !error ) + { + TT_SBit_Strike strike = face->sbit_strikes + strike_index; + + + sbit_metrics->x_ppem = metrics->x_ppem; + sbit_metrics->y_ppem = metrics->y_ppem; + + sbit_metrics->ascender = strike->hori.ascender << 6; + sbit_metrics->descender = strike->hori.descender << 6; + + /* XXX: Is this correct? */ + sbit_metrics->height = sbit_metrics->ascender - + sbit_metrics->descender; + + /* XXX: Is this correct? */ + sbit_metrics->max_advance = ( strike->hori.min_origin_SB + + strike->hori.max_width + + strike->hori.min_advance_SB ) << 6; + + size->strike_index = (FT_UInt)strike_index; + } + else + { + size->strike_index = 0xFFFFU; + + sbit_metrics->x_ppem = 0; + sbit_metrics->y_ppem = 0; + sbit_metrics->ascender = 0; + sbit_metrics->descender = 0; + sbit_metrics->height = 0; + sbit_metrics->max_advance = 0; + } + + return error; + } + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + static PSH_Globals_Funcs cff_size_get_globals_funcs( CFF_Size size ) { - CFF_Face face = (CFF_Face)size->face; + CFF_Face face = (CFF_Face)size->root.face; CFF_Font font = (CFF_FontRec *)face->extra.data; PSHinter_Service pshinter = (PSHinter_Service)font->pshinter; FT_Module module; - module = FT_Get_Module( size->face->driver->root.library, + module = FT_Get_Module( size->root.face->driver->root.library, "pshinter" ); return ( module && pshinter && pshinter->get_globals_funcs ) ? pshinter->get_globals_funcs( module ) @@ -72,16 +137,16 @@ FT_LOCAL_DEF( void ) cff_size_done( CFF_Size size ) { - if ( size->internal ) + if ( size->root.internal ) { PSH_Globals_Funcs funcs; funcs = cff_size_get_globals_funcs( size ); if ( funcs ) - funcs->destroy( (PSH_Globals)size->internal ); + funcs->destroy( (PSH_Globals)size->root.internal ); - size->internal = 0; + size->root.internal = 0; } } @@ -89,14 +154,14 @@ FT_LOCAL_DEF( FT_Error ) cff_size_init( CFF_Size size ) { - FT_Error error = 0; + FT_Error error = CFF_Err_Ok; PSH_Globals_Funcs funcs = cff_size_get_globals_funcs( size ); if ( funcs ) { PSH_Globals globals; - CFF_Face face = (CFF_Face)size->face; + CFF_Face face = (CFF_Face)size->root.face; CFF_Font font = (CFF_FontRec *)face->extra.data; CFF_SubFont subfont = &font->top_font; @@ -150,9 +215,9 @@ priv.lenIV = cpriv->lenIV; } - error = funcs->create( size->face->memory, &priv, &globals ); + error = funcs->create( size->root.face->memory, &priv, &globals ); if ( !error ) - size->internal = (FT_Size_Internal)(void*)globals; + size->root.internal = (FT_Size_Internal)(void*)globals; } return error; @@ -163,15 +228,32 @@ cff_size_reset( CFF_Size size ) { PSH_Globals_Funcs funcs = cff_size_get_globals_funcs( size ); - FT_Error error = 0; + FT_Error error = CFF_Err_Ok; + FT_Face face = size->root.face; if ( funcs ) - error = funcs->set_scale( (PSH_Globals)size->internal, - size->metrics.x_scale, - size->metrics.y_scale, + error = funcs->set_scale( (PSH_Globals)size->root.internal, + size->root.metrics.x_scale, + size->root.metrics.y_scale, 0, 0 ); - return error; + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + if ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES ) + { + error = sbit_size_reset( size ); + + if ( !error && !( face->face_flags & FT_FACE_FLAG_SCALABLE ) ) + size->root.metrics = size->strike_metrics; + } + +#endif + + if ( face->face_flags & FT_FACE_FLAG_SCALABLE ) + return CFF_Err_Ok; + else + return error; } @@ -244,8 +326,6 @@ } - - FT_LOCAL_DEF( FT_Error ) cff_face_init( FT_Stream stream, CFF_Face face, @@ -253,30 +333,37 @@ FT_Int num_params, FT_Parameter* params ) { - FT_Error error; - SFNT_Service sfnt; - PSNames_Service psnames; - PSHinter_Service pshinter; - FT_Bool pure_cff = 1; - FT_Bool sfnt_format = 0; + FT_Error error; + SFNT_Service sfnt; + FT_Service_PsCMaps psnames; + PSHinter_Service pshinter; + FT_Bool pure_cff = 1; + FT_Bool sfnt_format = 0; +#if 0 + FT_FACE_FIND_GLOBAL_SERVICE( face, sfnt, SFNT ); + FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_NAMES ); + FT_FACE_FIND_GLOBAL_SERVICE( face, pshinter, POSTSCRIPT_HINTER ); + if ( !sfnt ) + goto Bad_Format; +#else sfnt = (SFNT_Service)FT_Get_Module_Interface( face->root.driver->root.library, "sfnt" ); if ( !sfnt ) goto Bad_Format; - psnames = (PSNames_Service)FT_Get_Module_Interface( - face->root.driver->root.library, "psnames" ); + FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); pshinter = (PSHinter_Service)FT_Get_Module_Interface( face->root.driver->root.library, "pshinter" ); +#endif /* create input stream from resource */ if ( FT_STREAM_SEEK( 0 ) ) goto Exit; - /* check that we have a valid OpenType file */ + /* check whether we have a valid OpenType file */ error = sfnt->init_face( stream, face, face_index, num_params, params ); if ( !error ) { @@ -293,7 +380,7 @@ sfnt_format = 1; /* now, the font can be either an OpenType/CFF font, or an SVG CEF */ - /* font in the later case; it doesn't have a `head' table */ + /* font; in the latter case it doesn't have a `head' table */ error = face->goto_table( face, TTAG_head, stream, 0 ); if ( !error ) { @@ -307,7 +394,7 @@ } else { - /* load the `cmap' table by hand */ + /* load the `cmap' table explicitly */ error = sfnt->load_charmaps( face, stream ); if ( error ) goto Exit; @@ -317,7 +404,7 @@ /* FreeType 2 */ } - /* now, load the CFF part of the file */ + /* now load the CFF part of the file */ error = face->goto_table( face, TTAG_CFF, stream, 0 ); if ( error ) goto Exit; @@ -332,10 +419,11 @@ /* now load and parse the CFF table in the file */ { - CFF_Font cff; - FT_Memory memory = face->root.memory; - FT_Face root; - FT_Int32 flags; + CFF_Font cff; + CFF_FontRecDict dict; + FT_Memory memory = face->root.memory; + FT_Face root; + FT_Int32 flags; if ( FT_NEW( cff ) ) @@ -347,7 +435,7 @@ goto Exit; cff->pshinter = pshinter; - cff->psnames = psnames; + cff->psnames = (void*)psnames; /* Complement the root flags with some interesting information. */ /* Note that this is only necessary for pure CFF and CEF fonts. */ @@ -355,26 +443,29 @@ root = &face->root; root->num_glyphs = cff->num_glyphs; + dict = &cff->top_font.font_dict; + + /* we need the `PSNames' module for CFF and CEF formats */ + /* which aren't CID-keyed */ + if ( dict->cid_registry == 0xFFFFU && !psnames ) + { + FT_ERROR(( "cff_face_init:" )); + FT_ERROR(( " cannot open CFF & CEF fonts\n" )); + FT_ERROR(( " " )); + FT_ERROR(( " without the `PSNames' module\n" )); + goto Bad_Format; + } + if ( pure_cff ) { - CFF_FontRecDict dict = &cff->top_font.font_dict; + char* style_name = NULL; - /* we need the `PSNames' module for pure-CFF and CEF formats */ - if ( !psnames ) - { - FT_ERROR(( "cff_face_init:" )); - FT_ERROR(( " cannot open CFF & CEF fonts\n" )); - FT_ERROR(( " " )); - FT_ERROR(( " without the `PSNames' module\n" )); - goto Bad_Format; - } - /* Set up num_faces. */ root->num_faces = cff->num_faces; /* compute number of glyphs */ - if ( dict->cid_registry ) + if ( dict->cid_registry != 0xFFFFU ) root->num_glyphs = dict->cid_count; else root->num_glyphs = cff->charstrings_index.count; @@ -385,7 +476,6 @@ root->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFFU ) >> 16; root->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFFU ) >> 16; - root->ascender = (FT_Short)( root->bbox.yMax ); root->descender = (FT_Short)( root->bbox.yMin ); root->height = (FT_Short)( @@ -396,14 +486,87 @@ else root->units_per_EM = 1000; + root->underline_position = + (FT_Short)( dict->underline_position >> 16 ); + root->underline_thickness = + (FT_Short)( dict->underline_thickness >> 16 ); + /* retrieve font family & style name */ - root->family_name = cff_index_get_name( &cff->name_index, face_index ); - if ( dict->cid_registry ) - root->style_name = cff_strcpy( memory, "Regular" ); /* XXXX */ + root->family_name = cff_index_get_name( &cff->name_index, + face_index ); + + if ( root->family_name ) + { + char* full = cff_index_get_sid_string( &cff->string_index, + dict->full_name, + psnames ); + char* fullp = full; + char* family = root->family_name; + + /* we're going to try to extract the style name from the + * full name. We need to ignore spaces and dashes during + * the search. + */ + if ( full ) + { + while ( *fullp ) + { + /* skip common characters at the start of both strings + */ + if ( *fullp == *family ) + { + family++; + fullp++; + continue; + } + + /* ignore spaces or dashes in full name during comparison + */ + if ( *fullp == ' ' || *fullp == '-' ) + { + fullp++; + continue; + } + /* ignore spaces and dashes in family name during comparison + */ + if ( *family == ' ' || *family == '-' ) + { + family++; + continue; + } + + if ( !*family && *fullp ) + { + /* the full name begins with the same characters than the + * family name, with spaces and dashes removed. In this + * case, the remaining string in "fullp" will be used + * as the style name + */ + style_name = cff_strcpy( memory, fullp ); + } + break; + } + FT_FREE( full ); + } + } else - root->style_name = cff_index_get_sid_string( &cff->string_index, - dict->weight, - psnames ); + { + char *cid_font_name = + cff_index_get_sid_string( &cff->string_index, + dict->cid_font_name, + psnames ); + + + /* do we have a `/FontName' for a CID-keyed font? */ + if ( cid_font_name ) + root->family_name = cid_font_name; + } + + if ( style_name ) + root->style_name = style_name; + else + /* assume "Regular" style if we don't know better */ + root->style_name = cff_strcpy( memory, (char *)"Regular" ); /*******************************************************************/ /* */ @@ -426,10 +589,6 @@ flags |= FT_FACE_FLAG_KERNING; #endif -#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES - flags |= FT_FACE_FLAG_GLYPH_NAMES; -#endif - root->face_flags = flags; /*******************************************************************/ @@ -441,13 +600,29 @@ if ( dict->italic_angle ) flags |= FT_STYLE_FLAG_ITALIC; - /* XXX: may not be correct */ - if ( cff->top_font.private_dict.force_bold ) - flags |= FT_STYLE_FLAG_BOLD; + { + char *weight = cff_index_get_sid_string( &cff->string_index, + dict->weight, + psnames ); + + + if ( weight ) + if ( !ft_strcmp( weight, "Bold" ) || + !ft_strcmp( weight, "Black" ) ) + flags |= FT_STYLE_FLAG_BOLD; + FT_FREE( weight ); + } root->style_flags = flags; } +#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES + /* CID-keyed CFF fonts don't have glyph names -- the SFNT loader */ + /* has unset this flag because of the 3.0 `post' table */ + if ( dict->cid_registry == 0xFFFFU ) + root->face_flags |= FT_FACE_FLAG_GLYPH_NAMES; +#endif + /*******************************************************************/ /* */ /* Compute char maps. */ @@ -463,7 +638,7 @@ CFF_Encoding encoding = &cff->encoding; - for ( nn = 0; nn < (FT_UInt) root->num_charmaps; nn++ ) + for ( nn = 0; nn < (FT_UInt)root->num_charmaps; nn++ ) { cmap = root->charmaps[nn]; @@ -476,18 +651,23 @@ goto Skip_Unicode; /* Standard Unicode (deprecated) */ } - /* we didn't find a Unicode charmap, synthetize one */ + /* since CID-keyed fonts don't contain glyph names, we can't */ + /* construct a cmap */ + if ( pure_cff && cff->top_font.font_dict.cid_registry != 0xFFFFU ) + goto Exit; + + /* we didn't find a Unicode charmap -- synthetize one */ cmaprec.face = root; cmaprec.platform_id = 3; cmaprec.encoding_id = 1; cmaprec.encoding = FT_ENCODING_UNICODE; - nn = (FT_UInt) root->num_charmaps; + nn = (FT_UInt)root->num_charmaps; FT_CMap_New( &cff_cmap_unicode_class_rec, NULL, &cmaprec, NULL ); /* if no Unicode charmap was previously selected, select this one */ - if ( root->charmap == NULL && nn != (FT_UInt) root->num_charmaps ) + if ( root->charmap == NULL && nn != (FT_UInt)root->num_charmaps ) root->charmap = root->charmaps[nn]; Skip_Unicode: @@ -501,26 +681,25 @@ if ( encoding->offset == 0 ) { - cmaprec.encoding_id = 0; + cmaprec.encoding_id = TT_ADOBE_ID_STANDARD; cmaprec.encoding = FT_ENCODING_ADOBE_STANDARD; clazz = &cff_cmap_encoding_class_rec; } else if ( encoding->offset == 1 ) { - cmaprec.encoding_id = 1; + cmaprec.encoding_id = TT_ADOBE_ID_EXPERT; cmaprec.encoding = FT_ENCODING_ADOBE_EXPERT; clazz = &cff_cmap_encoding_class_rec; } else { - cmaprec.encoding_id = 3; + cmaprec.encoding_id = TT_ADOBE_ID_CUSTOM; cmaprec.encoding = FT_ENCODING_ADOBE_CUSTOM; clazz = &cff_cmap_encoding_class_rec; } FT_CMap_New( clazz, NULL, &cmaprec, NULL ); } - } } @@ -572,4 +751,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/cff/cffobjs.h b/src/libs/freetype2/cff/cffobjs.h index 878d47ea99..f02a5d7484 100644 --- a/src/libs/freetype2/cff/cffobjs.h +++ b/src/libs/freetype2/cff/cffobjs.h @@ -4,7 +4,7 @@ /* */ /* OpenType objects manager (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,9 +22,9 @@ #include <ft2build.h> #include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_CFF_TYPES_H +#include "cfftypes.h" #include FT_INTERNAL_TRUETYPE_TYPES_H -#include FT_INTERNAL_POSTSCRIPT_NAMES_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H FT_BEGIN_HEADER @@ -51,7 +51,18 @@ FT_BEGIN_HEADER /* <Description> */ /* A handle to an OpenType size object. */ /* */ - typedef FT_Size CFF_Size; + typedef struct CFF_SizeRec_ + { + FT_SizeRec root; + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + FT_UInt strike_index; /* 0xFFFF to indicate invalid */ + FT_Size_Metrics strike_metrics; /* current strike's metrics */ + +#endif + + } CFF_SizeRec, *CFF_Size; /*************************************************************************/ @@ -89,15 +100,6 @@ FT_BEGIN_HEADER } CFF_Transform; - /* this is only used in the case of a pure CFF font with no charmap */ - typedef struct CFF_CharMapRec_ - { - TT_CharMapRec root; - PS_Unicodes unicodes; - - } CFF_CharMapRec, *CFF_CharMap; - - /***********************************************************************/ /* */ /* TrueType driver class. */ @@ -157,4 +159,4 @@ FT_END_HEADER #endif /* __CFFOBJS_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/cff/cffparse.c b/src/libs/freetype2/cff/cffparse.c index 18ef7f7b42..c4e5a6c595 100644 --- a/src/libs/freetype2/cff/cffparse.c +++ b/src/libs/freetype2/cff/cffparse.c @@ -4,7 +4,7 @@ /* */ /* CFF token stream parser (body) */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -38,6 +38,7 @@ cff_kind_none = 0, cff_kind_num, cff_kind_fixed, + cff_kind_fixed_thousand, cff_kind_string, cff_kind_bool, cff_kind_delta, @@ -333,7 +334,7 @@ offset->x = cff_parse_fixed_thousand( data++ ); offset->y = cff_parse_fixed_thousand( data ); - temp = ABS( matrix->yy ); + temp = FT_ABS( matrix->yy ); *upm = (FT_UShort)FT_DivFix( 0x10000L, FT_DivFix( temp, 1000 ) ); @@ -429,6 +430,8 @@ CFF_FIELD( code, name, cff_kind_num ) #define CFF_FIELD_FIXED( code, name ) \ CFF_FIELD( code, name, cff_kind_fixed ) +#define CFF_FIELD_FIXED_1000( code, name ) \ + CFF_FIELD( code, name, cff_kind_fixed_thousand ) #define CFF_FIELD_STRING( code, name ) \ CFF_FIELD( code, name, cff_kind_string ) #define CFF_FIELD_BOOL( code, name ) \ @@ -579,6 +582,10 @@ case cff_kind_fixed: val = cff_parse_fixed( parser->stack ); + goto Store_Number; + + case cff_kind_fixed_thousand: + val = cff_parse_fixed_thousand( parser->stack ); Store_Number: switch ( field->size ) @@ -678,4 +685,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/cff/cffparse.h b/src/libs/freetype2/cff/cffparse.h index 2392764efb..8f3fa58859 100644 --- a/src/libs/freetype2/cff/cffparse.h +++ b/src/libs/freetype2/cff/cffparse.h @@ -4,7 +4,7 @@ /* */ /* CFF token stream parser (specification) */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,7 +21,7 @@ #include <ft2build.h> -#include FT_INTERNAL_CFF_TYPES_H +#include "cfftypes.h" #include FT_INTERNAL_OBJECTS_H @@ -66,4 +66,4 @@ FT_END_HEADER #endif /* __CFF_PARSE_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/cff/cfftoken.h b/src/libs/freetype2/cff/cfftoken.h index 4df58c1c7f..659d1576aa 100644 --- a/src/libs/freetype2/cff/cfftoken.h +++ b/src/libs/freetype2/cff/cfftoken.h @@ -4,7 +4,7 @@ /* */ /* CFF token definitions (specification only). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -30,8 +30,8 @@ CFF_FIELD_STRING ( 4, weight ) CFF_FIELD_BOOL ( 0x101, is_fixed_pitch ) CFF_FIELD_FIXED ( 0x102, italic_angle ) - CFF_FIELD_NUM ( 0x103, underline_position ) - CFF_FIELD_NUM ( 0x104, underline_thickness ) + CFF_FIELD_FIXED ( 0x103, underline_position ) + CFF_FIELD_FIXED ( 0x104, underline_thickness ) CFF_FIELD_NUM ( 0x105, paint_type ) CFF_FIELD_NUM ( 0x106, charstring_type ) CFF_FIELD_CALLBACK( 0x107, font_matrix ) @@ -43,10 +43,10 @@ CFF_FIELD_NUM ( 17, charstrings_offset ) CFF_FIELD_CALLBACK( 18, private_dict ) CFF_FIELD_NUM ( 0x114, synthetic_base ) - CFF_FIELD_STRING ( 0x115, postscript ) - CFF_FIELD_STRING ( 0x116, base_font_name ) + CFF_FIELD_STRING ( 0x115, embedded_postscript ) #if 0 + CFF_FIELD_STRING ( 0x116, base_font_name ) CFF_FIELD_DELTA ( 0x117, base_font_blend, 16 ) CFF_FIELD_CALLBACK( 0x118, multiple_master ) CFF_FIELD_CALLBACK( 0x119, blend_axit_types ) @@ -72,26 +72,26 @@ #undef CFFCODE #define CFFCODE CFFCODE_PRIVATE - CFF_FIELD_DELTA( 6, blue_values, 14 ) - CFF_FIELD_DELTA( 7, other_blues, 10 ) - CFF_FIELD_DELTA( 8, family_blues, 14 ) - CFF_FIELD_DELTA( 9, family_other_blues, 10 ) - CFF_FIELD_FIXED( 0x109, blue_scale ) - CFF_FIELD_NUM ( 0x10A, blue_shift ) - CFF_FIELD_NUM ( 0x10B, blue_fuzz ) - CFF_FIELD_NUM ( 10, standard_width ) - CFF_FIELD_NUM ( 11, standard_height ) - CFF_FIELD_DELTA( 0x10C, snap_widths, 13 ) - CFF_FIELD_DELTA( 0x10D, snap_heights, 13 ) - CFF_FIELD_BOOL ( 0x10E, force_bold ) - CFF_FIELD_FIXED( 0x10F, force_bold_threshold ) - CFF_FIELD_NUM ( 0x110, lenIV ) - CFF_FIELD_NUM ( 0x111, language_group ) - CFF_FIELD_FIXED( 0x112, expansion_factor ) - CFF_FIELD_NUM ( 0x113, initial_random_seed ) - CFF_FIELD_NUM ( 19, local_subrs_offset ) - CFF_FIELD_NUM ( 20, default_width ) - CFF_FIELD_NUM ( 21, nominal_width ) + CFF_FIELD_DELTA ( 6, blue_values, 14 ) + CFF_FIELD_DELTA ( 7, other_blues, 10 ) + CFF_FIELD_DELTA ( 8, family_blues, 14 ) + CFF_FIELD_DELTA ( 9, family_other_blues, 10 ) + CFF_FIELD_FIXED_1000( 0x109, blue_scale ) + CFF_FIELD_NUM ( 0x10A, blue_shift ) + CFF_FIELD_NUM ( 0x10B, blue_fuzz ) + CFF_FIELD_NUM ( 10, standard_width ) + CFF_FIELD_NUM ( 11, standard_height ) + CFF_FIELD_DELTA ( 0x10C, snap_widths, 13 ) + CFF_FIELD_DELTA ( 0x10D, snap_heights, 13 ) + CFF_FIELD_BOOL ( 0x10E, force_bold ) + CFF_FIELD_FIXED ( 0x10F, force_bold_threshold ) + CFF_FIELD_NUM ( 0x110, lenIV ) + CFF_FIELD_NUM ( 0x111, language_group ) + CFF_FIELD_FIXED ( 0x112, expansion_factor ) + CFF_FIELD_NUM ( 0x113, initial_random_seed ) + CFF_FIELD_NUM ( 19, local_subrs_offset ) + CFF_FIELD_NUM ( 20, default_width ) + CFF_FIELD_NUM ( 21, nominal_width ) -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/internal/cfftypes.h b/src/libs/freetype2/cff/cfftypes.h similarity index 95% rename from headers/libs/freetype2/freetype/internal/cfftypes.h rename to src/libs/freetype2/cff/cfftypes.h index 81b1d3f61a..9ddc663dea 100644 --- a/headers/libs/freetype2/freetype/internal/cfftypes.h +++ b/src/libs/freetype2/cff/cfftypes.h @@ -5,7 +5,7 @@ /* Basic OpenType/CFF type definitions and interface (specification */ /* only). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -82,7 +82,8 @@ FT_BEGIN_HEADER FT_ULong offset; FT_UShort* sids; - + FT_UShort* cids; /* the inverse mapping of `sids'; only needed */ + /* for CID-keyed fonts */ } CFF_CharsetRec, *CFF_Charset; @@ -96,8 +97,8 @@ FT_BEGIN_HEADER FT_UInt weight; FT_Bool is_fixed_pitch; FT_Fixed italic_angle; - FT_Pos underline_position; - FT_Pos underline_thickness; + FT_Fixed underline_position; + FT_Fixed underline_thickness; FT_Int paint_type; FT_Int charstring_type; FT_Matrix font_matrix; @@ -113,8 +114,6 @@ FT_BEGIN_HEADER FT_ULong private_size; FT_Long synthetic_base; FT_UInt embedded_postscript; - FT_UInt base_font_name; - FT_UInt postscript; /* these should only be used for the top-level font dictionary */ FT_UInt cid_registry; @@ -124,7 +123,7 @@ FT_BEGIN_HEADER FT_Long cid_font_version; FT_Long cid_font_revision; FT_Long cid_font_type; - FT_Long cid_count; + FT_ULong cid_count; FT_ULong cid_uid_base; FT_ULong cid_fd_array_offset; FT_ULong cid_fd_select_offset; @@ -200,7 +199,7 @@ FT_BEGIN_HEADER /* maximum number of sub-fonts in a CID-keyed file */ -#define CFF_MAX_CID_FONTS 16 +#define CFF_MAX_CID_FONTS 32 typedef struct CFF_FontRec_ @@ -253,4 +252,4 @@ FT_END_HEADER #endif /* __CFFTYPES_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/cff/descrip.mms b/src/libs/freetype2/cff/descrip.mms index 99b509cc88..2401f2ee2b 100644 --- a/src/libs/freetype2/cff/descrip.mms +++ b/src/libs/freetype2/cff/descrip.mms @@ -20,4 +20,4 @@ OBJS=cff.obj all : $(OBJS) library [--.lib]freetype.olb $(OBJS) -# EOF +# EOF diff --git a/src/libs/freetype2/cff/module.mk b/src/libs/freetype2/cff/module.mk index 91a15322db..68789c98ac 100644 --- a/src/libs/freetype2/cff/module.mk +++ b/src/libs/freetype2/cff/module.mk @@ -19,4 +19,4 @@ add_cff_driver: $(OPEN_DRIVER)cff_driver_class$(CLOSE_DRIVER) $(ECHO_DRIVER)cff $(ECHO_DRIVER_DESC)OpenType fonts with extension *.otf$(ECHO_DRIVER_DONE) -# EOF +# EOF diff --git a/src/libs/freetype2/cff/rules.mk b/src/libs/freetype2/cff/rules.mk index 7dabd9a290..4100c80687 100644 --- a/src/libs/freetype2/cff/rules.mk +++ b/src/libs/freetype2/cff/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2001 by +# Copyright 1996-2000, 2001, 2003 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -15,27 +15,27 @@ # OpenType driver directory # -CFF_DIR := $(SRC_)cff -CFF_DIR_ := $(CFF_DIR)$(SEP) +CFF_DIR := $(SRC_DIR)/cff -CFF_COMPILE := $(FT_COMPILE) $I$(CFF_DIR) +CFF_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(CFF_DIR)) # CFF driver sources (i.e., C files) # -CFF_DRV_SRC := $(CFF_DIR_)cffobjs.c \ - $(CFF_DIR_)cffload.c \ - $(CFF_DIR_)cffgload.c \ - $(CFF_DIR_)cffparse.c \ - $(CFF_DIR_)cffcmap.c \ - $(CFF_DIR_)cffdrivr.c +CFF_DRV_SRC := $(CFF_DIR)/cffobjs.c \ + $(CFF_DIR)/cffload.c \ + $(CFF_DIR)/cffgload.c \ + $(CFF_DIR)/cffparse.c \ + $(CFF_DIR)/cffcmap.c \ + $(CFF_DIR)/cffdrivr.c # CFF driver headers # CFF_DRV_H := $(CFF_DRV_SRC:%.c=%.h) \ - $(CFF_DIR_)cfftoken.h \ - $(CFF_DIR_)cfferrs.h + $(CFF_DIR)/cfftoken.h \ + $(CFF_DIR)/cfftypes.h \ + $(CFF_DIR)/cfferrs.h # CFF driver object(s) @@ -43,24 +43,24 @@ CFF_DRV_H := $(CFF_DRV_SRC:%.c=%.h) \ # CFF_DRV_OBJ_M is used during `multi' builds # CFF_DRV_OBJ_S is used during `single' builds # -CFF_DRV_OBJ_M := $(CFF_DRV_SRC:$(CFF_DIR_)%.c=$(OBJ_)%.$O) -CFF_DRV_OBJ_S := $(OBJ_)cff.$O +CFF_DRV_OBJ_M := $(CFF_DRV_SRC:$(CFF_DIR)/%.c=$(OBJ_DIR)/%.$O) +CFF_DRV_OBJ_S := $(OBJ_DIR)/cff.$O # CFF driver source file for single build # -CFF_DRV_SRC_S := $(CFF_DIR_)cff.c +CFF_DRV_SRC_S := $(CFF_DIR)/cff.c # CFF driver - single object # $(CFF_DRV_OBJ_S): $(CFF_DRV_SRC_S) $(CFF_DRV_SRC) $(FREETYPE_H) $(CFF_DRV_H) - $(CFF_COMPILE) $T$@ $(CFF_DRV_SRC_S) + $(CFF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(CFF_DRV_SRC_S)) # CFF driver - multiple objects # -$(OBJ_)%.$O: $(CFF_DIR_)%.c $(FREETYPE_H) $(CFF_DRV_H) - $(CFF_COMPILE) $T$@ $< +$(OBJ_DIR)/%.$O: $(CFF_DIR)/%.c $(FREETYPE_H) $(CFF_DRV_H) + $(CFF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) # update main driver object lists @@ -68,4 +68,5 @@ $(OBJ_)%.$O: $(CFF_DIR_)%.c $(FREETYPE_H) $(CFF_DRV_H) DRV_OBJS_S += $(CFF_DRV_OBJ_S) DRV_OBJS_M += $(CFF_DRV_OBJ_M) -# EOF + +# EOF diff --git a/src/libs/freetype2/cid/ciderrs.h b/src/libs/freetype2/cid/ciderrs.h index 9972bf6fa4..01813e1898 100644 --- a/src/libs/freetype2/cid/ciderrs.h +++ b/src/libs/freetype2/cid/ciderrs.h @@ -37,4 +37,4 @@ #endif /* __CIDERRS_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/cid/cidgload.c b/src/libs/freetype2/cid/cidgload.c index 7596a784aa..3717eeb9e5 100644 --- a/src/libs/freetype2/cid/cidgload.c +++ b/src/libs/freetype2/cid/cidgload.c @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 Glyph Loader (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -40,15 +40,16 @@ cid_load_glyph( T1_Decoder decoder, FT_UInt glyph_index ) { - CID_Face face = (CID_Face)decoder->builder.face; - CID_FaceInfo cid = &face->cid; - FT_Byte* p; - FT_UInt fd_select; - FT_Stream stream = face->root.stream; - FT_Error error = 0; - FT_Byte* charstring = 0; - FT_Memory memory = face->root.memory; - FT_UInt glyph_length = 0; + CID_Face face = (CID_Face)decoder->builder.face; + CID_FaceInfo cid = &face->cid; + FT_Byte* p; + FT_UInt fd_select; + FT_Stream stream = face->cid_stream; + FT_Error error = 0; + FT_Byte* charstring = 0; + FT_Memory memory = face->root.memory; + FT_ULong glyph_length = 0; + PSAux_Service psaux = (PSAux_Service)face->psaux; #ifdef FT_CONFIG_OPTION_INCREMENTAL @@ -107,8 +108,7 @@ fd_select = (FT_UInt) cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); off1 = (FT_ULong)cid_get_offset( &p, (FT_Byte)cid->gd_bytes ); p += cid->fd_bytes; - glyph_length = (FT_UInt) cid_get_offset( - &p, (FT_Byte)cid->gd_bytes ) - off1; + glyph_length = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ) - off1; FT_FRAME_EXIT(); if ( glyph_length == 0 ) @@ -146,11 +146,11 @@ /* Decrypt only if lenIV >= 0. */ if ( decoder->lenIV >= 0 ) - cid_decrypt( charstring, glyph_length, 4330 ); + psaux->t1_decrypt( charstring, glyph_length, 4330 ); - error = decoder->funcs.parse_charstrings( decoder, - charstring + cs_offset, - glyph_length - cs_offset ); + error = decoder->funcs.parse_charstrings( + decoder, charstring + cs_offset, + (FT_Int)glyph_length - cs_offset ); } FT_FREE( charstring ); @@ -158,15 +158,16 @@ #ifdef FT_CONFIG_OPTION_INCREMENTAL /* Incremental fonts can optionally override the metrics. */ - if ( !error && - face->root.internal->incremental_interface && + if ( !error && + face->root.internal->incremental_interface && face->root.internal->incremental_interface->funcs->get_glyph_metrics ) { FT_Incremental_MetricsRec metrics; + metrics.bearing_x = decoder->builder.left_bearing.x; - metrics.bearing_y = decoder->builder.left_bearing.y; - metrics.advance = decoder->builder.advance.x; + metrics.bearing_y = decoder->builder.left_bearing.y; + metrics.advance = decoder->builder.advance.x; error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( face->root.internal->incremental_interface->object, glyph_index, FALSE, &metrics ); @@ -305,7 +306,7 @@ 0, /* glyph names -- XXX */ 0, /* blend == 0 */ hinting, - FT_LOAD_TARGET_MODE(load_flags), + FT_LOAD_TARGET_MODE( load_flags ), cid_load_glyph ); /* set up the decoder */ @@ -347,6 +348,7 @@ { FT_BBox cbox; FT_Glyph_Metrics* metrics = &glyph->root.metrics; + FT_Vector advance; /* copy the _unscaled_ advance width */ @@ -372,6 +374,15 @@ font_offset.x, font_offset.y ); + advance.x = metrics->horiAdvance; + advance.y = 0; + FT_Vector_Transform( &advance, &font_matrix ); + metrics->horiAdvance = advance.x + font_offset.x; + advance.x = 0; + advance.y = metrics->vertAdvance; + FT_Vector_Transform( &advance, &font_matrix ); + metrics->vertAdvance = advance.y + font_offset.y; + if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) { /* scale the outline and the metrics */ @@ -401,11 +412,11 @@ if ( hinting ) { - metrics->horiAdvance = ( metrics->horiAdvance + 32 ) & -64; - metrics->vertAdvance = ( metrics->vertAdvance + 32 ) & -64; + metrics->horiAdvance = FT_PIX_ROUND( metrics->horiAdvance ); + metrics->vertAdvance = FT_PIX_ROUND( metrics->vertAdvance ); - metrics->vertBearingX = ( metrics->vertBearingX + 32 ) & -64; - metrics->vertBearingY = ( metrics->vertBearingY + 32 ) & -64; + metrics->vertBearingX = FT_PIX_ROUND( metrics->vertBearingX ); + metrics->vertBearingY = FT_PIX_ROUND( metrics->vertBearingY ); } } @@ -415,10 +426,10 @@ /* grid fit the bounding box if necessary */ if ( hinting ) { - cbox.xMin &= -64; - cbox.yMin &= -64; - cbox.xMax = ( cbox.xMax + 63 ) & -64; - cbox.yMax = ( cbox.yMax + 63 ) & -64; + cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); + cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); + cbox.xMax = FT_PIX_CEIL( cbox.xMax ); + cbox.yMax = FT_PIX_CEIL( cbox.yMax ); } metrics->width = cbox.xMax - cbox.xMin; @@ -432,4 +443,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/cid/cidgload.h b/src/libs/freetype2/cid/cidgload.h index 3bac242582..93858e8650 100644 --- a/src/libs/freetype2/cid/cidgload.h +++ b/src/libs/freetype2/cid/cidgload.h @@ -48,4 +48,4 @@ FT_END_HEADER #endif /* __CIDGLOAD_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/cid/cidload.c b/src/libs/freetype2/cid/cidload.c index febeb9701c..ad29dd52d2 100644 --- a/src/libs/freetype2/cid/cidload.c +++ b/src/libs/freetype2/cid/cidload.c @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 font loader (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -39,7 +39,7 @@ /* read a single offset */ FT_LOCAL_DEF( FT_Long ) - cid_get_offset( FT_Byte** start, + cid_get_offset( FT_Byte* *start, FT_Byte offsize ) { FT_Long result; @@ -57,24 +57,6 @@ } - FT_LOCAL_DEF( void ) - cid_decrypt( FT_Byte* buffer, - FT_Offset length, - FT_UShort seed ) - { - while ( length > 0 ) - { - FT_Byte plain; - - - plain = (FT_Byte)( *buffer ^ ( seed >> 8 ) ); - seed = (FT_UShort)( ( *buffer + seed ) * 52845U + 22719 ); - *buffer++ = plain; - length--; - } - } - - /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -115,6 +97,10 @@ object = (FT_Byte*)&cid->font_info; break; + case T1_FIELD_LOCATION_BBOX: + object = (FT_Byte*)&cid->font_bbox; + break; + default: { CID_FaceDict dict; @@ -147,33 +133,15 @@ if ( keyword->type == T1_FIELD_TYPE_INTEGER_ARRAY || keyword->type == T1_FIELD_TYPE_FIXED_ARRAY ) error = cid_parser_load_field_table( &loader->parser, keyword, - &dummy_object ); + &dummy_object ); else - error = cid_parser_load_field( &loader->parser, keyword, &dummy_object ); + error = cid_parser_load_field( &loader->parser, + keyword, &dummy_object ); Exit: return error; } - FT_CALLBACK_DEF( FT_Error ) - parse_font_bbox( CID_Face face, - CID_Parser* parser ) - { - FT_Fixed temp[4]; - FT_BBox* bbox = &face->cid.font_bbox; - - - (void)cid_parser_to_fixed_array( parser, 4, temp, 0 ); - bbox->xMin = FT_RoundFix( temp[0] ); - bbox->yMin = FT_RoundFix( temp[1] ); - bbox->xMax = FT_RoundFix( temp[2] ); - bbox->yMax = FT_RoundFix( temp[3] ); - - return CID_Err_Ok; /* this is a callback function; */ - /* we must return an error code */ - } - - FT_CALLBACK_DEF( FT_Error ) parse_font_matrix( CID_Face face, CID_Parser* parser ) @@ -194,11 +162,11 @@ (void)cid_parser_to_fixed_array( parser, 6, temp, 3 ); - temp_scale = ABS( temp[3] ); + temp_scale = FT_ABS( temp[3] ); - /* Set Units per EM based on FontMatrix values. We set the value to */ + /* Set units per EM based on FontMatrix values. We set the value to */ /* `1000/temp_scale', because temp_scale was already multiplied by */ - /* 1000 (in t1_tofixed(), from psobjs.c). */ + /* 1000 (in `t1_tofixed', from psobjs.c). */ root->units_per_EM = (FT_UShort)( FT_DivFix( 0x10000L, FT_DivFix( temp_scale, 1000 ) ) ); @@ -223,7 +191,7 @@ offset->y = temp[5] >> 16; } - return CID_Err_Ok; /* this is a callback function; */ + return CID_Err_Ok; /* this is a callback function; */ /* we must return an error code */ } @@ -272,22 +240,13 @@ #include "cidtoken.h" - T1_FIELD_CALLBACK( "FontBBox", parse_font_bbox ) - T1_FIELD_CALLBACK( "FDArray", parse_fd_array ) + T1_FIELD_CALLBACK( "FDArray", parse_fd_array ) T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix ) + { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0 } }; - static int - is_alpha( char c ) - { - return ( ft_isalnum( (int)c ) || - c == '.' || - c == '_' ); - } - - static FT_Error cid_parse_dict( CID_Face face, CID_Loader* loader, @@ -299,44 +258,61 @@ parser->root.cursor = base; parser->root.limit = base + size; - parser->root.error = 0; + parser->root.error = CID_Err_Ok; { FT_Byte* cur = base; FT_Byte* limit = cur + size; - for ( ;cur < limit; cur++ ) + for (;;) { - /* look for `%ADOBeginFontDict' */ - if ( *cur == '%' && cur + 20 < limit && - ft_strncmp( (char*)cur, "%ADOBeginFontDict", 17 ) == 0 ) - { - cur += 17; + FT_Byte* newlimit; - /* if /FDArray was found, then cid->num_dicts is > 0, and */ - /* we can start increasing parser->num_dict */ - if ( face->cid.num_dicts > 0 ) - parser->num_dict++; - } - /* look for immediates */ - else if ( *cur == '/' && cur + 2 < limit ) + + parser->root.cursor = cur; + cid_parser_skip_spaces( parser ); + + if ( parser->root.cursor >= limit ) + newlimit = limit - 1 - 17; + else + newlimit = parser->root.cursor - 17; + + /* look for `%ADOBeginFontDict' */ + for ( ; cur < newlimit; cur++ ) { - FT_Byte* cur2; - FT_Int len; + if ( *cur == '%' && + ft_strncmp( (char*)cur, "%ADOBeginFontDict", 17 ) == 0 ) + { + /* if /FDArray was found, then cid->num_dicts is > 0, and */ + /* we can start increasing parser->num_dict */ + if ( face->cid.num_dicts > 0 ) + parser->num_dict++; + } + } + + cur = parser->root.cursor; + /* no error can occur in cid_parser_skip_spaces */ + if ( cur >= limit ) + break; + + cid_parser_skip_PS_token( parser ); + if ( parser->root.cursor >= limit || parser->root.error ) + break; + + /* look for immediates */ + if ( *cur == '/' && cur + 2 < limit ) + { + FT_PtrDist len; cur++; + len = parser->root.cursor - cur; - cur2 = cur; - while ( cur2 < limit && is_alpha( *cur2 ) ) - cur2++; - - len = (FT_Int)( cur2 - cur ); if ( len > 0 && len < 22 ) { /* now compare the immediate name to the keyword table */ - T1_Field keyword = (T1_Field) cid_field_records; + T1_Field keyword = (T1_Field)cid_field_records; for (;;) @@ -348,10 +324,10 @@ if ( !name ) break; - if ( cur[0] == name[0] && - len == (FT_Int)ft_strlen( (const char*)name ) ) + if ( cur[0] == name[0] && + len == ft_strlen( (const char*)name ) ) { - FT_Int n; + FT_PtrDist n; for ( n = 1; n < len; n++ ) @@ -361,15 +337,11 @@ if ( n >= len ) { /* we found it - run the parsing callback */ - parser->root.cursor = cur2; - cid_parser_skip_spaces( parser ); parser->root.error = cid_load_keyword( face, loader, keyword ); if ( parser->root.error ) return parser->root.error; - - cur = parser->root.cursor; break; } } @@ -377,6 +349,8 @@ } } } + + cur = parser->root.cursor; } } return parser->root.error; @@ -387,14 +361,15 @@ static FT_Error cid_read_subrs( CID_Face face ) { - CID_FaceInfo cid = &face->cid; - FT_Memory memory = face->root.memory; - FT_Stream stream = face->root.stream; - FT_Error error; - FT_Int n; - CID_Subrs subr; - FT_UInt max_offsets = 0; - FT_ULong* offsets = 0; + CID_FaceInfo cid = &face->cid; + FT_Memory memory = face->root.memory; + FT_Stream stream = face->cid_stream; + FT_Error error; + FT_Int n; + CID_Subrs subr; + FT_UInt max_offsets = 0; + FT_ULong* offsets = 0; + PSAux_Service psaux = (PSAux_Service)face->psaux; if ( FT_NEW_ARRAY( face->subrs, cid->num_dicts ) ) @@ -413,7 +388,7 @@ /* reallocate offsets array if needed */ if ( num_subrs + 1 > max_offsets ) { - FT_UInt new_max = ( num_subrs + 1 + 3 ) & -4; + FT_UInt new_max = FT_PAD_CEIL( num_subrs + 1, 4 ); if ( FT_RENEW_ARRAY( offsets, max_offsets, new_max ) ) @@ -424,7 +399,7 @@ /* read the subrmap's offsets */ if ( FT_STREAM_SEEK( cid->data_offset + dict->subrmap_offset ) || - FT_FRAME_ENTER( ( num_subrs + 1 ) * dict->sd_bytes ) ) + FT_FRAME_ENTER( ( num_subrs + 1 ) * dict->sd_bytes ) ) goto Fail; p = (FT_Byte*)stream->cursor; @@ -464,7 +439,7 @@ len = offsets[count + 1] - offsets[count]; - cid_decrypt( subr->code[count], len, 4330 ); + psaux->t1_decrypt( subr->code[count], len, 4330 ); } } @@ -512,11 +487,111 @@ } + static FT_Error + cid_hex_to_binary( FT_Byte* data, + FT_Long data_len, + FT_ULong offset, + CID_Face face ) + { + FT_Stream stream = face->root.stream; + FT_Error error; + + FT_Byte buffer[256]; + FT_Byte *p, *plimit; + FT_Byte *d, *dlimit; + FT_Byte val; + + FT_Bool upper_nibble, done; + + + if ( FT_STREAM_SEEK( offset ) ) + goto Exit; + + d = data; + dlimit = d + data_len; + p = buffer; + plimit = p; + + upper_nibble = 1; + done = 0; + + while ( d < dlimit ) + { + if ( p >= plimit ) + { + FT_ULong oldpos = FT_STREAM_POS(); + FT_ULong size = stream->size - oldpos; + + + if ( size == 0 ) + { + error = CID_Err_Syntax_Error; + goto Exit; + } + + if ( FT_STREAM_READ( buffer, 256 > size ? size : 256 ) ) + goto Exit; + p = buffer; + plimit = p + FT_STREAM_POS() - oldpos; + } + + if ( ft_isdigit( *p ) ) + val = *p - '0'; + else if ( *p >= 'a' && *p <= 'f' ) + val = *p - 'a'; + else if ( *p >= 'A' && *p <= 'F' ) + val = *p - 'A' + 10; + else if ( *p == ' ' || + *p == '\t' || + *p == '\r' || + *p == '\n' || + *p == '\f' || + *p == '\0' ) + { + p++; + continue; + } + else if ( *p == '>' ) + { + val = 0; + done = 1; + } + else + { + error = CID_Err_Syntax_Error; + goto Exit; + } + + if ( upper_nibble ) + *d = val << 4; + else + { + *d += val; + d++; + } + + upper_nibble = 1 - upper_nibble; + + if ( done ) + break; + + p++; + } + + error = CID_Err_Ok; + + Exit: + return error; + } + + FT_LOCAL_DEF( FT_Error ) - cid_face_open( CID_Face face ) + cid_face_open( CID_Face face, + FT_Int face_index ) { CID_Loader loader; CID_Parser* parser; + FT_Memory memory = face->root.memory; FT_Error error; @@ -534,7 +609,30 @@ if ( error ) goto Exit; - face->cid.data_offset = loader.parser.data_offset; + if ( face_index < 0 ) + goto Exit; + + if ( FT_NEW( face->cid_stream ) ) + goto Exit; + + if ( parser->binary_length ) + { + /* we must convert the data section from hexadecimal to binary */ + if ( FT_ALLOC( face->binary_data, parser->binary_length ) || + cid_hex_to_binary( face->binary_data, parser->binary_length, + parser->data_offset, face ) ) + goto Exit; + + FT_Stream_OpenMemory( face->cid_stream, + face->binary_data, parser->binary_length ); + face->cid.data_offset = 0; + } + else + { + *face->cid_stream = *face->root.stream; + face->cid.data_offset = loader.parser.data_offset; + } + error = cid_read_subrs( face ); Exit: @@ -543,4 +641,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/cid/cidload.h b/src/libs/freetype2/cid/cidload.h index b92ca7ed29..8c172ffee2 100644 --- a/src/libs/freetype2/cid/cidload.h +++ b/src/libs/freetype2/cid/cidload.h @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 font loader (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -40,13 +40,9 @@ FT_BEGIN_HEADER cid_get_offset( FT_Byte** start, FT_Byte offsize ); - FT_LOCAL( void ) - cid_decrypt( FT_Byte* buffer, - FT_Offset length, - FT_UShort seed ); - FT_LOCAL( FT_Error ) - cid_face_open( CID_Face face ); + cid_face_open( CID_Face face, + FT_Int face_index ); FT_END_HEADER @@ -54,4 +50,4 @@ FT_END_HEADER #endif /* __CIDLOAD_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/cid/cidobjs.c b/src/libs/freetype2/cid/cidobjs.c index d8776cb342..356d01805a 100644 --- a/src/libs/freetype2/cid/cidobjs.c +++ b/src/libs/freetype2/cid/cidobjs.c @@ -4,7 +4,7 @@ /* */ /* CID objects manager (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,9 +19,11 @@ #include <ft2build.h> #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H + #include "cidgload.h" #include "cidload.h" -#include FT_INTERNAL_POSTSCRIPT_NAMES_H + +#include FT_SERVICE_POSTSCRIPT_CMAPS_H #include FT_INTERNAL_POSTSCRIPT_AUX_H #include FT_INTERNAL_POSTSCRIPT_HINTS_H @@ -197,12 +199,12 @@ if ( face->subrs ) { FT_Int n; - + for ( n = 0; n < cid->num_dicts; n++ ) { CID_Subrs subr = face->subrs + n; - + if ( subr->code ) { @@ -232,6 +234,9 @@ face->root.family_name = 0; face->root.style_name = 0; + + FT_FREE( face->binary_data ); + FT_FREE( face->cid_stream ); } } @@ -266,27 +271,19 @@ FT_Int num_params, FT_Parameter* params ) { - FT_Error error; - PSNames_Service psnames; - PSAux_Service psaux; - PSHinter_Service pshinter; + FT_Error error; + FT_Service_PsCMaps psnames; + PSAux_Service psaux; + PSHinter_Service pshinter; FT_UNUSED( num_params ); FT_UNUSED( params ); - FT_UNUSED( face_index ); FT_UNUSED( stream ); face->root.num_faces = 1; - psnames = (PSNames_Service)face->psnames; - if ( !psnames ) - { - psnames = (PSNames_Service)FT_Get_Module_Interface( - FT_FACE_LIBRARY( face ), "psnames" ); - - face->psnames = psnames; - } + FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); psaux = (PSAux_Service)face->psaux; if ( !psaux ) @@ -310,7 +307,7 @@ if ( FT_STREAM_SEEK( 0 ) ) goto Exit; - error = cid_face_open( face ); + error = cid_face_open( face, face_index ); if ( error ) goto Exit; @@ -326,77 +323,106 @@ goto Exit; } - /* Now, load the font program into the face object */ + /* now load the font program into the face object */ + + /* initialize the face object fields */ + + /* set up root face fields */ { - /* Init the face object fields */ - /* Now set up root face fields */ + FT_Face root = (FT_Face)&face->root; + CID_FaceInfo cid = &face->cid; + PS_FontInfo info = &cid->font_info; + + + root->num_glyphs = cid->cid_count; + root->num_charmaps = 0; + + root->face_index = face_index; + root->face_flags = FT_FACE_FLAG_SCALABLE; + + root->face_flags |= FT_FACE_FLAG_HORIZONTAL; + + if ( info->is_fixed_pitch ) + root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; + + /* XXX: TODO: add kerning with .afm support */ + + /* get style name -- be careful, some broken fonts only */ + /* have a /FontName dictionary entry! */ + root->family_name = info->family_name; + /* assume "Regular" style if we don't know better */ + root->style_name = (char *)"Regular"; + if ( root->family_name ) { - FT_Face root = (FT_Face)&face->root; + char* full = info->full_name; + char* family = root->family_name; - root->num_glyphs = face->cid.cid_count; - root->num_charmaps = 0; - - root->face_index = face_index; - root->face_flags = FT_FACE_FLAG_SCALABLE; - - root->face_flags |= FT_FACE_FLAG_HORIZONTAL; - - if ( face->cid.font_info.is_fixed_pitch ) - root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; - - /* XXX: TODO: add kerning with .afm support */ - - /* get style name -- be careful, some broken fonts only */ - /* have a /FontName dictionary entry! */ - root->family_name = face->cid.font_info.family_name; - if ( root->family_name ) + if ( full ) { - char* full = face->cid.font_info.full_name; - char* family = root->family_name; - - while ( *family && *full == *family ) + while ( *full ) { - family++; - full++; - } - - root->style_name = ( *full == ' ' ) ? full + 1 - : (char *)"Regular"; - } - else - { - /* do we have a `/FontName'? */ - if ( face->cid.cid_font_name ) - { - root->family_name = face->cid.cid_font_name; - root->style_name = (char *)"Regular"; + if ( *full == *family ) + { + family++; + full++; + } + else + { + if ( *full == ' ' || *full == '-' ) + full++; + else if ( *family == ' ' || *family == '-' ) + family++; + else + { + if ( !*family ) + root->style_name = full; + break; + } + } } } - - /* no embedded bitmap support */ - root->num_fixed_sizes = 0; - root->available_sizes = 0; - - root->bbox.xMin = face->cid.font_bbox.xMin >> 16; - root->bbox.yMin = face->cid.font_bbox.yMin >> 16; - root->bbox.xMax = ( face->cid.font_bbox.xMax + 0xFFFFU ) >> 16; - root->bbox.yMax = ( face->cid.font_bbox.yMax + 0xFFFFU ) >> 16; - - if ( !root->units_per_EM ) - root->units_per_EM = 1000; - - root->ascender = (FT_Short)( root->bbox.yMax ); - root->descender = (FT_Short)( root->bbox.yMin ); - root->height = (FT_Short)( - ( ( root->ascender + root->descender ) * 12 ) / 10 ); - - root->underline_position = face->cid.font_info.underline_position; - root->underline_thickness = face->cid.font_info.underline_thickness; - - root->internal->max_points = 0; - root->internal->max_contours = 0; } + else + { + /* do we have a `/FontName'? */ + if ( cid->cid_font_name ) + root->family_name = cid->cid_font_name; + } + + /* compute style flags */ + root->style_flags = 0; + if ( info->italic_angle ) + root->style_flags |= FT_STYLE_FLAG_ITALIC; + if ( info->weight ) + { + if ( !ft_strcmp( info->weight, "Bold" ) || + !ft_strcmp( info->weight, "Black" ) ) + root->style_flags |= FT_STYLE_FLAG_BOLD; + } + + /* no embedded bitmap support */ + root->num_fixed_sizes = 0; + root->available_sizes = 0; + + root->bbox.xMin = cid->font_bbox.xMin >> 16; + root->bbox.yMin = cid->font_bbox.yMin >> 16; + root->bbox.xMax = ( cid->font_bbox.xMax + 0xFFFFU ) >> 16; + root->bbox.yMax = ( cid->font_bbox.yMax + 0xFFFFU ) >> 16; + + if ( !root->units_per_EM ) + root->units_per_EM = 1000; + + root->ascender = (FT_Short)( root->bbox.yMax ); + root->descender = (FT_Short)( root->bbox.yMin ); + root->height = (FT_Short)( + ( ( root->ascender - root->descender ) * 12 ) / 10 ); + + root->underline_position = (FT_Short)info->underline_position; + root->underline_thickness = (FT_Short)info->underline_thickness; + + root->internal->max_points = 0; + root->internal->max_contours = 0; } Exit: @@ -445,4 +471,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/cid/cidobjs.h b/src/libs/freetype2/cid/cidobjs.h index eb2f1d747d..2d72d73e2f 100644 --- a/src/libs/freetype2/cid/cidobjs.h +++ b/src/libs/freetype2/cid/cidobjs.h @@ -155,4 +155,4 @@ FT_END_HEADER #endif /* __CIDOBJS_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/cid/cidparse.c b/src/libs/freetype2/cid/cidparse.c index a3ce61a998..3f18749f60 100644 --- a/src/libs/freetype2/cid/cidparse.c +++ b/src/libs/freetype2/cid/cidparse.c @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 parser (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -58,6 +58,8 @@ FT_ULong base_offset, offset, ps_len; FT_Byte buffer[256 + 10]; FT_Int buff_len; + FT_Byte *cur, *limit; + FT_Byte *arg1, *arg2; FT_MEM_ZERO( parser, sizeof ( *parser ) ); @@ -67,7 +69,7 @@ base_offset = FT_STREAM_POS(); - /* first of all, check the font format in the header */ + /* first of all, check the font format in the header */ if ( FT_FRAME_ENTER( 31 ) ) goto Exit; @@ -82,15 +84,17 @@ if ( error ) goto Exit; - /* now, read the rest of the file, until we find a `StartData' */ + Again: + /* now, read the rest of the file until we find a `StartData' */ buff_len = 256; for (;;) { - FT_Byte *p, *limit = buffer + 256; + FT_Byte* p; FT_ULong top_position; /* fill input buffer */ + limit = buffer + 256; buff_len -= 256; if ( buff_len > 0 ) FT_MEM_MOVE( buffer, limit, buff_len ); @@ -101,7 +105,7 @@ goto Exit; top_position = FT_STREAM_POS() - buff_len; - buff_len = 256 + 10; + buff_len = 256 + 10; /* look for `StartData' */ for ( p = buffer; p < limit; p++ ) @@ -116,12 +120,12 @@ } Found: - /* we have found the start of the binary data. We will now */ - /* rewind and extract the frame of corresponding to the Postscript */ - /* section */ + /* we have found the start of the binary data. We will now */ + /* rewind and extract the frame corresponding to the PostScript */ + /* section */ ps_len = offset - base_offset; - if ( FT_STREAM_SEEK( base_offset ) || + if ( FT_STREAM_SEEK( base_offset ) || FT_FRAME_EXTRACT( ps_len, parser->postscript ) ) goto Exit; @@ -132,6 +136,45 @@ parser->root.limit = parser->root.cursor + ps_len; parser->num_dict = -1; + /* Finally, we check whether `StartData' was real -- it could be */ + /* in a comment or string. We also get its arguments to find out */ + /* whether the data is represented in binary or hex format. */ + + arg1 = parser->root.cursor; + cid_parser_skip_PS_token( parser ); + cid_parser_skip_spaces ( parser ); + arg2 = parser->root.cursor; + cid_parser_skip_PS_token( parser ); + cid_parser_skip_spaces ( parser ); + + limit = parser->root.limit; + cur = parser->root.cursor; + + while ( cur < limit ) + { + if ( *cur == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 ) + { + if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 ) + parser->binary_length = ft_atol( (const char *)arg2 ); + + limit = parser->root.limit; + cur = parser->root.cursor; + goto Exit; + } + + cid_parser_skip_PS_token( parser ); + cid_parser_skip_spaces ( parser ); + arg1 = arg2; + arg2 = cur; + cur = parser->root.cursor; + } + + /* we haven't found the correct `StartData'; go back and continue */ + /* searching */ + FT_FRAME_RELEASE( parser->postscript ); + if ( !FT_STREAM_SEEK( offset ) ) + goto Again; + Exit: return error; } @@ -152,4 +195,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/cid/cidparse.h b/src/libs/freetype2/cid/cidparse.h index cb97ea0a75..ca37deab93 100644 --- a/src/libs/freetype2/cid/cidparse.h +++ b/src/libs/freetype2/cid/cidparse.h @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 parser (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -50,6 +50,9 @@ FT_BEGIN_HEADER /* data_offset :: The start position of the binary data (i.e., the */ /* end of the data to be parsed. */ /* */ + /* binary_length :: The length of the data after the `StartData' */ + /* command if the data format is hexadecimal. */ + /* */ /* cid :: A structure which holds the information about */ /* the current font. */ /* */ @@ -65,6 +68,8 @@ FT_BEGIN_HEADER FT_ULong data_offset; + FT_Long binary_length; + CID_FaceInfo cid; FT_Int num_dict; @@ -87,8 +92,10 @@ FT_BEGIN_HEADER /* */ /*************************************************************************/ -#define cid_parser_skip_spaces( p ) (p)->root.funcs.skip_spaces( &(p)->root ) -#define cid_parser_skip_alpha( p ) (p)->root.funcs.skip_alpha ( &(p)->root ) +#define cid_parser_skip_spaces( p ) \ + (p)->root.funcs.skip_spaces( &(p)->root ) +#define cid_parser_skip_PS_token( p ) \ + (p)->root.funcs.skip_PS_token( &(p)->root ) #define cid_parser_to_int( p ) (p)->root.funcs.to_int( &(p)->root ) #define cid_parser_to_fixed( p, t ) (p)->root.funcs.to_fixed( &(p)->root, t ) @@ -113,4 +120,4 @@ FT_END_HEADER #endif /* __CIDPARSE_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/cid/cidriver.c b/src/libs/freetype2/cid/cidriver.c index a36e3251de..f5639b9f76 100644 --- a/src/libs/freetype2/cid/cidriver.c +++ b/src/libs/freetype2/cid/cidriver.c @@ -4,7 +4,7 @@ /* */ /* CID driver interface (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,10 +21,12 @@ #include "cidgload.h" #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_POSTSCRIPT_NAMES_H #include "ciderrs.h" +#include FT_SERVICE_POSTSCRIPT_NAME_H +#include FT_SERVICE_XFREE86_NAME_H +#include FT_SERVICE_POSTSCRIPT_INFO_H /*************************************************************************/ /* */ @@ -36,6 +38,11 @@ #define FT_COMPONENT trace_ciddriver + /* + * POSTSCRIPT NAME SERVICE + * + */ + static const char* cid_get_postscript_name( CID_Face face ) { @@ -49,6 +56,47 @@ } + static const FT_Service_PsFontNameRec cid_service_ps_name = + { + (FT_PsName_GetFunc) cid_get_postscript_name + }; + + + /* + * POSTSCRIPT INFO SERVICE + * + */ + + static FT_Error + cid_ps_get_font_info( FT_Face face, + PS_FontInfoRec* afont_info ) + { + *afont_info = ((CID_Face)face)->cid.font_info; + return 0; + } + + + static const FT_Service_PsInfoRec cid_service_ps_info = + { + (PS_GetFontInfoFunc) cid_ps_get_font_info, + (PS_HasGlyphNamesFunc)NULL /* unsupported with CID fonts */ + }; + + + /* + * SERVICE LIST + * + */ + + static const FT_ServiceDescRec cid_services[] = + { + { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cid_service_ps_name }, + { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CID }, + { FT_SERVICE_ID_POSTSCRIPT_INFO, &cid_service_ps_info }, + { NULL, NULL } + }; + + static FT_Module_Interface cid_get_interface( FT_Driver driver, const FT_String* cid_interface ) @@ -56,10 +104,7 @@ FT_UNUSED( driver ); FT_UNUSED( cid_interface ); - if ( ft_strcmp( (const char*)cid_interface, "postscript_name" ) == 0 ) - return (FT_Module_Interface)cid_get_postscript_name; - - return 0; + return ft_service_list_lookup( cid_services, cid_interface ); } @@ -69,9 +114,9 @@ { /* first of all, the FT_Module_Class fields */ { - ft_module_font_driver | - ft_module_driver_scalable | - ft_module_driver_has_hinter , + FT_MODULE_FONT_DRIVER | + FT_MODULE_DRIVER_SCALABLE | + FT_MODULE_DRIVER_HAS_HINTER, sizeof( FT_DriverRec ), "t1cid", /* module name */ @@ -110,4 +155,4 @@ }; -/* END */ +/* END */ diff --git a/src/libs/freetype2/cid/cidriver.h b/src/libs/freetype2/cid/cidriver.h index 2327b514e4..d5a80f6f9f 100644 --- a/src/libs/freetype2/cid/cidriver.h +++ b/src/libs/freetype2/cid/cidriver.h @@ -36,4 +36,4 @@ FT_END_HEADER #endif /* __CIDRIVER_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/cid/cidtoken.h b/src/libs/freetype2/cid/cidtoken.h index ca08ca0361..2070aa91bb 100644 --- a/src/libs/freetype2/cid/cidtoken.h +++ b/src/libs/freetype2/cid/cidtoken.h @@ -4,7 +4,7 @@ /* */ /* CID token definitions (specification only). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,7 +21,7 @@ #undef T1CODE #define T1CODE T1_FIELD_LOCATION_CID_INFO - T1_FIELD_STRING( "CIDFontName", cid_font_name ) + T1_FIELD_KEY ( "CIDFontName", cid_font_name ) T1_FIELD_NUM ( "CIDFontVersion", cid_version ) T1_FIELD_NUM ( "CIDFontType", cid_font_type ) T1_FIELD_STRING( "Registry", registry ) @@ -39,15 +39,15 @@ #undef T1CODE #define T1CODE T1_FIELD_LOCATION_FONT_INFO - T1_FIELD_STRING ( "version", version ) - T1_FIELD_STRING ( "Notice", notice ) - T1_FIELD_STRING ( "FullName", full_name ) - T1_FIELD_STRING ( "FamilyName", family_name ) - T1_FIELD_STRING ( "Weight", weight ) - T1_FIELD_FIXED ( "ItalicAngle", italic_angle ) - T1_FIELD_TYPE_BOOL( "isFixedPitch", is_fixed_pitch ) - T1_FIELD_NUM ( "UnderlinePosition", underline_position ) - T1_FIELD_NUM ( "UnderlineThickness", underline_thickness ) + T1_FIELD_STRING( "version", version ) + T1_FIELD_STRING( "Notice", notice ) + T1_FIELD_STRING( "FullName", full_name ) + T1_FIELD_STRING( "FamilyName", family_name ) + T1_FIELD_STRING( "Weight", weight ) + T1_FIELD_NUM ( "ItalicAngle", italic_angle ) + T1_FIELD_BOOL ( "isFixedPitch", is_fixed_pitch ) + T1_FIELD_NUM ( "UnderlinePosition", underline_position ) + T1_FIELD_NUM ( "UnderlineThickness", underline_thickness ) #undef FT_STRUCTURE @@ -63,7 +63,7 @@ T1_FIELD_NUM ( "lenBuildCharArray", len_buildchar ) T1_FIELD_FIXED( "ForceBoldThreshold", forcebold_threshold ) T1_FIELD_FIXED( "ExpansionFactor", expansion_factor ) - T1_FIELD_NUM ( "StrokeWidth", stroke_width ) + T1_FIELD_FIXED( "StrokeWidth", stroke_width ) #undef FT_STRUCTURE @@ -76,7 +76,7 @@ T1_FIELD_NUM ( "LanguageGroup", language_group ) T1_FIELD_NUM ( "password", password ) - T1_FIELD_FIXED ( "BlueScale", blue_scale ) + T1_FIELD_FIXED_1000( "BlueScale", blue_scale ) T1_FIELD_NUM ( "BlueShift", blue_shift ) T1_FIELD_NUM ( "BlueFuzz", blue_fuzz ) @@ -92,5 +92,12 @@ T1_FIELD_NUM_TABLE ( "StemSnapH", snap_widths, 12 ) T1_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12 ) +#undef FT_STRUCTURE +#define FT_STRUCTURE FT_BBox +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_BBOX -/* END */ + T1_FIELD_BBOX( "FontBBox", xMin ) + + +/* END */ diff --git a/src/libs/freetype2/cid/descrip.mms b/src/libs/freetype2/cid/descrip.mms index a252ad1263..592fd587a7 100644 --- a/src/libs/freetype2/cid/descrip.mms +++ b/src/libs/freetype2/cid/descrip.mms @@ -20,4 +20,4 @@ OBJS=type1cid.obj all : $(OBJS) library [--.lib]freetype.olb $(OBJS) -# EOF +# EOF diff --git a/src/libs/freetype2/cid/module.mk b/src/libs/freetype2/cid/module.mk index a8bd687f4d..f59d8a9516 100644 --- a/src/libs/freetype2/cid/module.mk +++ b/src/libs/freetype2/cid/module.mk @@ -18,4 +18,4 @@ make_module_list: add_type1cid_driver add_type1cid_driver: $(OPEN_DRIVER)t1cid_driver_class$(CLOSE_DRIVER) $(ECHO_DRIVER)cid $(ECHO_DRIVER_DESC)Postscript CID-keyed fonts, no known extension$(ECHO_DRIVER_DONE) -# EOF +# EOF diff --git a/src/libs/freetype2/cid/rules.mk b/src/libs/freetype2/cid/rules.mk index bbfff9a03c..f362744612 100644 --- a/src/libs/freetype2/cid/rules.mk +++ b/src/libs/freetype2/cid/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2001 by +# Copyright 1996-2000, 2001, 2003 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -15,26 +15,25 @@ # CID driver directory # -CID_DIR := $(SRC_)cid -CID_DIR_ := $(CID_DIR)$(SEP) +CID_DIR := $(SRC_DIR)/cid -CID_COMPILE := $(FT_COMPILE) $I$(CID_DIR) +CID_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(CID_DIR)) # CID driver sources (i.e., C files) # -CID_DRV_SRC := $(CID_DIR_)cidparse.c \ - $(CID_DIR_)cidload.c \ - $(CID_DIR_)cidriver.c \ - $(CID_DIR_)cidgload.c \ - $(CID_DIR_)cidobjs.c +CID_DRV_SRC := $(CID_DIR)/cidparse.c \ + $(CID_DIR)/cidload.c \ + $(CID_DIR)/cidriver.c \ + $(CID_DIR)/cidgload.c \ + $(CID_DIR)/cidobjs.c # CID driver headers # CID_DRV_H := $(CID_DRV_SRC:%.c=%.h) \ - $(CID_DIR_)cidtoken.h \ - $(CID_DIR_)ciderrs.h + $(CID_DIR)/cidtoken.h \ + $(CID_DIR)/ciderrs.h # CID driver object(s) @@ -42,24 +41,24 @@ CID_DRV_H := $(CID_DRV_SRC:%.c=%.h) \ # CID_DRV_OBJ_M is used during `multi' builds # CID_DRV_OBJ_S is used during `single' builds # -CID_DRV_OBJ_M := $(CID_DRV_SRC:$(CID_DIR_)%.c=$(OBJ_)%.$O) -CID_DRV_OBJ_S := $(OBJ_)type1cid.$O +CID_DRV_OBJ_M := $(CID_DRV_SRC:$(CID_DIR)/%.c=$(OBJ_DIR)/%.$O) +CID_DRV_OBJ_S := $(OBJ_DIR)/type1cid.$O # CID driver source file for single build # -CID_DRV_SRC_S := $(CID_DIR_)type1cid.c +CID_DRV_SRC_S := $(CID_DIR)/type1cid.c # CID driver - single object # $(CID_DRV_OBJ_S): $(CID_DRV_SRC_S) $(CID_DRV_SRC) $(FREETYPE_H) $(CID_DRV_H) - $(CID_COMPILE) $T$@ $(CID_DRV_SRC_S) + $(CID_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(CID_DRV_SRC_S)) # CID driver - multiple objects # -$(OBJ_)%.$O: $(CID_DIR_)%.c $(FREETYPE_H) $(CID_DRV_H) - $(CID_COMPILE) $T$@ $< +$(OBJ_DIR)/%.$O: $(CID_DIR)/%.c $(FREETYPE_H) $(CID_DRV_H) + $(CID_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) # update main driver object lists @@ -67,4 +66,5 @@ $(OBJ_)%.$O: $(CID_DIR_)%.c $(FREETYPE_H) $(CID_DRV_H) DRV_OBJS_S += $(CID_DRV_OBJ_S) DRV_OBJS_M += $(CID_DRV_OBJ_M) -# EOF + +# EOF diff --git a/src/libs/freetype2/cid/type1cid.c b/src/libs/freetype2/cid/type1cid.c index 2897a9614d..0b866e97c4 100644 --- a/src/libs/freetype2/cid/type1cid.c +++ b/src/libs/freetype2/cid/type1cid.c @@ -26,4 +26,4 @@ #include "cidgload.c" -/* END */ +/* END */ diff --git a/src/libs/freetype2/gzip/adler32.c b/src/libs/freetype2/gzip/adler32.c index 09ed8d7e69..bd47f73093 100644 --- a/src/libs/freetype2/gzip/adler32.c +++ b/src/libs/freetype2/gzip/adler32.c @@ -3,7 +3,7 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id: adler32.c,v 1.2 2003/07/24 18:52:52 darkwyrm Exp $ */ +/* @(#) $Id: adler32.c,v 1.3 2004/06/22 14:01:14 darkwyrm Exp $ */ #include "zlib.h" @@ -45,4 +45,4 @@ ZEXPORT(uLong) adler32( /* adler, buf, len) */ s2 %= BASE; } return (s2 << 16) | s1; -} +} diff --git a/src/libs/freetype2/gzip/descrip.mms b/src/libs/freetype2/gzip/descrip.mms index f036e6c07f..68d7a870d6 100644 --- a/src/libs/freetype2/gzip/descrip.mms +++ b/src/libs/freetype2/gzip/descrip.mms @@ -20,4 +20,4 @@ OBJS=ftgzip.obj all : $(OBJS) library [--.lib]freetype.olb $(OBJS) -# EOF +# EOF diff --git a/src/libs/freetype2/gzip/ftgzip.c b/src/libs/freetype2/gzip/ftgzip.c index f1053c252b..e35c07385b 100644 --- a/src/libs/freetype2/gzip/ftgzip.c +++ b/src/libs/freetype2/gzip/ftgzip.c @@ -2,13 +2,13 @@ /* */ /* ftgzip.c */ /* */ -/* FreeType support for .gz compressed fileds */ +/* FreeType support for .gz compressed files. */ /* */ -/* this optional component relies on zlib. It should mainly be used to */ +/* This optional component relies on zlib. It should mainly be used to */ /* parse compressed PCF fonts, as found with many X11 server */ /* distributions. */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,45 +19,67 @@ /* */ /***************************************************************************/ + #include <ft2build.h> #include FT_INTERNAL_MEMORY_H #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_DEBUG_H #include <string.h> + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX Gzip_Err_ +#define FT_ERR_BASE FT_Mod_Err_Gzip + +#include FT_ERRORS_H + + #ifdef FT_CONFIG_OPTION_USE_ZLIB #ifdef FT_CONFIG_OPTION_SYSTEM_ZLIB -# include <zlib.h> +#include <zlib.h> -#else /* !SYSTEM_ZLIB */ +#else /* !FT_CONFIG_OPTION_SYSTEM_ZLIB */ - /* in this case, we include our own modified sources of the ZLib */ - /* within the "ftgzip" component. The modifications were necessary */ - /* to #include all files without conflicts, as well as preventing */ - /* the definition of "extern" functions that may cause linking */ - /* conflicts when a program is linked with both FreeType and the */ - /* original ZLib */ + /* In this case, we include our own modified sources of the ZLib */ + /* within the "ftgzip" component. The modifications were necessary */ + /* to #include all files without conflicts, as well as preventing */ + /* the definition of "extern" functions that may cause linking */ + /* conflicts when a program is linked with both FreeType and the */ + /* original ZLib. */ -# define NO_DUMMY_DECL -# define BUILDFIXED /* save code size */ -# define MY_ZCALLOC +#define NO_DUMMY_DECL +#define MY_ZCALLOC -# include "zlib.h" +#include "zlib.h" -# undef SLOW -# define SLOW 1 /* we can't use asm-optimized sources here !! */ +#undef SLOW +#define SLOW 1 /* we can't use asm-optimized sources here! */ -# include "zutil.c" -# include "inftrees.c" -# include "infcodes.c" -# include "infutil.c" -# include "infblock.c" -# include "inflate.c" -# include "adler32.c" + /* Urgh. `inflate_mask' must not be declared twice -- C++ doesn't like + this. We temporarily disable it and load all necessary header files. */ +#define NO_INFLATE_MASK +#include "zutil.h" +#include "inftrees.h" +#include "infblock.h" +#include "infcodes.h" +#include "infutil.h" +#undef NO_INFLATE_MASK -#endif /* !SYSTEM_ZLIB */ + /* infutil.c must be included before infcodes.c */ +#include "zutil.c" +#include "inftrees.c" +#include "infutil.c" +#include "infcodes.c" +#include "infblock.c" +#include "inflate.c" +#include "adler32.c" + +#endif /* !FT_CONFIG_OPTION_SYSTEM_ZLIB */ /***************************************************************************/ @@ -68,48 +90,48 @@ /***************************************************************************/ /***************************************************************************/ - /* it's better to use FreeType memory routines instead of raw 'malloc/free' */ + /* it is better to use FreeType memory routines instead of raw + 'malloc/free' */ + + static voidpf + ft_gzip_alloc( FT_Memory memory, + uInt items, + uInt size ) + { + FT_ULong sz = (FT_ULong)size * items; + FT_Pointer p; - static voidpf - ft_gzip_alloc( FT_Memory memory, - uInt items, - uInt size ) - { - FT_ULong sz = (FT_ULong)size * items; - FT_Pointer p; + FT_MEM_ALLOC( p, sz ); - FT_MEM_ALLOC( p, sz ); - - return (voidpf) p; - } + return (voidpf) p; + } - static void - ft_gzip_free( FT_Memory memory, - voidpf address ) - { - FT_MEM_FREE( address ); - } + static void + ft_gzip_free( FT_Memory memory, + voidpf address ) + { + FT_MEM_FREE( address ); + } #ifndef FT_CONFIG_OPTION_SYSTEM_ZLIB - local voidpf - zcalloc ( /* opaque, items, size) */ - voidpf opaque, - unsigned items, - unsigned size ) - { - return ft_gzip_alloc( opaque, items, size ); - } + local voidpf + zcalloc ( voidpf opaque, + unsigned items, + unsigned size ) + { + return ft_gzip_alloc( (FT_Memory)opaque, items, size ); + } - local void - zcfree( voidpf opaque, - voidpf ptr ) - { - ft_gzip_free( opaque, ptr ); - } + local void + zcfree( voidpf opaque, + voidpf ptr ) + { + ft_gzip_free( (FT_Memory)opaque, ptr ); + } #endif /* !SYSTEM_ZLIB */ @@ -122,27 +144,27 @@ /***************************************************************************/ /***************************************************************************/ -#define FT_GZIP_BUFFER_SIZE 4096 +#define FT_GZIP_BUFFER_SIZE 4096 - typedef struct FT_GZipFileRec_ + typedef struct FT_GZipFileRec_ { - FT_Stream source; /* parent/source stream */ - FT_Stream stream; /* embedding stream */ - FT_Memory memory; /* memory allocator */ - z_stream zstream; /* zlib input stream */ + FT_Stream source; /* parent/source stream */ + FT_Stream stream; /* embedding stream */ + FT_Memory memory; /* memory allocator */ + z_stream zstream; /* zlib input stream */ - FT_ULong start; /* starting position, after .gz header */ - FT_Byte input[ FT_GZIP_BUFFER_SIZE ]; /* input read buffer */ + FT_ULong start; /* starting position, after .gz header */ + FT_Byte input[FT_GZIP_BUFFER_SIZE]; /* input read buffer */ - FT_Byte buffer[ FT_GZIP_BUFFER_SIZE ]; /* output buffer */ - FT_ULong pos; /* position in output */ - FT_Byte* cursor; - FT_Byte* limit; + FT_Byte buffer[FT_GZIP_BUFFER_SIZE]; /* output buffer */ + FT_ULong pos; /* position in output */ + FT_Byte* cursor; + FT_Byte* limit; } FT_GZipFileRec, *FT_GZipFile; -/* gzip flag byte */ + /* gzip flag byte */ #define FT_GZIP_ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ #define FT_GZIP_HEAD_CRC 0x02 /* bit 1 set: header CRC present */ #define FT_GZIP_EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ @@ -151,25 +173,26 @@ #define FT_GZIP_RESERVED 0xE0 /* bits 5..7: reserved */ - /* check and skip .gz header - we don't support "transparent" compression */ + /* check and skip .gz header - we don't support `transparent' compression */ static FT_Error ft_gzip_check_header( FT_Stream stream ) { FT_Error error; FT_Byte head[4]; + if ( FT_STREAM_SEEK( 0 ) || FT_STREAM_READ( head, 4 ) ) goto Exit; - /* head[0] && head[1] are the magic numbers */ + /* head[0] && head[1] are the magic numbers; */ /* head[2] is the method, and head[3] the flags */ if ( head[0] != 0x1f || head[1] != 0x8b || head[2] != Z_DEFLATED || (head[3] & FT_GZIP_RESERVED) ) { - error = FT_Err_Invalid_File_Format; + error = Gzip_Err_Invalid_File_Format; goto Exit; } @@ -181,6 +204,7 @@ { FT_UInt len; + if ( FT_READ_USHORT_LE( len ) || FT_STREAM_SKIP( len ) ) goto Exit; @@ -192,7 +216,8 @@ { FT_UInt c; - if ( FT_READ_BYTE( c) ) + + if ( FT_READ_BYTE( c ) ) goto Exit; if ( c == 0 ) @@ -205,7 +230,8 @@ { FT_UInt c; - if ( FT_READ_BYTE( c) ) + + if ( FT_READ_BYTE( c ) ) goto Exit; if ( c == 0 ) @@ -222,14 +248,14 @@ } - static FT_Error - ft_gzip_file_init( FT_GZipFile zip, - FT_Stream stream, - FT_Stream source ) + ft_gzip_file_init( FT_GZipFile zip, + FT_Stream stream, + FT_Stream source ) { z_stream* zstream = &zip->zstream; - FT_Error error = 0; + FT_Error error = Gzip_Err_Ok; + zip->stream = stream; zip->source = source; @@ -244,15 +270,15 @@ stream = source; error = ft_gzip_check_header( stream ); - if (error) + if ( error ) goto Exit; zip->start = FT_STREAM_POS(); } - /* initialize zlib - there is no zlib header in the compressed stream */ - zstream->zalloc = (alloc_func) ft_gzip_alloc; - zstream->zfree = (free_func) ft_gzip_free; + /* initialize zlib -- there is no zlib header in the compressed stream */ + zstream->zalloc = (alloc_func)ft_gzip_alloc; + zstream->zfree = (free_func) ft_gzip_free; zstream->opaque = stream->memory; zstream->avail_in = 0; @@ -260,22 +286,19 @@ if ( inflateInit2( zstream, -MAX_WBITS ) != Z_OK || zstream->next_in == NULL ) - { - error = FT_Err_Invalid_File_Format; - goto Exit; - } + error = Gzip_Err_Invalid_File_Format; Exit: return error; } - static void ft_gzip_file_done( FT_GZipFile zip ) { z_stream* zstream = &zip->zstream; + inflateEnd( zstream ); /* clear the rest */ @@ -299,10 +322,12 @@ FT_Stream stream = zip->source; FT_Error error; + if ( !FT_STREAM_SEEK( zip->start ) ) { z_stream* zstream = &zip->zstream; + inflateReset( zstream ); zstream->avail_in = 0; @@ -314,7 +339,8 @@ zip->cursor = zip->limit; zip->pos = 0; } - return error; + + return error; } @@ -325,11 +351,13 @@ FT_Stream stream = zip->source; FT_ULong size; + if ( stream->read ) { - size = stream->read( stream, stream->pos, zip->input, FT_GZIP_BUFFER_SIZE ); + size = stream->read( stream, stream->pos, zip->input, + FT_GZIP_BUFFER_SIZE ); if ( size == 0 ) - return FT_Err_Invalid_Stream_Operation; + return Gzip_Err_Invalid_Stream_Operation; } else { @@ -338,7 +366,7 @@ size = FT_GZIP_BUFFER_SIZE; if ( size == 0 ) - return FT_Err_Invalid_Stream_Operation; + return Gzip_Err_Invalid_Stream_Operation; FT_MEM_COPY( zip->input, stream->base + stream->pos, size ); } @@ -347,17 +375,17 @@ zstream->next_in = zip->input; zstream->avail_in = size; - return 0; + return Gzip_Err_Ok; } - static FT_Error ft_gzip_file_fill_output( FT_GZipFile zip ) { z_stream* zstream = &zip->zstream; FT_Error error = 0; + zip->cursor = zip->buffer; zstream->next_out = zip->cursor; zstream->avail_out = FT_GZIP_BUFFER_SIZE; @@ -366,6 +394,7 @@ { int err; + if ( zstream->avail_in == 0 ) { error = ft_gzip_file_fill_input( zip ); @@ -378,26 +407,29 @@ if ( err == Z_STREAM_END ) { zip->limit = zstream->next_out; - error = FT_Err_Invalid_Stream_Operation; + if ( zip->limit == zip->cursor ) + error = Gzip_Err_Invalid_Stream_Operation; break; } else if ( err != Z_OK ) { - error = FT_Err_Invalid_Stream_Operation; + error = Gzip_Err_Invalid_Stream_Operation; break; } } + return error; } - /* fill output buffer, 'count' must be <= FT_GZIP_BUFFER_SIZE */ + /* fill output buffer; `count' must be <= FT_GZIP_BUFFER_SIZE */ static FT_Error ft_gzip_file_skip_output( FT_GZipFile zip, FT_ULong count ) { - FT_Error error = 0; - FT_ULong delta; + FT_Error error = Gzip_Err_Ok; + FT_ULong delta; + for (;;) { @@ -422,27 +454,29 @@ static FT_ULong - ft_gzip_file_io( FT_GZipFile zip, - FT_ULong pos, - FT_Byte* buffer, - FT_ULong count ) + ft_gzip_file_io( FT_GZipFile zip, + FT_ULong pos, + FT_Byte* buffer, + FT_ULong count ) { - FT_ULong result = 0; - FT_Error error; + FT_ULong result = 0; + FT_Error error; - /* reset inflate stream if we're seeking backwards */ - /* yes, that's not too efficient, but it saves memory :-) */ + + /* Reset inflate stream if we're seeking backwards. */ + /* Yes, that is not too efficient, but it saves memory :-) */ if ( pos < zip->pos ) { error = ft_gzip_file_reset( zip ); - if ( error ) goto Exit; + if ( error ) + goto Exit; } /* skip unwanted bytes */ if ( pos > zip->pos ) { error = ft_gzip_file_skip_output( zip, (FT_ULong)( pos - zip->pos ) ); - if (error) + if ( error ) goto Exit; } @@ -452,7 +486,8 @@ /* now read the data */ for (;;) { - FT_ULong delta; + FT_ULong delta; + delta = (FT_ULong)( zip->limit - zip->cursor ); if ( delta >= count ) @@ -469,7 +504,7 @@ break; error = ft_gzip_file_fill_output( zip ); - if (error) + if ( error ) break; } @@ -489,9 +524,10 @@ static void ft_gzip_stream_close( FT_Stream stream ) { - FT_GZipFile zip = stream->descriptor.pointer; + FT_GZipFile zip = (FT_GZipFile)stream->descriptor.pointer; FT_Memory memory = stream->memory; + if ( zip ) { /* finalize gzip file descriptor */ @@ -505,25 +541,27 @@ static FT_ULong - ft_gzip_stream_io( FT_Stream stream, - FT_ULong pos, - FT_Byte* buffer, - FT_ULong count ) + ft_gzip_stream_io( FT_Stream stream, + FT_ULong pos, + FT_Byte* buffer, + FT_ULong count ) { - FT_GZipFile zip = stream->descriptor.pointer; + FT_GZipFile zip = (FT_GZipFile)stream->descriptor.pointer; + return ft_gzip_file_io( zip, pos, buffer, count ); } FT_EXPORT_DEF( FT_Error ) - FT_Stream_OpenGzip( FT_Stream stream, - FT_Stream source ) + FT_Stream_OpenGzip( FT_Stream stream, + FT_Stream source ) { FT_Error error; FT_Memory memory = source->memory; FT_GZipFile zip; + FT_ZERO( stream ); stream->memory = memory; @@ -539,7 +577,7 @@ stream->descriptor.pointer = zip; } - stream->size = 0x7FFFFFFF; /* don't know the real size !! */ + stream->size = 0x7FFFFFFFL; /* don't know the real size! */ stream->pos = 0; stream->base = 0; stream->read = ft_gzip_stream_io; @@ -552,13 +590,16 @@ #else /* !FT_CONFIG_OPTION_USE_ZLIB */ FT_EXPORT_DEF( FT_Error ) - FT_Stream_OpenGzip( FT_Stream stream, - FT_Stream source ) + FT_Stream_OpenGzip( FT_Stream stream, + FT_Stream source ) { FT_UNUSED( stream ); FT_UNUSED( source ); - return FT_Err_Unimplemented_Feature; + return Gzip_Err_Unimplemented_Feature; } -#endif /* !FT_CONFIG_OPTION_USE_ZLIB */ +#endif /* !FT_CONFIG_OPTION_USE_ZLIB */ + + +/* END */ diff --git a/src/libs/freetype2/gzip/infblock.c b/src/libs/freetype2/gzip/infblock.c index 123ae1d7a7..d6e2dc297d 100644 --- a/src/libs/freetype2/gzip/infblock.c +++ b/src/libs/freetype2/gzip/infblock.c @@ -156,7 +156,8 @@ int r ) uInt bl, bd; inflate_huft *tl, *td; - inflate_trees_fixed(&bl, &bd, &tl, &td, z); + inflate_trees_fixed(&bl, &bd, (const inflate_huft**)&tl, + (const inflate_huft**)&td, z); s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); if (s->sub.decode.codes == Z_NULL) { @@ -383,4 +384,4 @@ z_streamp z ) return Z_OK; } - + diff --git a/src/libs/freetype2/gzip/infblock.h b/src/libs/freetype2/gzip/infblock.h index 3df7322adf..c2535a1e45 100644 --- a/src/libs/freetype2/gzip/infblock.h +++ b/src/libs/freetype2/gzip/infblock.h @@ -33,4 +33,4 @@ local int inflate_blocks_free OF(( inflate_blocks_statef *, z_streamp)); -#endif /* _INFBLOCK_H */ +#endif /* _INFBLOCK_H */ diff --git a/src/libs/freetype2/gzip/infcodes.c b/src/libs/freetype2/gzip/infcodes.c index 6a36ead7b3..f7bfd58c4f 100644 --- a/src/libs/freetype2/gzip/infcodes.c +++ b/src/libs/freetype2/gzip/infcodes.c @@ -247,4 +247,4 @@ z_streamp z ) { ZFREE(z, c); Tracev((stderr, "inflate: codes free\n")); -} +} diff --git a/src/libs/freetype2/gzip/infcodes.h b/src/libs/freetype2/gzip/infcodes.h index 3281491815..154d7f896c 100644 --- a/src/libs/freetype2/gzip/infcodes.h +++ b/src/libs/freetype2/gzip/infcodes.h @@ -28,4 +28,4 @@ local void inflate_codes_free OF(( inflate_codes_statef *, z_streamp )); -#endif /* _INFCODES_H */ +#endif /* _INFCODES_H */ diff --git a/src/libs/freetype2/gzip/inffixed.h b/src/libs/freetype2/gzip/inffixed.h index 64e757c238..4d4760ea00 100644 --- a/src/libs/freetype2/gzip/inffixed.h +++ b/src/libs/freetype2/gzip/inffixed.h @@ -7,9 +7,9 @@ subject to change. Applications should only use zlib.h. */ -local uInt fixed_bl = 9; -local uInt fixed_bd = 5; -local inflate_huft fixed_tl[] = { +local const uInt fixed_bl = 9; +local const uInt fixed_bd = 5; +local const inflate_huft fixed_tl[] = { {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192}, {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160}, @@ -139,7 +139,7 @@ local inflate_huft fixed_tl[] = { {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191}, {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255} }; -local inflate_huft fixed_td[] = { +local const inflate_huft fixed_td[] = { {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097}, {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385}, {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193}, @@ -148,4 +148,4 @@ local inflate_huft fixed_td[] = { {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577}, {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289}, {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577} - }; + }; diff --git a/src/libs/freetype2/gzip/inflate.c b/src/libs/freetype2/gzip/inflate.c index 01029767eb..8877fa3eb2 100644 --- a/src/libs/freetype2/gzip/inflate.c +++ b/src/libs/freetype2/gzip/inflate.c @@ -270,4 +270,4 @@ int f ) return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ #endif } - + diff --git a/src/libs/freetype2/gzip/inftrees.c b/src/libs/freetype2/gzip/inftrees.c index d394d6202d..9002bf5b89 100644 --- a/src/libs/freetype2/gzip/inftrees.c +++ b/src/libs/freetype2/gzip/inftrees.c @@ -401,11 +401,11 @@ local inflate_huft *fixed_td; local int inflate_trees_fixed( /* bl, bd, tl, td, z) */ -uIntf *bl, /* literal desired/actual bit depth */ -uIntf *bd, /* distance desired/actual bit depth */ -inflate_huft * FAR *tl, /* literal/length tree result */ -inflate_huft * FAR *td, /* distance tree result */ -z_streamp z /* for memory allocation */ +uIntf *bl, /* literal desired/actual bit depth */ +uIntf *bd, /* distance desired/actual bit depth */ +const inflate_huft * FAR *tl, /* literal/length tree result */ +const inflate_huft * FAR *td, /* distance tree result */ +z_streamp z /* for memory allocation */ ) { #ifdef BUILDFIXED @@ -451,10 +451,12 @@ z_streamp z /* for memory allocation */ ZFREE(z, c); fixed_built = 1; } +#else + FT_UNUSED(z); #endif *bl = fixed_bl; *bd = fixed_bd; *tl = fixed_tl; *td = fixed_td; return Z_OK; -} +} diff --git a/src/libs/freetype2/gzip/inftrees.h b/src/libs/freetype2/gzip/inftrees.h index e59619652f..07bf2aa0bf 100644 --- a/src/libs/freetype2/gzip/inftrees.h +++ b/src/libs/freetype2/gzip/inftrees.h @@ -56,8 +56,8 @@ local int inflate_trees_dynamic OF(( local int inflate_trees_fixed OF(( uIntf *, /* literal desired/actual bit depth */ uIntf *, /* distance desired/actual bit depth */ - inflate_huft * FAR *, /* literal/length tree result */ - inflate_huft * FAR *, /* distance tree result */ + const inflate_huft * FAR *, /* literal/length tree result */ + const inflate_huft * FAR *, /* distance tree result */ z_streamp)); /* for memory allocation */ -#endif /* _INFTREES_H */ +#endif /* _INFTREES_H */ diff --git a/src/libs/freetype2/gzip/infutil.c b/src/libs/freetype2/gzip/infutil.c index 3c7bfec80c..6087b40647 100644 --- a/src/libs/freetype2/gzip/infutil.c +++ b/src/libs/freetype2/gzip/infutil.c @@ -11,7 +11,7 @@ /* And'ing with mask[n] masks the lower n bits */ -local uInt inflate_mask[17] = { +local const uInt inflate_mask[17] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff @@ -83,4 +83,4 @@ int r ) /* done */ return r; -} +} diff --git a/src/libs/freetype2/gzip/infutil.h b/src/libs/freetype2/gzip/infutil.h index db9abac5e5..7174b6dd0f 100644 --- a/src/libs/freetype2/gzip/infutil.h +++ b/src/libs/freetype2/gzip/infutil.h @@ -85,7 +85,9 @@ struct inflate_blocks_state { #define LOAD {LOADIN LOADOUT} /* masks for lower bits (size given to avoid silly warnings with Visual C++) */ +#ifndef NO_INFLATE_MASK local uInt inflate_mask[17]; +#endif /* copy as much as possible from the sliding window to the output area */ local int inflate_flush OF(( @@ -93,4 +95,4 @@ local int inflate_flush OF(( z_streamp , int)); -#endif +#endif diff --git a/src/libs/freetype2/gzip/rules.mk b/src/libs/freetype2/gzip/rules.mk index da7fa4d2f9..d2a43a6a89 100644 --- a/src/libs/freetype2/gzip/rules.mk +++ b/src/libs/freetype2/gzip/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2002 by +# Copyright 2002, 2003 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -15,14 +15,13 @@ # gzip driver directory # -GZIP_DIR := $(SRC_)gzip -GZIP_DIR_ := $(GZIP_DIR)$(SEP) +GZIP_DIR := $(SRC_DIR)/gzip # compilation flags for the driver # ifeq ($(SYSTEM_ZLIB),) - GZIP_COMPILE := $(FT_COMPILE) $I$(GZIP_DIR) + GZIP_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(GZIP_DIR)) else GZIP_COMPILE := $(FT_COMPILE) endif @@ -30,7 +29,7 @@ endif # gzip support sources (i.e., C files) # -GZIP_DRV_SRC := $(GZIP_DIR_)ftgzip.c +GZIP_DRV_SRC := $(GZIP_DIR)/ftgzip.c # gzip support headers # @@ -43,27 +42,28 @@ GZIP_DRV_H := # GZIP_DRV_OBJ_S is used during `single' builds # ifeq ($(SYSTEM_ZLIB),) - GZIP_DRV_OBJ_M := $(GZIP_DRV_SRC:$(GZIP_DIR_)%.c=$(OBJ_)%.$O) + GZIP_DRV_OBJ_M := $(GZIP_DRV_SRC:$(GZIP_DIR)/%.c=$(OBJ_DIR)/%.$O) else - GZIP_DRV_OBJ_M := $(OBJ_)ftgzip.$O + GZIP_DRV_OBJ_M := $(OBJ_DIR)/ftgzip.$O endif -GZIP_DRV_OBJ_S := $(OBJ_)ftgzip.$O +GZIP_DRV_OBJ_S := $(OBJ_DIR)/ftgzip.$O # gzip support source file for single build # -GZIP_DRV_SRC_S := $(GZIP_DIR_)ftgzip.c +GZIP_DRV_SRC_S := $(GZIP_DIR)/ftgzip.c # gzip support - single object # -$(GZIP_DRV_OBJ_S): $(GZIP_DRV_SRC_S) $(GZIP_DRV_SRC) $(FREETYPE_H) $(GZIP_DRV_H) - $(GZIP_COMPILE) $T$@ $(GZIP_DRV_SRC_S) +$(GZIP_DRV_OBJ_S): $(GZIP_DRV_SRC_S) $(GZIP_DRV_SRC) $(FREETYPE_H) \ + $(GZIP_DRV_H) + $(GZIP_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(GZIP_DRV_SRC_S)) # gzip support - multiple objects # -$(OBJ_)%.$O: $(GZIP_DIR_)%.c $(FREETYPE_H) $(GZIP_DRV_H) - $(GZIP_COMPILE) $T$@ $< +$(OBJ_DIR)/%.$O: $(GZIP_DIR)/%.c $(FREETYPE_H) $(GZIP_DRV_H) + $(GZIP_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) # update main driver object lists @@ -71,4 +71,5 @@ $(OBJ_)%.$O: $(GZIP_DIR_)%.c $(FREETYPE_H) $(GZIP_DRV_H) DRV_OBJS_S += $(GZIP_DRV_OBJ_S) DRV_OBJS_M += $(GZIP_DRV_OBJ_M) -# EOF + +# EOF diff --git a/src/libs/freetype2/gzip/zconf.h b/src/libs/freetype2/gzip/zconf.h index 5728fca4af..f0bbc8da35 100644 --- a/src/libs/freetype2/gzip/zconf.h +++ b/src/libs/freetype2/gzip/zconf.h @@ -3,7 +3,7 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id: zconf.h,v 1.2 2003/07/24 18:52:52 darkwyrm Exp $ */ +/* @(#) $Id: zconf.h,v 1.3 2004/06/22 14:01:14 darkwyrm Exp $ */ #ifndef _ZCONF_H #define _ZCONF_H @@ -275,4 +275,4 @@ typedef uLong FAR uLongf; # pragma map(inflate_trees_free,"INTRFR") #endif -#endif /* _ZCONF_H */ +#endif /* _ZCONF_H */ diff --git a/src/libs/freetype2/gzip/zlib.h b/src/libs/freetype2/gzip/zlib.h index f7fa65cf9e..50d0d3f146 100644 --- a/src/libs/freetype2/gzip/zlib.h +++ b/src/libs/freetype2/gzip/zlib.h @@ -827,4 +827,4 @@ ZEXTERN(int) inflateInit2_ OF((z_streamp strm, int windowBits, } #endif -#endif /* _ZLIB_H */ +#endif /* _ZLIB_H */ diff --git a/src/libs/freetype2/gzip/zutil.c b/src/libs/freetype2/gzip/zutil.c index e1f419ea61..e3591954e5 100644 --- a/src/libs/freetype2/gzip/zutil.c +++ b/src/libs/freetype2/gzip/zutil.c @@ -3,7 +3,7 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id: zutil.c,v 1.2 2003/07/24 18:52:52 darkwyrm Exp $ */ +/* @(#) $Id: zutil.c,v 1.3 2004/06/22 14:01:14 darkwyrm Exp $ */ #include "zutil.h" @@ -178,4 +178,4 @@ void zcfree (opaque, ptr) if (opaque) return; /* make compiler happy */ } -#endif /* MY_ZCALLOC */ +#endif /* MY_ZCALLOC */ diff --git a/src/libs/freetype2/gzip/zutil.h b/src/libs/freetype2/gzip/zutil.h index ca77c25ac3..12af4e0d31 100644 --- a/src/libs/freetype2/gzip/zutil.h +++ b/src/libs/freetype2/gzip/zutil.h @@ -8,7 +8,7 @@ subject to change. Applications should only use zlib.h. */ -/* @(#) $Id: zutil.h,v 1.2 2003/07/24 18:52:52 darkwyrm Exp $ */ +/* @(#) $Id: zutil.h,v 1.3 2004/06/22 14:01:14 darkwyrm Exp $ */ #ifndef _Z_UTIL_H #define _Z_UTIL_H @@ -173,8 +173,8 @@ typedef unsigned long ulg; # define zmemzero(dest, len) _fmemset(dest, 0, len) # else # define zmemcpy ft_memcpy -# define zmemcmp memcmp -# define zmemzero(dest, len) memset(dest, 0, len) +# define zmemcmp ft_memcmp +# define zmemzero(dest, len) ft_memset(dest, 0, len) # endif #else extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); @@ -213,4 +213,4 @@ local void zcfree OF((voidpf opaque, voidpf ptr)); #define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) #define TRY_FREE(s, p) {if (p) ZFREE(s, p);} -#endif /* _Z_UTIL_H */ +#endif /* _Z_UTIL_H */ diff --git a/src/libs/freetype2/lzw/Jamfile b/src/libs/freetype2/lzw/Jamfile new file mode 100644 index 0000000000..d4841cbe19 --- /dev/null +++ b/src/libs/freetype2/lzw/Jamfile @@ -0,0 +1,11 @@ +# FreeType 2 src/gzip Jamfile (c) 2001 David Turner +# + +SubDir OBOS_TOP src libs freetype2 lzw ; + +UseFreeTypeHeaders ; + +FT2_Library $(FT2_LIB) : ftlzw.c ; + +# end of src/lzw Jamfile + diff --git a/src/libs/freetype2/lzw/ftlzw.c b/src/libs/freetype2/lzw/ftlzw.c new file mode 100644 index 0000000000..a0e4cc5762 --- /dev/null +++ b/src/libs/freetype2/lzw/ftlzw.c @@ -0,0 +1,463 @@ +/***************************************************************************/ +/* */ +/* ftlzw.c */ +/* */ +/* FreeType support for .Z compressed files. */ +/* */ +/* This optional component relies on NetBSD's zopen(). It should mainly */ +/* be used to parse compressed PCF fonts, as found with many X11 server */ +/* distributions. */ +/* */ +/* Copyright 2004 by */ +/* Albert Chin-A-Young. */ +/* */ +/* Based on code in src/gzip/ftgzip.c, Copyright 2004 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. */ +/* */ +/***************************************************************************/ + +#include <ft2build.h> +#include FT_INTERNAL_MEMORY_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_DEBUG_H +#include <string.h> +#include <stdio.h> + + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX LZW_Err_ +#define FT_ERR_BASE FT_Mod_Err_LZW + +#include FT_ERRORS_H + + +#ifdef FT_CONFIG_OPTION_USE_LZW + +#include "zopen.h" + + +/***************************************************************************/ +/***************************************************************************/ +/***** *****/ +/***** M E M O R Y M A N A G E M E N T *****/ +/***** *****/ +/***************************************************************************/ +/***************************************************************************/ + +/***************************************************************************/ +/***************************************************************************/ +/***** *****/ +/***** F I L E D E S C R I P T O R *****/ +/***** *****/ +/***************************************************************************/ +/***************************************************************************/ + +#define FT_LZW_BUFFER_SIZE 4096 + + typedef struct FT_LZWFileRec_ + { + FT_Stream source; /* parent/source stream */ + FT_Stream stream; /* embedding stream */ + FT_Memory memory; /* memory allocator */ + s_zstate_t zstream; /* lzw input stream */ + + FT_ULong start; /* starting position, after .Z header */ + FT_Byte input[FT_LZW_BUFFER_SIZE]; /* input buffer */ + + FT_Byte buffer[FT_LZW_BUFFER_SIZE]; /* output buffer */ + FT_ULong pos; /* position in output */ + FT_Byte* cursor; + FT_Byte* limit; + + } FT_LZWFileRec, *FT_LZWFile; + + + /* check and skip .Z header */ + static FT_Error + ft_lzw_check_header( FT_Stream stream ) + { + FT_Error error; + FT_Byte head[2]; + + + if ( FT_STREAM_SEEK( 0 ) || + FT_STREAM_READ( head, 2 ) ) + goto Exit; + + /* head[0] && head[1] are the magic numbers */ + if ( head[0] != 0x1f || + head[1] != 0x9d ) + error = LZW_Err_Invalid_File_Format; + + Exit: + return error; + } + + + static FT_Error + ft_lzw_file_init( FT_LZWFile zip, + FT_Stream stream, + FT_Stream source ) + { + s_zstate_t* zstream = &zip->zstream; + FT_Error error = LZW_Err_Ok; + + + zip->stream = stream; + zip->source = source; + zip->memory = stream->memory; + + zip->limit = zip->buffer + FT_LZW_BUFFER_SIZE; + zip->cursor = zip->limit; + zip->pos = 0; + + /* check and skip .Z header */ + { + stream = source; + + error = ft_lzw_check_header( source ); + if ( error ) + goto Exit; + + zip->start = FT_STREAM_POS(); + } + + /* initialize internal lzw variable */ + zinit( zstream ); + + zstream->avail_in = 0; + zstream->next_in = zip->buffer; + zstream->zs_in_count = source->size - 2; + + if ( zstream->next_in == NULL ) + error = LZW_Err_Invalid_File_Format; + + Exit: + return error; + } + + + static void + ft_lzw_file_done( FT_LZWFile zip ) + { + s_zstate_t* zstream = &zip->zstream; + + + /* clear the rest */ + zstream->next_in = NULL; + zstream->next_out = NULL; + zstream->avail_in = 0; + zstream->avail_out = 0; + zstream->total_in = 0; + zstream->total_out = 0; + + zip->memory = NULL; + zip->source = NULL; + zip->stream = NULL; + } + + + static FT_Error + ft_lzw_file_reset( FT_LZWFile zip ) + { + FT_Stream stream = zip->source; + FT_Error error; + + + if ( !FT_STREAM_SEEK( zip->start ) ) + { + s_zstate_t* zstream = &zip->zstream; + + + zinit( zstream ); + + zstream->avail_in = 0; + zstream->next_in = zip->input; + zstream->total_in = 0; + zstream->avail_out = 0; + zstream->next_out = zip->buffer; + zstream->total_out = 0; + zstream->zs_in_count = zip->source->size - 2; + + zip->limit = zip->buffer + FT_LZW_BUFFER_SIZE; + zip->cursor = zip->limit; + zip->pos = 0; + } + + return error; + } + + + static FT_Error + ft_lzw_file_fill_input( FT_LZWFile zip ) + { + s_zstate_t* zstream = &zip->zstream; + FT_Stream stream = zip->source; + FT_ULong size; + + + if ( stream->read ) + { + size = stream->read( stream, stream->pos, zip->input, + FT_LZW_BUFFER_SIZE ); + if ( size == 0 ) + return LZW_Err_Invalid_Stream_Operation; + } + else + { + size = stream->size - stream->pos; + if ( size > FT_LZW_BUFFER_SIZE ) + size = FT_LZW_BUFFER_SIZE; + + if ( size == 0 ) + return LZW_Err_Invalid_Stream_Operation; + + FT_MEM_COPY( zip->input, stream->base + stream->pos, size ); + } + stream->pos += size; + + zstream->next_in = zip->input; + zstream->avail_in = size; + + return LZW_Err_Ok; + } + + + + static FT_Error + ft_lzw_file_fill_output( FT_LZWFile zip ) + { + s_zstate_t* zstream = &zip->zstream; + FT_Error error = 0; + + + zip->cursor = zip->buffer; + zstream->next_out = zip->cursor; + zstream->avail_out = FT_LZW_BUFFER_SIZE; + + while ( zstream->avail_out > 0 ) + { + int num_read = 0; + + + if ( zstream->avail_in == 0 ) + { + error = ft_lzw_file_fill_input( zip ); + if ( error ) + break; + } + + num_read = zread( zstream ); + + if ( num_read == -1 && zstream->zs_in_count == 0 ) + { + zip->limit = zstream->next_out; + if ( zip->limit == zip->cursor ) + error = LZW_Err_Invalid_Stream_Operation; + break; + } + else if ( num_read == -1 ) + break; + else + zstream->avail_out -= num_read; + } + + return error; + } + + + /* fill output buffer; `count' must be <= FT_LZW_BUFFER_SIZE */ + static FT_Error + ft_lzw_file_skip_output( FT_LZWFile zip, + FT_ULong count ) + { + FT_Error error = LZW_Err_Ok; + FT_ULong delta; + + + for (;;) + { + delta = (FT_ULong)( zip->limit - zip->cursor ); + if ( delta >= count ) + delta = count; + + zip->cursor += delta; + zip->pos += delta; + + count -= delta; + if ( count == 0 ) + break; + + error = ft_lzw_file_fill_output( zip ); + if ( error ) + break; + } + + return error; + } + + + static FT_ULong + ft_lzw_file_io( FT_LZWFile zip, + FT_ULong pos, + FT_Byte* buffer, + FT_ULong count ) + { + FT_ULong result = 0; + FT_Error error; + + + /* Teset inflate stream if we're seeking backwards. */ + /* Yes, that is not too efficient, but it saves memory :-) */ + if ( pos < zip->pos ) + { + error = ft_lzw_file_reset( zip ); + if ( error ) + goto Exit; + } + + /* skip unwanted bytes */ + if ( pos > zip->pos ) + { + error = ft_lzw_file_skip_output( zip, (FT_ULong)( pos - zip->pos ) ); + if ( error ) + goto Exit; + } + + if ( count == 0 ) + goto Exit; + + /* now read the data */ + for (;;) + { + FT_ULong delta; + + + delta = (FT_ULong)( zip->limit - zip->cursor ); + if ( delta >= count ) + delta = count; + + FT_MEM_COPY( buffer, zip->cursor, delta ); + buffer += delta; + result += delta; + zip->cursor += delta; + zip->pos += delta; + + count -= delta; + if ( count == 0 ) + break; + + error = ft_lzw_file_fill_output( zip ); + if ( error ) + break; + } + + Exit: + return result; + } + + +/***************************************************************************/ +/***************************************************************************/ +/***** *****/ +/***** L Z W E M B E D D I N G S T R E A M *****/ +/***** *****/ +/***************************************************************************/ +/***************************************************************************/ + + static void + ft_lzw_stream_close( FT_Stream stream ) + { + FT_LZWFile zip = (FT_LZWFile)stream->descriptor.pointer; + FT_Memory memory = stream->memory; + + + if ( zip ) + { + /* finalize lzw file descriptor */ + ft_lzw_file_done( zip ); + + FT_FREE( zip ); + + stream->descriptor.pointer = NULL; + } + } + + + static FT_ULong + ft_lzw_stream_io( FT_Stream stream, + FT_ULong pos, + FT_Byte* buffer, + FT_ULong count ) + { + FT_LZWFile zip = (FT_LZWFile)stream->descriptor.pointer; + + + return ft_lzw_file_io( zip, pos, buffer, count ); + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Stream_OpenLZW( FT_Stream stream, + FT_Stream source ) + { + FT_Error error; + FT_Memory memory = source->memory; + FT_LZWFile zip; + + + FT_ZERO( stream ); + stream->memory = memory; + + if ( !FT_NEW( zip ) ) + { + error = ft_lzw_file_init( zip, stream, source ); + if ( error ) + { + FT_FREE( zip ); + goto Exit; + } + + stream->descriptor.pointer = zip; + } + + stream->size = 0x7FFFFFFFL; /* don't know the real size! */ + stream->pos = 0; + stream->base = 0; + stream->read = ft_lzw_stream_io; + stream->close = ft_lzw_stream_close; + + Exit: + return error; + } + +#include "zopen.c" + + +#else /* !FT_CONFIG_OPTION_USE_LZW */ + + + FT_EXPORT_DEF( FT_Error ) + FT_Stream_OpenLZW( FT_Stream stream, + FT_Stream source ) + { + FT_UNUSED( stream ); + FT_UNUSED( source ); + + return LZW_Err_Unimplemented_Feature; + } + + +#endif /* !FT_CONFIG_OPTION_USE_LZW */ + + +/* END */ diff --git a/src/libs/freetype2/lzw/rules.mk b/src/libs/freetype2/lzw/rules.mk new file mode 100644 index 0000000000..73ce718044 --- /dev/null +++ b/src/libs/freetype2/lzw/rules.mk @@ -0,0 +1,70 @@ +# +# FreeType 2 LZW support configuration rules +# + + +# Copyright 2004 by +# Albert Chin-A-Young. +# +# Based on src/lzw/rules.mk, Copyright 2002 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. + + +# LZW driver directory +# +LZW_DIR := $(SRC_DIR)/lzw + + +# compilation flags for the driver +# +LZW_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(LZW_DIR)) + + +# LZW support sources (i.e., C files) +# +LZW_DRV_SRC := $(LZW_DIR)/ftlzw.c \ + $(LZW_DIR)/zopen.c + +# LZW support headers +# +LZW_DRV_H := $(LZW_DIR)/zopen.h + + +# LZW driver object(s) +# +# LZW_DRV_OBJ_M is used during `multi' builds +# LZW_DRV_OBJ_S is used during `single' builds +# +LZW_DRV_OBJ_M := $(OBJ_DIR)/ftlzw.$O +LZW_DRV_OBJ_S := $(OBJ_DIR)/ftlzw.$O + +# LZW support source file for single build +# +LZW_DRV_SRC_S := $(LZW_DIR)/ftlzw.c + + +# LZW support - single object +# +$(LZW_DRV_OBJ_S): $(LZW_DRV_SRC_S) $(LZW_DRV_SRC) $(FREETYPE_H) $(LZW_DRV_H) + $(LZW_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(LZW_DRV_SRC_S)) + + +# LZW support - multiple objects +# +$(OBJ_DIR)/%.$O: $(LZW_DIR)/%.c $(FREETYPE_H) $(LZW_DRV_H) + $(LZW_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) + + +# update main driver object lists +# +DRV_OBJS_S += $(LZW_DRV_OBJ_S) +DRV_OBJS_M += $(LZW_DRV_OBJ_M) + + +# EOF diff --git a/src/libs/freetype2/lzw/zopen.c b/src/libs/freetype2/lzw/zopen.c new file mode 100644 index 0000000000..5267f1622b --- /dev/null +++ b/src/libs/freetype2/lzw/zopen.c @@ -0,0 +1,396 @@ +/* $NetBSD: zopen.c,v 1.8 2003/08/07 11:13:29 agc Exp $ */ + +/*- + * Copyright (c) 1985, 1986, 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Diomidis Spinellis and James A. Woods, derived from original + * work by Spencer Thomas and Joseph Orost. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*- + * + * Copyright (c) 2004 + * Albert Chin-A-Young. + * + * Modified to work with FreeType's PCF driver. + * + */ + +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)zopen.c 8.1 (Berkeley) 6/27/93"; +#else +static char rcsid[] = "$NetBSD: zopen.c,v 1.8 2003/08/07 11:13:29 agc Exp $"; +#endif +#endif /* LIBC_SCCS and not lint */ + +/*- + * fcompress.c - File compression ala IEEE Computer, June 1984. + * + * Compress authors: + * Spencer W. Thomas (decvax!utah-cs!thomas) + * Jim McKie (decvax!mcvax!jim) + * Steve Davies (decvax!vax135!petsd!peora!srd) + * Ken Turkowski (decvax!decwrl!turtlevax!ken) + * James A. Woods (decvax!ihnp4!ames!jaw) + * Joe Orost (decvax!vax135!petsd!joe) + * + * Cleaned up and converted to library returning I/O streams by + * Diomidis Spinellis <dds@doc.ic.ac.uk>. + */ + +#include <ctype.h> +#include <signal.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#if 0 +static char_type magic_header[] = + { 0x1f, 0x9d }; /* 1F 9D */ +#endif + +#define BIT_MASK 0x1f /* Defines for third byte of header. */ +#define BLOCK_MASK 0x80 + +/* + * Masks 0x40 and 0x20 are free. I think 0x20 should mean that there is + * a fourth header byte (for expansion). + */ +#define INIT_BITS 9 /* Initial number of bits/code. */ + +#define MAXCODE(n_bits) ((1 << (n_bits)) - 1) + +/* Definitions to retain old variable names */ +#define fp zs->zs_fp +#define state zs->zs_state +#define n_bits zs->zs_n_bits +#define maxbits zs->zs_maxbits +#define maxcode zs->zs_maxcode +#define maxmaxcode zs->zs_maxmaxcode +#define htab zs->zs_htab +#define codetab zs->zs_codetab +#define hsize zs->zs_hsize +#define free_ent zs->zs_free_ent +#define block_compress zs->zs_block_compress +#define clear_flg zs->zs_clear_flg +#define offset zs->zs_offset +#define in_count zs->zs_in_count +#define buf_len zs->zs_buf_len +#define buf zs->zs_buf +#define stackp zs->u.r.zs_stackp +#define finchar zs->u.r.zs_finchar +#define code zs->u.r.zs_code +#define oldcode zs->u.r.zs_oldcode +#define incode zs->u.r.zs_incode +#define roffset zs->u.r.zs_roffset +#define size zs->u.r.zs_size +#define gbuf zs->u.r.zs_gbuf + +/* + * To save much memory, we overlay the table used by compress() with those + * used by decompress(). The tab_prefix table is the same size and type as + * the codetab. The tab_suffix table needs 2**BITS characters. We get this + * from the beginning of htab. The output stack uses the rest of htab, and + * contains characters. There is plenty of room for any possible stack + * (stack used to be 8000 characters). + */ + +#define htabof(i) htab[i] +#define codetabof(i) codetab[i] + +#define tab_prefixof(i) codetabof(i) +#define tab_suffixof(i) ((char_type *)(htab))[i] +#define de_stack ((char_type *)&tab_suffixof(1 << BITS)) + +#define CHECK_GAP 10000 /* Ratio check interval. */ + +/* + * the next two codes should not be changed lightly, as they must not + * lie within the contiguous general code space. + */ +#define FIRST 257 /* First free entry. */ +#define CLEAR 256 /* Table clear output code. */ + +/*- + * Algorithm from "A Technique for High Performance Data Compression", + * Terry A. Welch, IEEE Computer Vol 17, No 6 (June 1984), pp 8-19. + * + * Algorithm: + * Modified Lempel-Ziv method (LZW). Basically finds common + * substrings and replaces them with a variable size code. This is + * deterministic, and can be done on the fly. Thus, the decompression + * procedure needs no input table, but tracks the way the table was built. + */ + +#if 0 +static int +zclose(s_zstate_t *zs) +{ + free(zs); + return (0); +} +#endif + +/*- + * Output the given code. + * Inputs: + * code: A n_bits-bit integer. If == -1, then EOF. This assumes + * that n_bits =< (long)wordsize - 1. + * Outputs: + * Outputs code to the file. + * Assumptions: + * Chars are 8 bits long. + * Algorithm: + * Maintain a BITS character long buffer (so that 8 codes will + * fit in it exactly). Use the VAX insv instruction to insert each + * code in turn. When the buffer fills up empty it and start over. + */ + +static const char_type rmask[9] = + {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff}; + +/* + * Decompress read. This routine adapts to the codes in the file building + * the "string" table on-the-fly; requiring no table to be stored in the + * compressed file. The tables used herein are shared with those of the + * compress() routine. See the definitions above. + */ +static int +zread(s_zstate_t *zs) +{ + unsigned int count; + + if (in_count == 0) + return -1; + if (zs->avail_out == 0) + return 0; + + count = zs->avail_out; + switch (state) { + case S_START: + state = S_MIDDLE; + break; + case S_MIDDLE: + goto middle; + case S_EOF: + goto eof; + } + + maxbits = *(zs->next_in); /* Set -b from file. */ + zs->avail_in--; + zs->next_in++; + zs->total_in++; + in_count--; + block_compress = maxbits & BLOCK_MASK; + maxbits &= BIT_MASK; + maxmaxcode = 1L << maxbits; + if (maxbits > BITS) { + return -1; + } + /* As above, initialize the first 256 entries in the table. */ + maxcode = MAXCODE(n_bits = INIT_BITS); + for (code = 255; code >= 0; code--) { + tab_prefixof(code) = 0; + tab_suffixof(code) = (char_type) code; + } + free_ent = block_compress ? FIRST : 256; + + finchar = oldcode = getcode(zs); + if (oldcode == -1) /* EOF already? */ + return 0; /* Get out of here */ + + /* First code must be 8 bits = char. */ + *(zs->next_out)++ = (unsigned char)finchar; + zs->total_out++; + count--; + stackp = de_stack; + + while ((code = getcode(zs)) > -1) { + if ((code == CLEAR) && block_compress) { + for (code = 255; code >= 0; code--) + tab_prefixof(code) = 0; + clear_flg = 1; + free_ent = FIRST - 1; + if ((code = getcode(zs)) == -1) + /* O, untimely death! */ + break; + } + incode = code; + + /* Special case for KwKwK string. */ + if (code >= free_ent) { + *stackp++ = finchar; + code = oldcode; + } + + /* Generate output characters in reverse order. */ + while (code >= 256) { + *stackp++ = tab_suffixof(code); + code = tab_prefixof(code); + } + *stackp++ = finchar = tab_suffixof(code); + + /* And put them out in forward order. */ +middle: + if (stackp == de_stack) + continue; + + do { + if (count-- == 0) { + return zs->avail_out; + } + *(zs->next_out)++ = *--stackp; + zs->total_out++; + } while (stackp > de_stack); + + /* Generate the new entry. */ + if ((code = free_ent) < maxmaxcode) { + tab_prefixof(code) = (unsigned short) oldcode; + tab_suffixof(code) = finchar; + free_ent = code + 1; + } + + /* Remember previous code. */ + oldcode = incode; + } + /* state = S_EOF; */ +eof: return (zs->avail_out - count); +} + +/*- + * Read one code from the standard input. If EOF, return -1. + * Inputs: + * stdin + * Outputs: + * code or -1 is returned. + */ +static code_int +getcode(s_zstate_t *zs) +{ + code_int gcode; + int r_off, bits; + char_type *bp; + + bp = gbuf; + if (clear_flg > 0 || roffset >= size || free_ent > maxcode) { + /* + * If the next entry will be too big for the current gcode + * size, then we must increase the size. This implies reading + * a new buffer full, too. + */ + if (free_ent > maxcode) { + n_bits++; + if (n_bits == maxbits) /* Won't get any bigger now. */ + maxcode = maxmaxcode; + else + maxcode = MAXCODE(n_bits); + } + if (clear_flg > 0) { + maxcode = MAXCODE(n_bits = INIT_BITS); + clear_flg = 0; + } + if ( zs->avail_in < (unsigned int)n_bits && in_count > (long)n_bits ) { + memcpy (buf, zs->next_in, zs->avail_in); + buf_len = zs->avail_in; + zs->avail_in = 0; + return -1; + } + if (buf_len) { + memcpy (gbuf, buf, buf_len); + memcpy (gbuf + buf_len, zs->next_in, + n_bits - buf_len); + zs->next_in += n_bits - buf_len; + zs->avail_in -= n_bits - buf_len; + buf_len = 0; + zs->total_in += n_bits; + size = n_bits; + in_count -= n_bits; + } else { + if (in_count > n_bits) { + memcpy (gbuf, zs->next_in, n_bits); + zs->next_in += n_bits; + zs->avail_in -= n_bits; + zs->total_in += n_bits; + size = n_bits; + in_count -= n_bits; + } else { + memcpy (gbuf, zs->next_in, in_count); + zs->next_in += in_count; + zs->avail_in -= in_count; + zs->total_in += in_count; + size = in_count; + in_count = 0; + } + } + roffset = 0; + /* Round size down to integral number of codes. */ + size = (size << 3) - (n_bits - 1); + } + r_off = roffset; + bits = n_bits; + + /* Get to the first byte. */ + bp += (r_off >> 3); + r_off &= 7; + + /* Get first part (low order bits). */ + gcode = (*bp++ >> r_off); + bits -= (8 - r_off); + r_off = 8 - r_off; /* Now, roffset into gcode word. */ + + /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */ + if (bits >= 8) { + gcode |= *bp++ << r_off; + r_off += 8; + bits -= 8; + } + + /* High order bits. */ + gcode |= (*bp & rmask[bits]) << r_off; + roffset += n_bits; + + return (gcode); +} + +static void +zinit(s_zstate_t *zs) +{ + memset(zs, 0, sizeof (s_zstate_t)); + + maxbits = BITS; /* User settable max # bits/code. */ + maxmaxcode = 1 << maxbits; /* Should NEVER generate this code. */ + hsize = HSIZE; /* For dynamic table sizing. */ + free_ent = 0; /* First unused entry. */ + block_compress = BLOCK_MASK; + clear_flg = 0; + state = S_START; + roffset = 0; + size = 0; +} diff --git a/src/libs/freetype2/lzw/zopen.h b/src/libs/freetype2/lzw/zopen.h new file mode 100644 index 0000000000..483b47e5c6 --- /dev/null +++ b/src/libs/freetype2/lzw/zopen.h @@ -0,0 +1,114 @@ +/* $NetBSD: zopen.c,v 1.8 2003/08/07 11:13:29 agc Exp $ */ + +/*- + * Copyright (c) 1985, 1986, 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Diomidis Spinellis and James A. Woods, derived from original + * work by Spencer Thomas and Joseph Orost. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*- + * + * Copyright (c) 2004 + * Albert Chin-A-Young. + * + * Modified to work with FreeType's PCF driver. + * + */ + +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)zopen.c 8.1 (Berkeley) 6/27/93"; +#else +static char rcsid[] = "$NetBSD: zopen.c,v 1.8 2003/08/07 11:13:29 agc Exp $"; +#endif +#endif /* LIBC_SCCS and not lint */ + +#include <stdio.h> + +#define BITS 16 /* Default bits. */ +#define HSIZE 69001 /* 95% occupancy */ + +/* A code_int must be able to hold 2**BITS values of type int, and also -1. */ +typedef long code_int; +typedef long count_int; + +typedef unsigned char char_type; + +typedef enum { + S_START, S_MIDDLE, S_EOF +} zs_enum; + +typedef struct { + unsigned char *next_in; + unsigned int avail_in; + unsigned long total_in; + + unsigned char *next_out; + unsigned int avail_out; + unsigned long total_out; + + zs_enum zs_state; /* State of computation */ + int zs_n_bits; /* Number of bits/code. */ + int zs_maxbits; /* User settable max # bits/code. */ + code_int zs_maxcode; /* Maximum code, given n_bits. */ + code_int zs_maxmaxcode; /* Should NEVER generate this code. */ + count_int zs_htab [HSIZE]; + unsigned short zs_codetab [HSIZE]; + code_int zs_hsize; /* For dynamic table sizing. */ + code_int zs_free_ent; /* First unused entry. */ + /* + * Block compression parameters -- after all codes are used up, + * and compression rate changes, start over. + */ + int zs_block_compress; + int zs_clear_flg; + int zs_offset; + long zs_in_count; /* Remaining uncompressed bytes. */ + char_type zs_buf_len; + char_type zs_buf[BITS]; /* Temporary buffer if we need + to read more to accumulate + n_bits. */ + union { + struct { + char_type *zs_stackp; + int zs_finchar; + code_int zs_code, zs_oldcode, zs_incode; + int zs_roffset, zs_size; + char_type zs_gbuf[BITS]; + } r; /* Read parameters */ + } u; +} s_zstate_t; + +static code_int getcode(s_zstate_t *); +#if 0 +static int zclose(s_zstate_t *); +#endif +static void zinit(s_zstate_t *); +static int zread(s_zstate_t *); diff --git a/src/libs/freetype2/otlayout/otlayout.h b/src/libs/freetype2/otlayout/otlayout.h index 1afe9c7985..2cd67f568f 100644 --- a/src/libs/freetype2/otlayout/otlayout.h +++ b/src/libs/freetype2/otlayout/otlayout.h @@ -202,4 +202,4 @@ OTL_BEGIN_HEADER OTL_END_HEADER -#endif /* __OPENTYPE_LAYOUT_H__ */ +#endif /* __OPENTYPE_LAYOUT_H__ */ diff --git a/src/libs/freetype2/otlayout/otlbase.h b/src/libs/freetype2/otlayout/otlbase.h index d00fa682ea..563d3002d0 100644 --- a/src/libs/freetype2/otlayout/otlbase.h +++ b/src/libs/freetype2/otlayout/otlbase.h @@ -11,4 +11,4 @@ OTL_BEGIN_HEADER OTL_END_HEADER -#endif /* __OTL_BASE_H__ */ +#endif /* __OTL_BASE_H__ */ diff --git a/src/libs/freetype2/otlayout/otlcommn.c b/src/libs/freetype2/otlayout/otlcommn.c index 9d648367f7..742ff5b36e 100644 --- a/src/libs/freetype2/otlayout/otlcommn.c +++ b/src/libs/freetype2/otlayout/otlcommn.c @@ -937,4 +937,4 @@ type_count, type_funcs, valid ); } -/* END */ +/* END */ diff --git a/src/libs/freetype2/otlayout/otlcommn.h b/src/libs/freetype2/otlayout/otlcommn.h index 31c624a5ac..25914fb9f7 100644 --- a/src/libs/freetype2/otlayout/otlcommn.h +++ b/src/libs/freetype2/otlayout/otlcommn.h @@ -274,4 +274,4 @@ OTL_END_HEADER #endif /* __OTLCOMMN_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/otlayout/otlconf.h b/src/libs/freetype2/otlayout/otlconf.h index 1ba60cb2e2..3ef17a0799 100644 --- a/src/libs/freetype2/otlayout/otlconf.h +++ b/src/libs/freetype2/otlayout/otlconf.h @@ -75,4 +75,4 @@ /* */ -#endif /* __OT_LAYOUT_CONFIG_H__ */ +#endif /* __OT_LAYOUT_CONFIG_H__ */ diff --git a/src/libs/freetype2/otlayout/otlgdef.c b/src/libs/freetype2/otlayout/otlgdef.c index 6c5a163a2d..ff1c2a1e86 100644 --- a/src/libs/freetype2/otlayout/otlgdef.c +++ b/src/libs/freetype2/otlayout/otlgdef.c @@ -172,4 +172,4 @@ /* validate mark attach class */ otl_class_definition_validate( table + OTL_NEXT_USHORT( p ) ); } - + diff --git a/src/libs/freetype2/otlayout/otlgdef.h b/src/libs/freetype2/otlayout/otlgdef.h index db81aa216f..5046cc4364 100644 --- a/src/libs/freetype2/otlayout/otlgdef.h +++ b/src/libs/freetype2/otlayout/otlgdef.h @@ -11,4 +11,4 @@ OTL_BEGIN_HEADER OTL_END_HEADER -#endif /* __OTL_GDEF_H__ */ +#endif /* __OTL_GDEF_H__ */ diff --git a/src/libs/freetype2/otlayout/otlgpos.h b/src/libs/freetype2/otlayout/otlgpos.h index b079d9909c..1d10cab495 100644 --- a/src/libs/freetype2/otlayout/otlgpos.h +++ b/src/libs/freetype2/otlayout/otlgpos.h @@ -11,4 +11,4 @@ OTL_BEGIN_HEADER OTL_END_HEADER -#endif /* __OTL_GPOS_H__ */ +#endif /* __OTL_GPOS_H__ */ diff --git a/src/libs/freetype2/otlayout/otlgsub.c b/src/libs/freetype2/otlayout/otlgsub.c index aa720d34a8..13a8eae98d 100644 --- a/src/libs/freetype2/otlayout/otlgsub.c +++ b/src/libs/freetype2/otlayout/otlgsub.c @@ -87,7 +87,7 @@ OTL_Int index; OTL_Bool subst = 0; - if ( parser->context_len != 0xFFFF && parser->context_len < 1 ) + if ( parser->context_len != 0xFFFFU && parser->context_len < 1 ) goto Exit; gindex = otl_parser_get_gindex( parser ); @@ -107,7 +107,7 @@ { OTL_Int delta = OTL_NEXT_SHORT(p); - gindex = ( gindex + delta ) & 0xFFFF; + gindex = ( gindex + delta ) & 0xFFFFU; otl_parser_replace_1( parser, gindex ); subst = 1; } @@ -223,7 +223,7 @@ OTL_Int index; OTL_Bool subst = 0; - if ( context_len != 0xFFFF && context_len < 1 ) + if ( context_len != 0xFFFFU && context_len < 1 ) goto Exit; gindex = otl_parser_get_gindex( parser ); @@ -341,7 +341,7 @@ OTL_GSUB_Alternate alternate = parser->alternate; - if ( context_len != 0xFFFF && context_len < 1 ) + if ( context_len != 0xFFFFU && context_len < 1 ) goto Exit; if ( alternate == NULL ) @@ -864,4 +864,4 @@ otl_lookup_list_validate( table + lookups, 7, otl_gsub_validate_funcs, valid ); - } + } diff --git a/src/libs/freetype2/otlayout/otlgsub.h b/src/libs/freetype2/otlayout/otlgsub.h index f097d3b534..db5edecf12 100644 --- a/src/libs/freetype2/otlayout/otlgsub.h +++ b/src/libs/freetype2/otlayout/otlgsub.h @@ -23,4 +23,4 @@ OTL_BEGIN_HEADER OTL_END_HEADER -#endif /* __OTL_GSUB_H__ */ +#endif /* __OTL_GSUB_H__ */ diff --git a/src/libs/freetype2/otlayout/otlparse.c b/src/libs/freetype2/otlayout/otlparse.c index caa8f5b564..705c0c60fa 100644 --- a/src/libs/freetype2/otlayout/otlparse.c +++ b/src/libs/freetype2/otlayout/otlparse.c @@ -139,4 +139,4 @@ } - + diff --git a/src/libs/freetype2/otlayout/otlparse.h b/src/libs/freetype2/otlayout/otlparse.h index adaa0634de..92f34bfdc2 100644 --- a/src/libs/freetype2/otlayout/otlparse.h +++ b/src/libs/freetype2/otlayout/otlparse.h @@ -96,4 +96,4 @@ OTL_BEGIN_HEADER OTL_END_HEADER #endif /* __OTL_PARSER_H__ */ - + diff --git a/src/libs/freetype2/otlayout/otltable.h b/src/libs/freetype2/otlayout/otltable.h index 0441e15766..af7bd78a58 100644 --- a/src/libs/freetype2/otlayout/otltable.h +++ b/src/libs/freetype2/otlayout/otltable.h @@ -57,4 +57,4 @@ OTL_BEGIN_HEADER OTL_END_HEADER -#endif /* __OTL_TABLE_H__ */ +#endif /* __OTL_TABLE_H__ */ diff --git a/src/libs/freetype2/otlayout/otltags.h b/src/libs/freetype2/otlayout/otltags.h index 236bb9f1c8..d954b58514 100644 --- a/src/libs/freetype2/otlayout/otltags.h +++ b/src/libs/freetype2/otlayout/otltags.h @@ -85,4 +85,4 @@ OTL_SCRIPT_TAG( 'y','i',' ',' ', "Yi", YI ) #endif #undef OTL_FEATURE_TAG - + diff --git a/src/libs/freetype2/otlayout/otlutils.h b/src/libs/freetype2/otlayout/otlutils.h index 6341accf29..de50f66f07 100644 --- a/src/libs/freetype2/otlayout/otlutils.h +++ b/src/libs/freetype2/otlayout/otlutils.h @@ -30,4 +30,4 @@ OTL_BEGIN_HEADER OTL_END_HEADER -#endif /* __OTLAYOUT_UTILS_H__ */ +#endif /* __OTLAYOUT_UTILS_H__ */ diff --git a/src/libs/freetype2/pcf/Jamfile b/src/libs/freetype2/pcf/Jamfile index b126fa526f..bd9bb45699 100644 --- a/src/libs/freetype2/pcf/Jamfile +++ b/src/libs/freetype2/pcf/Jamfile @@ -10,7 +10,7 @@ UseFreeTypeHeaders ; if $(FT2_MULTI) { - _sources = pcfdriver pcfread pcfutil ; + _sources = pcfdrivr pcfread pcfutil ; } else { @@ -20,4 +20,5 @@ UseFreeTypeHeaders ; FT2_Library $(FT2_LIB) : $(_sources).c ; } -# end of src/pcf Jamfile +# end of src/pcf Jamfile + diff --git a/src/libs/freetype2/pcf/descrip.mms b/src/libs/freetype2/pcf/descrip.mms index 164b669f3a..a3fd23180f 100644 --- a/src/libs/freetype2/pcf/descrip.mms +++ b/src/libs/freetype2/pcf/descrip.mms @@ -32,4 +32,4 @@ OBJS=pcf.obj all : $(OBJS) library [--.lib]freetype.olb $(OBJS) -# EOF +# EOF diff --git a/src/libs/freetype2/pcf/module.mk b/src/libs/freetype2/pcf/module.mk index 2bb6f8faef..614c319208 100644 --- a/src/libs/freetype2/pcf/module.mk +++ b/src/libs/freetype2/pcf/module.mk @@ -29,4 +29,4 @@ add_pcf_driver: $(OPEN_DRIVER)pcf_driver_class$(CLOSE_DRIVER) $(ECHO_DRIVER)pcf $(ECHO_DRIVER_DESC)pcf bitmap fonts$(ECHO_DRIVER_DONE) -# EOF +# EOF diff --git a/src/libs/freetype2/pcf/pcf.c b/src/libs/freetype2/pcf/pcf.c index a43f363458..11d5b7b2a0 100644 --- a/src/libs/freetype2/pcf/pcf.c +++ b/src/libs/freetype2/pcf/pcf.c @@ -2,7 +2,7 @@ FreeType font driver for pcf fonts - Copyright 2000-2001 by + Copyright 2000-2001, 2003 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy @@ -31,6 +31,6 @@ THE SOFTWARE. #include <ft2build.h> #include "pcfutil.c" #include "pcfread.c" -#include "pcfdriver.c" +#include "pcfdrivr.c" -/* END */ +/* END */ diff --git a/src/libs/freetype2/pcf/pcf.h b/src/libs/freetype2/pcf/pcf.h index 3745623826..64acefc4ee 100644 --- a/src/libs/freetype2/pcf/pcf.h +++ b/src/libs/freetype2/pcf/pcf.h @@ -2,7 +2,7 @@ FreeType font driver for pcf fonts - Copyright (C) 2000-2001, 2002 by + Copyright (C) 2000, 2001, 2002, 2003 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy @@ -124,10 +124,10 @@ FT_BEGIN_HEADER } PCF_AccelRec, *PCF_Accel; - typedef struct PCD_EncodingRec_ + typedef struct PCF_EncodingRec_ { - FT_Long enc; - FT_Short glyph; + FT_Long enc; + FT_UShort glyph; } PCF_EncodingRec, *PCF_Encoding; @@ -234,4 +234,4 @@ FT_END_HEADER #endif /* __PCF_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/pcf/pcfdriver.c b/src/libs/freetype2/pcf/pcfdrivr.c similarity index 80% rename from src/libs/freetype2/pcf/pcfdriver.c rename to src/libs/freetype2/pcf/pcfdrivr.c index 480eb833b9..80f043f9eb 100644 --- a/src/libs/freetype2/pcf/pcfdriver.c +++ b/src/libs/freetype2/pcf/pcfdrivr.c @@ -1,8 +1,8 @@ -/* pcfdriver.c +/* pcfdrivr.c FreeType font driver for pcf files - Copyright (C) 2000-2001, 2002 by + Copyright (C) 2000, 2001, 2002, 2003, 2004 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy @@ -31,12 +31,12 @@ THE SOFTWARE. #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_OBJECTS_H #include FT_GZIP_H +#include FT_LZW_H #include FT_ERRORS_H #include FT_BDF_H #include "pcf.h" -#include "pcfdriver.h" -#include "pcfutil.h" +#include "pcfdrivr.h" #include "pcfread.h" #include "pcferror.h" @@ -44,6 +44,8 @@ THE SOFTWARE. #undef FT_COMPONENT #define FT_COMPONENT trace_pcfread +#include FT_SERVICE_BDF_H +#include FT_SERVICE_XFREE86_NAME_H typedef struct PCF_CMapRec_ { @@ -63,7 +65,7 @@ THE SOFTWARE. cmap->num_encodings = (FT_UInt)face->nencodings; cmap->encodings = face->encodings; - return FT_Err_Ok; + return PCF_Err_Ok; } @@ -212,7 +214,7 @@ THE SOFTWARE. FT_TRACE4(( "PCF_Face_Done: done face\n" )); - /* close gzip stream if any */ + /* close gzip/LZW stream if any */ if ( face->root.stream == &face->gzip_stream ) { FT_Stream_Close( &face->gzip_stream ); @@ -242,23 +244,47 @@ THE SOFTWARE. { FT_Error error2; - /* this didn't work, try gzip support !! */ + + /* this didn't work, try gzip support! */ error2 = FT_Stream_OpenGzip( &face->gzip_stream, stream ); - if ( error2 == FT_Err_Unimplemented_Feature ) + if ( FT_ERROR_BASE( error2 ) == FT_Err_Unimplemented_Feature ) goto Fail; error = error2; if ( error ) - goto Fail; + { + FT_Error error3; - face->gzip_source = stream; - face->root.stream = &face->gzip_stream; - stream = face->root.stream; + /* this didn't work, try LZW support! */ + error3 = FT_Stream_OpenLZW( &face->gzip_stream, stream ); + if ( FT_ERROR_BASE( error3 ) == FT_Err_Unimplemented_Feature ) + goto Fail; - error = pcf_load_font( stream, face ); - if ( error ) - goto Fail; + error = error3; + if ( error ) + goto Fail; + + face->gzip_source = stream; + face->root.stream = &face->gzip_stream; + + stream = face->root.stream; + + error = pcf_load_font( stream, face ); + if ( error ) + goto Fail; + } + else + { + face->gzip_source = stream; + face->root.stream = &face->gzip_stream; + + stream = face->root.stream; + + error = pcf_load_font( stream, face ); + if ( error ) + goto Fail; + } } /* set-up charmap */ @@ -273,10 +299,21 @@ THE SOFTWARE. if ( ( charset_registry != NULL ) && ( charset_encoding != NULL ) ) { - if ( !ft_strcmp( face->charset_registry, "ISO10646" ) || - ( !ft_strcmp( face->charset_registry, "ISO8859" ) && - !ft_strcmp( face->charset_encoding, "1" ) ) ) + char* s = face->charset_registry; + + + /* Uh, oh, compare first letters manually to avoid dependency + on locales. */ + if ( ( s[0] == 'i' || s[0] == 'I' ) && + ( s[1] == 's' || s[1] == 'S' ) && + ( s[2] == 'o' || s[2] == 'O' ) ) + { + s += 3; + if ( !ft_strcmp( s, "10646" ) || + ( !ft_strcmp( s, "8859" ) && + !ft_strcmp( face->charset_encoding, "1" ) ) ) unicode_charmap = 1; + } } { @@ -322,9 +359,9 @@ THE SOFTWARE. FT_TRACE4(( "rec %d - pres %d\n", size->metrics.y_ppem, - face->root.available_sizes->height )); + face->root.available_sizes->y_ppem >> 6 )); - if ( size->metrics.y_ppem == face->root.available_sizes->height ) + if ( size->metrics.y_ppem == face->root.available_sizes->y_ppem >> 6 ) { size->metrics.ascender = face->accel.fontAscent << 6; size->metrics.descender = face->accel.fontDescent * (-64); @@ -442,9 +479,9 @@ THE SOFTWARE. slot->bitmap_left = metric->leftSideBearing; slot->bitmap_top = metric->ascent; - slot->metrics.horiAdvance = metric->characterWidth << 6 ; - slot->metrics.horiBearingX = metric->leftSideBearing << 6 ; - slot->metrics.horiBearingY = metric->ascent << 6 ; + slot->metrics.horiAdvance = metric->characterWidth << 6; + slot->metrics.horiBearingX = metric->leftSideBearing << 6; + slot->metrics.horiBearingY = metric->ascent << 6; slot->metrics.width = ( metric->rightSideBearing - metric->leftSideBearing ) << 6; slot->metrics.height = bitmap->rows << 6; @@ -459,12 +496,19 @@ THE SOFTWARE. } + /* + * + * BDF SERVICE + * + */ + static FT_Error pcf_get_bdf_property( PCF_Face face, const char* prop_name, BDF_PropertyRec *aproperty ) { - PCF_Property prop; + PCF_Property prop; + prop = pcf_find_property( face, prop_name ); if ( prop != NULL ) @@ -476,29 +520,60 @@ THE SOFTWARE. } else { - /* apparently, the PCF driver loads all properties as signed integers ! - * this really doesn't seem to be a problem, because this is - * sufficient for any meaningful values - */ + /* Apparently, the PCF driver loads all properties as signed integers! + * This really doesn't seem to be a problem, because this is + * sufficient for any meaningful values. + */ aproperty->type = BDF_PROPERTY_TYPE_INTEGER; aproperty->u.integer = prop->value.integer; } return 0; } - return FT_Err_Invalid_Argument; + + return PCF_Err_Invalid_Argument; } + static FT_Error + pcf_get_charset_id( PCF_Face face, + const char* *acharset_encoding, + const char* *acharset_registry ) + { + *acharset_encoding = face->charset_encoding; + *acharset_registry = face->charset_registry; + + return 0; + } + + + static const FT_Service_BDFRec pcf_service_bdf = + { + (FT_BDF_GetCharsetIdFunc)pcf_get_charset_id, + (FT_BDF_GetPropertyFunc) pcf_get_bdf_property + }; + + + /* + * + * SERVICE LIST + * + */ + + static const FT_ServiceDescRec pcf_services[] = + { + { FT_SERVICE_ID_BDF, &pcf_service_bdf }, + { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_PCF }, + { NULL, NULL } + }; + + static FT_Module_Interface pcf_driver_requester( FT_Module module, const char* name ) { FT_UNUSED( module ); - if ( name && ft_strcmp( name, "get_bdf_property" ) == 0 ) - return (FT_Module_Interface) pcf_get_bdf_property; - - return NULL; + return ft_service_list_lookup( pcf_services, name ); } @@ -506,7 +581,8 @@ THE SOFTWARE. const FT_Driver_ClassRec pcf_driver_class = { { - ft_module_font_driver, + FT_MODULE_FONT_DRIVER | + FT_MODULE_DRIVER_NO_OUTLINES, sizeof ( FT_DriverRec ), "pcf", @@ -542,4 +618,4 @@ THE SOFTWARE. }; -/* END */ +/* END */ diff --git a/src/libs/freetype2/pcf/pcfdriver.h b/src/libs/freetype2/pcf/pcfdrivr.h similarity index 93% rename from src/libs/freetype2/pcf/pcfdriver.h rename to src/libs/freetype2/pcf/pcfdrivr.h index a4c8289db6..7ddf697e16 100644 --- a/src/libs/freetype2/pcf/pcfdriver.h +++ b/src/libs/freetype2/pcf/pcfdrivr.h @@ -1,4 +1,4 @@ -/* pcfdriver.h +/* pcfdrivr.h FreeType font driver for pcf fonts @@ -25,8 +25,8 @@ THE SOFTWARE. */ -#ifndef __PCFDRIVER_H__ -#define __PCFDRIVER_H__ +#ifndef __PCFDRIVR_H__ +#define __PCFDRIVR_H__ #include <ft2build.h> #include FT_INTERNAL_DRIVER_H @@ -38,7 +38,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PCFDRIVER_H__ */ +#endif /* __PCFDRIVR_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/pcf/pcferror.h b/src/libs/freetype2/pcf/pcferror.h index 486b121996..d75c067aa6 100644 --- a/src/libs/freetype2/pcf/pcferror.h +++ b/src/libs/freetype2/pcf/pcferror.h @@ -37,4 +37,4 @@ #endif /* __PCFERROR_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/pcf/pcfread.c b/src/libs/freetype2/pcf/pcfread.c index afbf272ecb..3beabbfb2f 100644 --- a/src/libs/freetype2/pcf/pcfread.c +++ b/src/libs/freetype2/pcf/pcfread.c @@ -2,7 +2,7 @@ FreeType font driver for pcf fonts - Copyright 2000-2001, 2002 by + Copyright 2000, 2001, 2002, 2003, 2004 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy @@ -32,7 +32,7 @@ THE SOFTWARE. #include FT_INTERNAL_OBJECTS_H #include "pcf.h" -#include "pcfdriver.h" +#include "pcfdrivr.h" #include "pcfread.h" #include "pcferror.h" @@ -49,7 +49,7 @@ THE SOFTWARE. #if defined( FT_DEBUG_LEVEL_TRACE ) - static const char* tableNames[] = + static const char* const tableNames[] = { "prop", "accl", "mtrcs", "bmps", "imtrcs", "enc", "swidth", "names", "accel" @@ -250,18 +250,22 @@ THE SOFTWARE. FT_ULong *aformat, FT_ULong *asize ) { - FT_Error error = 0; + FT_Error error = PCF_Err_Invalid_File_Format; FT_Int i; for ( i = 0; i < ntables; i++ ) if ( tables[i].type == type ) { - if ( stream->pos > tables[i].offset ) - return PCF_Err_Invalid_Stream_Skip; + if ( stream->pos > tables[i].offset ) { + error = PCF_Err_Invalid_Stream_Skip; + goto Fail; + } - if ( FT_STREAM_SKIP( tables[i].offset - stream->pos ) ) - return PCF_Err_Invalid_Stream_Skip; + if ( FT_STREAM_SKIP( tables[i].offset - stream->pos ) ) { + error = PCF_Err_Invalid_Stream_Skip; + goto Fail; + } *asize = tables[i].size; /* unused - to be removed */ *aformat = tables[i].format; @@ -269,7 +273,8 @@ THE SOFTWARE. return PCF_Err_Ok; } - return PCF_Err_Invalid_File_Format; + Fail: + return error; } @@ -857,6 +862,116 @@ THE SOFTWARE. } + static FT_Error + pcf_interpret_style( PCF_Face pcf ) + { + FT_Error error = PCF_Err_Ok; + FT_Face face = FT_FACE( pcf ); + FT_Memory memory = face->memory; + + PCF_Property prop; + + char *istr = NULL, *bstr = NULL; + char *sstr = NULL, *astr = NULL; + + int parts = 0, len = 0; + + + face->style_flags = 0; + + prop = pcf_find_property( pcf, "SLANT" ); + if ( prop && prop->isString && + ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' || + *(prop->value.atom) == 'I' || *(prop->value.atom) == 'i' ) ) + { + face->style_flags |= FT_STYLE_FLAG_ITALIC; + istr = ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' ) + ? (char *)"Oblique" + : (char *)"Italic"; + len += ft_strlen( istr ); + parts++; + } + + prop = pcf_find_property( pcf, "WEIGHT_NAME" ); + if ( prop && prop->isString && + ( *(prop->value.atom) == 'B' || *(prop->value.atom) == 'b' ) ) + { + face->style_flags |= FT_STYLE_FLAG_BOLD; + bstr = (char *)"Bold"; + len += ft_strlen( bstr ); + parts++; + } + + prop = pcf_find_property( pcf, "SETWIDTH_NAME" ); + if ( prop && prop->isString && + *(prop->value.atom) && + !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) + { + sstr = (char *)(prop->value.atom); + len += ft_strlen( sstr ); + parts++; + } + + prop = pcf_find_property( pcf, "ADD_STYLE_NAME" ); + if ( prop && prop->isString && + *(prop->value.atom) && + !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) + { + astr = (char *)(prop->value.atom); + len += ft_strlen( astr ); + parts++; + } + + if ( !parts || !len ) + face->style_name = (char *)"Regular"; + else + { + char *style, *s; + unsigned int i; + + + if ( FT_ALLOC( style, len + parts ) ) + return error; + + s = style; + + if ( astr ) + { + ft_strcpy( s, astr ); + for ( i = 0; i < ft_strlen( astr ); i++, s++ ) + if ( *s == ' ' ) + *s = '-'; /* replace spaces with dashes */ + *(s++) = ' '; + } + if ( bstr ) + { + ft_strcpy( s, bstr ); + s += ft_strlen( bstr ); + *(s++) = ' '; + } + if ( istr ) + { + ft_strcpy( s, istr ); + s += ft_strlen( istr ); + *(s++) = ' '; + } + if ( sstr ) + { + ft_strcpy( s, sstr ); + for ( i = 0; i < ft_strlen( sstr ); i++, s++ ) + if ( *s == ' ' ) + *s = '-'; /* replace spaces with dashes */ + *(s++) = ' '; + } + *(--s) = '\0'; /* overwrite last ' ', terminate the string */ + + face->style_name = style; /* allocated string */ + } + + return error; + } + + FT_LOCAL_DEF( FT_Error ) pcf_load_font( FT_Stream stream, PCF_Face face ) @@ -914,10 +1029,9 @@ THE SOFTWARE. { FT_Face root = FT_FACE( face ); PCF_Property prop; - int size_set = 0; - root->num_faces = 1; + root->num_faces = 1; root->face_index = 0; root->face_flags = FT_FACE_FLAG_FIXED_SIZES | FT_FACE_FLAG_HORIZONTAL | @@ -926,95 +1040,80 @@ THE SOFTWARE. if ( face->accel.constantWidth ) root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; - root->style_flags = 0; - prop = pcf_find_property( face, "SLANT" ); - if ( prop != NULL ) - if ( prop->isString ) - if ( ( *(prop->value.atom) == 'O' ) || - ( *(prop->value.atom) == 'I' ) ) - root->style_flags |= FT_STYLE_FLAG_ITALIC; - - prop = pcf_find_property( face, "WEIGHT_NAME" ); - if ( prop != NULL ) - if ( prop->isString ) - if ( *(prop->value.atom) == 'B' ) - root->style_flags |= FT_STYLE_FLAG_BOLD; - - root->style_name = (char *)"Regular"; - - if ( root->style_flags & FT_STYLE_FLAG_BOLD ) { - if ( root->style_flags & FT_STYLE_FLAG_ITALIC ) - root->style_name = (char *)"Bold Italic"; - else - root->style_name = (char *)"Bold"; - } - else if ( root->style_flags & FT_STYLE_FLAG_ITALIC ) - root->style_name = (char *)"Italic"; + if ( ( error = pcf_interpret_style( face ) ) != 0 ) + goto Exit; prop = pcf_find_property( face, "FAMILY_NAME" ); - if ( prop != NULL ) + if ( prop && prop->isString ) { - if ( prop->isString ) - { - int l = ft_strlen( prop->value.atom ) + 1; + int l = ft_strlen( prop->value.atom ) + 1; - if ( FT_NEW_ARRAY( root->family_name, l ) ) - goto Exit; - ft_strcpy( root->family_name, prop->value.atom ); - } + if ( FT_NEW_ARRAY( root->family_name, l ) ) + goto Exit; + ft_strcpy( root->family_name, prop->value.atom ); } else - root->family_name = 0; + root->family_name = NULL; - root->num_glyphs = face->nmetrics; + /* Note: We shift all glyph indices by +1 since we must + * respect the convention that glyph 0 always corresponds + * to the "missing glyph". + * + * This implies bumping the number of "available" glyphs by 1. + */ + root->num_glyphs = face->nmetrics + 1; root->num_fixed_sizes = 1; if ( FT_NEW_ARRAY( root->available_sizes, 1 ) ) goto Exit; - prop = pcf_find_property( face, "PIXEL_SIZE" ); - if ( prop != NULL ) { - root->available_sizes->height = - root->available_sizes->width = (FT_Short)( prop->value.integer ); + FT_Bitmap_Size* bsize = root->available_sizes; + FT_Short resolution_x = 0, resolution_y = 0; + + + FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) ); + + bsize->height = face->accel.fontAscent + face->accel.fontDescent; + + prop = pcf_find_property( face, "AVERAGE_WIDTH" ); + if ( prop ) + bsize->width = (FT_Short)( ( prop->value.integer + 5 ) / 10 ); + else + bsize->width = bsize->height * 2/3; - size_set = 1; - } - else - { prop = pcf_find_property( face, "POINT_SIZE" ); - if ( prop != NULL ) + if ( prop ) + /* convert from 722.7 decipoints to 72 points per inch */ + bsize->size = + (FT_Pos)( ( prop->value.integer * 64 * 7200 + 36135L ) / 72270L ); + + prop = pcf_find_property( face, "PIXEL_SIZE" ); + if ( prop ) + bsize->y_ppem = (FT_Short)prop->value.integer << 6; + + prop = pcf_find_property( face, "RESOLUTION_X" ); + if ( prop ) + resolution_x = (FT_Short)prop->value.integer; + + prop = pcf_find_property( face, "RESOLUTION_Y" ); + if ( prop ) + resolution_y = (FT_Short)prop->value.integer; + + if ( bsize->y_ppem == 0 ) { - PCF_Property xres, yres, avgw; - - - xres = pcf_find_property( face, "RESOLUTION_X" ); - yres = pcf_find_property( face, "RESOLUTION_Y" ); - avgw = pcf_find_property( face, "AVERAGE_WIDTH" ); - - if ( ( yres != NULL ) && ( xres != NULL ) ) - { - root->available_sizes->height = - (FT_Short)( prop->value.integer * - yres->value.integer / 720 ); - - root->available_sizes->width = - (FT_Short)( prop->value.integer * - xres->value.integer / 720 ); - - size_set = 1; - } + bsize->y_ppem = bsize->size; + if ( resolution_y ) + bsize->y_ppem = bsize->y_ppem * resolution_y / 72; } + if ( resolution_x && resolution_y ) + bsize->x_ppem = bsize->y_ppem * resolution_x / resolution_y; + else + bsize->x_ppem = bsize->y_ppem; } - if (size_set == 0 ) - { - root->available_sizes->width = 12; - root->available_sizes->height = 12; - } - - /* set-up charset */ + /* set up charset */ { PCF_Property charset_registry = 0, charset_encoding = 0; @@ -1022,23 +1121,19 @@ THE SOFTWARE. charset_registry = pcf_find_property( face, "CHARSET_REGISTRY" ); charset_encoding = pcf_find_property( face, "CHARSET_ENCODING" ); - if ( ( charset_registry != NULL ) && - ( charset_encoding != NULL ) ) + if ( charset_registry && charset_registry->isString && + charset_encoding && charset_encoding->isString ) { - if ( ( charset_registry->isString ) && - ( charset_encoding->isString ) ) - { - if ( FT_NEW_ARRAY( face->charset_encoding, - ft_strlen( charset_encoding->value.atom ) + 1 ) ) - goto Exit; + if ( FT_NEW_ARRAY( face->charset_encoding, + ft_strlen( charset_encoding->value.atom ) + 1 ) ) + goto Exit; - if ( FT_NEW_ARRAY( face->charset_registry, - ft_strlen( charset_registry->value.atom ) + 1 ) ) - goto Exit; + if ( FT_NEW_ARRAY( face->charset_registry, + ft_strlen( charset_registry->value.atom ) + 1 ) ) + goto Exit; - ft_strcpy( face->charset_registry, charset_registry->value.atom ); - ft_strcpy( face->charset_encoding, charset_encoding->value.atom ); - } + ft_strcpy( face->charset_registry, charset_registry->value.atom ); + ft_strcpy( face->charset_encoding, charset_encoding->value.atom ); } } } @@ -1055,4 +1150,4 @@ THE SOFTWARE. } -/* END */ +/* END */ diff --git a/src/libs/freetype2/pcf/pcfread.h b/src/libs/freetype2/pcf/pcfread.h index 6ac7345fdf..c9524f1346 100644 --- a/src/libs/freetype2/pcf/pcfread.h +++ b/src/libs/freetype2/pcf/pcfread.h @@ -2,7 +2,7 @@ FreeType font driver for pcf fonts - Copyright 2000-2001 by + Copyright 2003 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy @@ -39,7 +39,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PCFUTIL_H__ */ +#endif /* __PCFREAD_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/pcf/pcfutil.c b/src/libs/freetype2/pcf/pcfutil.c index a477cb8bcd..ddaca35fd9 100644 --- a/src/libs/freetype2/pcf/pcfutil.c +++ b/src/libs/freetype2/pcf/pcfutil.c @@ -25,6 +25,8 @@ in this Software without prior written authorization from The Open Group. * Author: Keith Packard, MIT X Consortium */ +/* Modified for use with FreeType */ + #include <ft2build.h> #include "pcfutil.h" @@ -72,7 +74,7 @@ in this Software without prior written authorization from The Open Group. * Invert bit order within each BYTE of an array. */ - void + static void BitOrderInvert( unsigned char* buf, int nbytes ) { @@ -88,7 +90,7 @@ in this Software without prior written authorization from The Open Group. * Invert byte order within each 16-bits of an array. */ - void + static void TwoByteSwap( unsigned char* buf, int nbytes ) { @@ -107,7 +109,7 @@ in this Software without prior written authorization from The Open Group. * Invert byte order within each 32-bits of an array. */ - void + static void FourByteSwap( unsigned char* buf, int nbytes ) { @@ -127,89 +129,4 @@ in this Software without prior written authorization from The Open Group. } - /* - * Repad a bitmap. - */ - - int - RepadBitmap( char* pSrc, - char* pDst, - unsigned int srcPad, - unsigned int dstPad, - int width, - int height ) - { - int srcWidthBytes, dstWidthBytes; - int row, col; - char *pTmpSrc, *pTmpDst; - - - switch ( srcPad ) - { - case 1: - srcWidthBytes = ( width + 7 ) >> 3; - break; - - case 2: - srcWidthBytes = ( ( width + 15 ) >> 4 ) << 1; - break; - - case 4: - srcWidthBytes = ( ( width + 31 ) >> 5 ) << 2; - break; - - case 8: - srcWidthBytes = ( ( width + 63 ) >> 6 ) << 3; - break; - - default: - return 0; - } - - switch ( dstPad ) - { - case 1: - dstWidthBytes = ( width + 7 ) >> 3; - break; - - case 2: - dstWidthBytes = ( ( width + 15 ) >> 4 ) << 1; - break; - - case 4: - dstWidthBytes = ( ( width + 31 ) >> 5 ) << 2; - break; - - case 8: - dstWidthBytes = ( ( width + 63 ) >> 6 ) << 3; - break; - - default: - return 0; - } - - width = srcWidthBytes; - if ( width > dstWidthBytes ) - width = dstWidthBytes; - - pTmpSrc= pSrc; - pTmpDst= pDst; - - for ( row = 0; row < height; row++ ) - { - for ( col = 0; col < width; col++ ) - *pTmpDst++ = *pTmpSrc++; - - while ( col < dstWidthBytes ) - { - *pTmpDst++ = '\0'; - col++; - } - pTmpSrc += srcWidthBytes - width; - } - - return dstWidthBytes * height; - } - - -/* END */ +/* END */ diff --git a/src/libs/freetype2/pcf/pcfutil.h b/src/libs/freetype2/pcf/pcfutil.h index dca88c6a1e..017c515baa 100644 --- a/src/libs/freetype2/pcf/pcfutil.h +++ b/src/libs/freetype2/pcf/pcfutil.h @@ -2,7 +2,7 @@ FreeType font driver for pcf fonts - Copyright 2000-2001 by + Copyright 2000, 2001, 2004 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy @@ -32,27 +32,20 @@ THE SOFTWARE. #include <ft2build.h> - void + static void BitOrderInvert( unsigned char* buf, int nbytes); - void + static void TwoByteSwap( unsigned char* buf, int nbytes); - void + static void FourByteSwap( unsigned char* buf, int nbytes); - int - RepadBitmap( char* pSrc, - char* pDst, - unsigned int srcPad, - unsigned int dstPad, - int width, - int height); #endif /* __PCFUTIL_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/pcf/readme b/src/libs/freetype2/pcf/readme index e1a5372119..75f49e1427 100644 --- a/src/libs/freetype2/pcf/readme +++ b/src/libs/freetype2/pcf/readme @@ -111,4 +111,4 @@ Credits Keith Packard wrote the pcf driver found in XFree86. His work is at the same time the specification and the sample implementation of the -PCF format. Undoubtedly, this driver is inspired from his work. +PCF format. Undoubtedly, this driver is inspired from his work. diff --git a/src/libs/freetype2/pcf/rules.mk b/src/libs/freetype2/pcf/rules.mk index c993a1986a..1ad4ba897a 100644 --- a/src/libs/freetype2/pcf/rules.mk +++ b/src/libs/freetype2/pcf/rules.mk @@ -3,7 +3,7 @@ # -# Copyright (C) 2000, 2001 by +# Copyright (C) 2000, 2001, 2003 by # Francesco Zappa Nardelli # # Permission is hereby granted, free of charge, to any person obtaining a copy @@ -27,49 +27,48 @@ # pcf driver directory # -PCF_DIR := $(SRC_)pcf -PCF_DIR_ := $(PCF_DIR)$(SEP) +PCF_DIR := $(SRC_DIR)/pcf -PCF_COMPILE := $(FT_COMPILE) $I$(PCF_DIR) +PCF_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(PCF_DIR)) # pcf driver sources (i.e., C files) # -PCF_DRV_SRC := $(PCF_DIR_)pcfread.c \ - $(PCF_DIR_)pcfdriver.c \ - $(PCF_DIR_)pcfutil.c +PCF_DRV_SRC := $(PCF_DIR)/pcfread.c \ + $(PCF_DIR)/pcfdrivr.c \ + $(PCF_DIR)/pcfutil.c # pcf driver headers # -PCF_DRV_H := $(PCF_DIR_)pcf.h \ - $(PCF_DIR_)pcfdriver.h \ - $(PCF_DIR_)pcfutil.h \ - $(PCF_DIR_)pcferror.h +PCF_DRV_H := $(PCF_DIR)/pcf.h \ + $(PCF_DIR)/pcfdrivr.h \ + $(PCF_DIR)/pcfutil.h \ + $(PCF_DIR)/pcferror.h # pcf driver object(s) # # PCF_DRV_OBJ_M is used during `multi' builds # PCF_DRV_OBJ_S is used during `single' builds # -PCF_DRV_OBJ_M := $(PCF_DRV_SRC:$(PCF_DIR_)%.c=$(OBJ_)%.$O) -PCF_DRV_OBJ_S := $(OBJ_)pcf.$O +PCF_DRV_OBJ_M := $(PCF_DRV_SRC:$(PCF_DIR)/%.c=$(OBJ_DIR)/%.$O) +PCF_DRV_OBJ_S := $(OBJ_DIR)/pcf.$O -# Windows driver source file for single build +# pcf driver source file for single build # -PCF_DRV_SRC_S := $(PCF_DIR_)pcf.c +PCF_DRV_SRC_S := $(PCF_DIR)/pcf.c # pcf driver - single object # $(PCF_DRV_OBJ_S): $(PCF_DRV_SRC_S) $(PCF_DRV_SRC) $(FREETYPE_H) $(PCF_DRV_H) - $(PCF_COMPILE) $T$@ $(PCF_DRV_SRC_S) + $(PCF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(PCF_DRV_SRC_S)) # pcf driver - multiple objects # -$(OBJ_)%.$O: $(PCF_DIR_)%.c $(FREETYPE_H) $(PCF_DRV_H) - $(PCF_COMPILE) $T$@ $< +$(OBJ_DIR)/%.$O: $(PCF_DIR)/%.c $(FREETYPE_H) $(PCF_DRV_H) + $(PCF_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) # update main driver object lists @@ -77,4 +76,5 @@ $(OBJ_)%.$O: $(PCF_DIR_)%.c $(FREETYPE_H) $(PCF_DRV_H) DRV_OBJS_S += $(PCF_DRV_OBJ_S) DRV_OBJS_M += $(PCF_DRV_OBJ_M) -# EOF + +# EOF diff --git a/src/libs/freetype2/pfr/descrip.mms b/src/libs/freetype2/pfr/descrip.mms index 0c0a8550b9..75178d0eff 100644 --- a/src/libs/freetype2/pfr/descrip.mms +++ b/src/libs/freetype2/pfr/descrip.mms @@ -20,4 +20,4 @@ OBJS=pfr.obj all : $(OBJS) library [--.lib]freetype.olb $(OBJS) -# EOF +# EOF diff --git a/src/libs/freetype2/pfr/module.mk b/src/libs/freetype2/pfr/module.mk index eb6cff2c40..3da0d5a3c7 100644 --- a/src/libs/freetype2/pfr/module.mk +++ b/src/libs/freetype2/pfr/module.mk @@ -19,4 +19,4 @@ add_pfr_driver: $(OPEN_DRIVER)pfr_driver_class$(CLOSE_DRIVER) $(ECHO_DRIVER)pfr $(ECHO_DRIVER_DESC)PFR/TrueDoc font files with extension *.pfr$(ECHO_DRIVER_DONE) -# EOF +# EOF diff --git a/src/libs/freetype2/pfr/pfr.c b/src/libs/freetype2/pfr/pfr.c index 2dbf2983b9..eb2c4edb7e 100644 --- a/src/libs/freetype2/pfr/pfr.c +++ b/src/libs/freetype2/pfr/pfr.c @@ -26,4 +26,4 @@ #include "pfrdrivr.c" #include "pfrsbit.c" -/* END */ +/* END */ diff --git a/src/libs/freetype2/pfr/pfrcmap.c b/src/libs/freetype2/pfr/pfrcmap.c index 804da8f343..de6c5a07cf 100644 --- a/src/libs/freetype2/pfr/pfrcmap.c +++ b/src/libs/freetype2/pfr/pfrcmap.c @@ -155,4 +155,4 @@ }; -/* END */ +/* END */ diff --git a/src/libs/freetype2/pfr/pfrcmap.h b/src/libs/freetype2/pfr/pfrcmap.h index 035fc05438..d77813e3c8 100644 --- a/src/libs/freetype2/pfr/pfrcmap.h +++ b/src/libs/freetype2/pfr/pfrcmap.h @@ -43,4 +43,4 @@ FT_END_HEADER #endif /* __PFRCMAP_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/pfr/pfrdrivr.c b/src/libs/freetype2/pfr/pfrdrivr.c index e4ef2ca3c5..4e0d6fdb47 100644 --- a/src/libs/freetype2/pfr/pfrdrivr.c +++ b/src/libs/freetype2/pfr/pfrdrivr.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR driver interface (body). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,10 +19,13 @@ #include <ft2build.h> #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_PFR_H +#include FT_SERVICE_PFR_H +#include FT_SERVICE_XFREE86_NAME_H #include "pfrdrivr.h" #include "pfrobjs.h" +#include "pfrerror.h" + static FT_Error pfr_get_kerning( PFR_Face face, @@ -30,44 +33,49 @@ FT_UInt right, FT_Vector *avector ) { - FT_Error error; + PFR_PhyFont phys = &face->phy_font; - error = pfr_face_get_kerning( face, left, right, avector ); - if ( !error ) + + pfr_face_get_kerning( face, left, right, avector ); + + /* convert from metrics to outline units when necessary */ + if ( phys->outline_resolution != phys->metrics_resolution ) { - PFR_PhyFont phys = &face->phy_font; + if ( avector->x != 0 ) + avector->x = FT_MulDiv( avector->x, phys->outline_resolution, + phys->metrics_resolution ); - /* convert from metrics to outline units when necessary */ - if ( phys->outline_resolution != phys->metrics_resolution ) - { - if ( avector->x != 0 ) - avector->x = FT_MulDiv( avector->x, phys->outline_resolution, - phys->metrics_resolution ); - - if ( avector->y != 0 ) - avector->y = FT_MulDiv( avector->x, phys->outline_resolution, - phys->metrics_resolution ); - } + if ( avector->y != 0 ) + avector->y = FT_MulDiv( avector->x, phys->outline_resolution, + phys->metrics_resolution ); } - return error; + + return PFR_Err_Ok; } - static FT_Error - pfr_get_advance( PFR_Face face, - FT_UInt gindex, - FT_Pos *aadvance ) - { - FT_Error error = FT_Err_Bad_Argument; + /* + * PFR METRICS SERVICE + * + */ - *aadvance = 0; + static FT_Error + pfr_get_advance( PFR_Face face, + FT_UInt gindex, + FT_Pos *anadvance ) + { + FT_Error error = PFR_Err_Bad_Argument; + + + *anadvance = 0; if ( face ) { - PFR_PhyFont phys = &face->phy_font; + PFR_PhyFont phys = &face->phy_font; + if ( gindex < phys->num_chars ) { - *aadvance = phys->chars[ gindex ].advance; + *anadvance = phys->chars[gindex].advance; error = 0; } } @@ -78,17 +86,18 @@ static FT_Error pfr_get_metrics( PFR_Face face, - FT_UInt *aoutline_resolution, + FT_UInt *anoutline_resolution, FT_UInt *ametrics_resolution, FT_Fixed *ametrics_x_scale, FT_Fixed *ametrics_y_scale ) { - PFR_PhyFont phys = &face->phy_font; + PFR_PhyFont phys = &face->phy_font; FT_Fixed x_scale, y_scale; FT_Size size = face->root.size; - if ( aoutline_resolution ) - *aoutline_resolution = phys->outline_resolution; + + if ( anoutline_resolution ) + *anoutline_resolution = phys->outline_resolution; if ( ametrics_resolution ) *ametrics_resolution = phys->metrics_resolution; @@ -111,25 +120,48 @@ if ( ametrics_y_scale ) *ametrics_y_scale = y_scale; - return 0; + return PFR_Err_Ok; } FT_CALLBACK_TABLE_DEF - const FT_PFR_ServiceRec pfr_service_rec = + const FT_Service_PfrMetricsRec pfr_metrics_service_rec = { - (FT_PFR_GetMetricsFunc) pfr_get_metrics, - (FT_PFR_GetKerningFunc) pfr_get_kerning, - (FT_PFR_GetAdvanceFunc) pfr_get_advance + (FT_PFR_GetMetricsFunc)pfr_get_metrics, + (FT_PFR_GetKerningFunc)pfr_face_get_kerning, + (FT_PFR_GetAdvanceFunc)pfr_get_advance }; + /* + * SERVICE LIST + * + */ + + static const FT_ServiceDescRec pfr_services[] = + { + { FT_SERVICE_ID_PFR_METRICS, &pfr_metrics_service_rec }, + { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_PFR }, + { NULL, NULL } + }; + + + static FT_Module_Interface + pfr_get_service( FT_Driver driver, + const FT_String* service_id ) + { + FT_UNUSED( driver ); + + return ft_service_list_lookup( pfr_services, service_id ); + } + + FT_CALLBACK_TABLE_DEF const FT_Driver_ClassRec pfr_driver_class = { { - ft_module_font_driver | - ft_module_driver_scalable, + FT_MODULE_FONT_DRIVER | + FT_MODULE_DRIVER_SCALABLE, sizeof( FT_DriverRec ), @@ -137,32 +169,32 @@ 0x10000L, 0x20000L, - (FT_PFR_Service) &pfr_service_rec, /* format interface */ + NULL, (FT_Module_Constructor)NULL, (FT_Module_Destructor) NULL, - (FT_Module_Requester) NULL + (FT_Module_Requester) pfr_get_service }, sizeof( PFR_FaceRec ), sizeof( PFR_SizeRec ), sizeof( PFR_SlotRec ), - (FT_Face_InitFunc) pfr_face_init, - (FT_Face_DoneFunc) pfr_face_done, - (FT_Size_InitFunc) NULL, - (FT_Size_DoneFunc) NULL, - (FT_Slot_InitFunc) pfr_slot_init, - (FT_Slot_DoneFunc) pfr_slot_done, + (FT_Face_InitFunc) pfr_face_init, + (FT_Face_DoneFunc) pfr_face_done, + (FT_Size_InitFunc) NULL, + (FT_Size_DoneFunc) NULL, + (FT_Slot_InitFunc) pfr_slot_init, + (FT_Slot_DoneFunc) pfr_slot_done, - (FT_Size_ResetPointsFunc) NULL, - (FT_Size_ResetPixelsFunc) NULL, - (FT_Slot_LoadFunc) pfr_slot_load, + (FT_Size_ResetPointsFunc)NULL, + (FT_Size_ResetPixelsFunc)NULL, + (FT_Slot_LoadFunc) pfr_slot_load, - (FT_Face_GetKerningFunc) pfr_get_kerning, - (FT_Face_AttachFunc) 0, - (FT_Face_GetAdvancesFunc) 0 + (FT_Face_GetKerningFunc) pfr_get_kerning, + (FT_Face_AttachFunc) 0, + (FT_Face_GetAdvancesFunc)0 }; -/* END */ +/* END */ diff --git a/src/libs/freetype2/pfr/pfrdrivr.h b/src/libs/freetype2/pfr/pfrdrivr.h index 70cd05adb0..36f1205b77 100644 --- a/src/libs/freetype2/pfr/pfrdrivr.h +++ b/src/libs/freetype2/pfr/pfrdrivr.h @@ -36,4 +36,4 @@ FT_END_HEADER #endif /* __PFRDRIVR_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/pfr/pfrerror.h b/src/libs/freetype2/pfr/pfrerror.h index bd4e57f30d..2e1c401dd2 100644 --- a/src/libs/freetype2/pfr/pfrerror.h +++ b/src/libs/freetype2/pfr/pfrerror.h @@ -37,4 +37,4 @@ #endif /* __PFRERROR_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/pfr/pfrgload.c b/src/libs/freetype2/pfr/pfrgload.c index 4f01260b26..87ba6846e8 100644 --- a/src/libs/freetype2/pfr/pfrgload.c +++ b/src/libs/freetype2/pfr/pfrgload.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR glyph loader (body). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -198,7 +198,7 @@ /* indicate that a new contour has started */ glyph->path_begun = 1; - /* check that there is room for a new contour and a new point */ + /* check that there is space for a new contour and a new point */ error = FT_GlyphLoader_CheckPoints( loader, 1, 1 ); if ( !error ) /* add new start point */ @@ -276,7 +276,7 @@ /* re-allocate array when necessary */ if ( count > glyph->max_xy_control ) { - FT_UInt new_max = ( count + 7 ) & -8; + FT_UInt new_max = FT_PAD_CEIL( count, 8 ); if ( FT_RENEW_ARRAY( glyph->x_control, @@ -798,4 +798,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/pfr/pfrgload.h b/src/libs/freetype2/pfr/pfrgload.h index 5ee2ac1f42..7cc7a8702a 100644 --- a/src/libs/freetype2/pfr/pfrgload.h +++ b/src/libs/freetype2/pfr/pfrgload.h @@ -46,4 +46,4 @@ FT_END_HEADER #endif /* __PFRGLOAD_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/pfr/pfrload.c b/src/libs/freetype2/pfr/pfrload.c index f32d1f9711..19ced45d13 100644 --- a/src/libs/freetype2/pfr/pfrload.c +++ b/src/libs/freetype2/pfr/pfrload.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR loader (body). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -153,7 +153,7 @@ pfr_header_load( PFR_Header header, FT_Stream stream ) { - FT_Error error; + FT_Error error; /* read header directly */ @@ -201,9 +201,9 @@ FT_UInt32 section_offset, FT_UInt *acount ) { - FT_Error error; - FT_UInt count; - FT_UInt result = 0; + FT_Error error; + FT_UInt count; + FT_UInt result = 0; if ( FT_STREAM_SEEK( section_offset ) || FT_READ_USHORT( count ) ) @@ -239,8 +239,8 @@ return PFR_Err_Invalid_Argument; if ( FT_STREAM_SKIP( idx * 5 ) || - FT_READ_USHORT( size ) || - FT_READ_UOFF3 ( offset ) ) + FT_READ_USHORT( size ) || + FT_READ_UOFF3 ( offset ) ) goto Exit; /* save logical font size and offset */ @@ -365,7 +365,8 @@ /* re-allocate when needed */ if ( phy_font->num_strikes + count > phy_font->max_strikes ) { - FT_UInt new_max = (phy_font->num_strikes + count + 3) & -4; + FT_UInt new_max = FT_PAD_CEIL( phy_font->num_strikes + count, 4 ); + if ( FT_RENEW_ARRAY( phy_font->strikes, phy_font->num_strikes, @@ -432,30 +433,30 @@ } - /* load font ID, this is a so-called "unique" name that is rather - * long and descriptive (like "Tiresias ScreenFont v7.51"). - * - * note that a PFR font's family name is contained in an *undocumented* - * string of the "auxiliary data" portion of a physical font record. this - * may also contain the "real" style name ! - * - * if no family name is present, the font id is used instead for the - * family - */ + /* Load font ID. This is a so-called "unique" name that is rather + * long and descriptive (like "Tiresias ScreenFont v7.51"). + * + * Note that a PFR font's family name is contained in an *undocumented* + * string of the "auxiliary data" portion of a physical font record. This + * may also contain the "real" style name! + * + * If no family name is present, the font ID is used instead for the + * family. + */ FT_CALLBACK_DEF( FT_Error ) pfr_extra_item_load_font_id( FT_Byte* p, FT_Byte* limit, PFR_PhyFont phy_font ) { - FT_Error error = 0; - FT_Memory memory = phy_font->memory; - FT_UInt len = (FT_UInt)( limit - p ); + FT_Error error = 0; + FT_Memory memory = phy_font->memory; + FT_PtrDist len = limit - p; if ( phy_font->font_id != NULL ) goto Exit; - if ( FT_ALLOC( phy_font->font_id, len+1 ) ) + if ( FT_ALLOC( phy_font->font_id, len + 1 ) ) goto Exit; /* copy font ID name, and terminate it for safety */ @@ -510,89 +511,6 @@ } -#if 0 - - /* load kerning pair data */ - FT_CALLBACK_DEF( FT_Error ) - pfr_extra_item_load_kerning_pairs( FT_Byte* p, - FT_Byte* limit, - PFR_PhyFont phy_font ) - { - FT_Int count; - FT_UShort base_adj; - FT_UInt flags; - FT_UInt num_pairs; - PFR_KernPair pairs; - FT_Error error = 0; - FT_Memory memory = phy_font->memory; - - - /* allocate a new kerning item */ - /* XXX: there may be multiple extra items for kerning */ - if ( phy_font->kern_pairs != NULL ) - goto Exit; - - FT_TRACE2(( "pfr_extra_item_load_kerning_pairs()\n" )); - - PFR_CHECK( 4 ); - - num_pairs = PFR_NEXT_BYTE( p ); - base_adj = PFR_NEXT_SHORT( p ); - flags = PFR_NEXT_BYTE( p ); - -#ifndef PFR_CONFIG_NO_CHECKS - count = 3; - - if ( flags & PFR_KERN_2BYTE_CHAR ) - count += 2; - - if ( flags & PFR_KERN_2BYTE_ADJ ) - count += 1; - - PFR_CHECK( num_pairs * count ); -#endif - - if ( FT_NEW_ARRAY( pairs, num_pairs ) ) - goto Exit; - - phy_font->num_kern_pairs = num_pairs; - phy_font->kern_pairs = pairs; - - for (count = num_pairs ; count > 0; count--, pairs++ ) - { - if ( flags & PFR_KERN_2BYTE_CHAR ) - { - pairs->glyph1 = PFR_NEXT_USHORT( p ); - pairs->glyph2 = PFR_NEXT_USHORT( p ); - } - else - { - pairs->glyph1 = PFR_NEXT_BYTE( p ); - pairs->glyph2 = PFR_NEXT_BYTE( p ); - } - - if ( flags & PFR_KERN_2BYTE_ADJ ) - pairs->kerning.x = base_adj + PFR_NEXT_SHORT( p ); - else - pairs->kerning.x = base_adj + PFR_NEXT_INT8( p ); - - pairs->kerning.y = 0; - - FT_TRACE2(( "kerning %d <-> %d : %ld\n", - pairs->glyph1, pairs->glyph2, pairs->kerning.x )); - } - - Exit: - return error; - - Too_Short: - error = PFR_Err_Invalid_Table; - FT_ERROR(( "pfr_extra_item_load_kerning_pairs: " - "invalid kerning pairs table\n" )); - goto Exit; - } - -#else /* 0 */ /* load kerning pair data */ FT_CALLBACK_DEF( FT_Error ) @@ -689,22 +607,161 @@ "invalid kerning pairs table\n" )); goto Exit; } -#endif /* 0 */ + + + /* + * The kerning data embedded in a PFR font are (charcode,charcode) + * pairs; we need to translate them to (gindex,gindex) and sort + * the resulting array. + */ + static FT_UInt + pfr_get_gindex( PFR_Char chars, + FT_UInt count, + FT_UInt charcode ) + { + FT_UInt min = 0; + FT_UInt max = count; + + + while ( min < max ) + { + FT_UInt mid = ( min + max ) >> 1; + PFR_Char c = chars + mid; + + + if ( c->char_code == charcode ) + return mid + 1; + + if ( c->char_code < charcode ) + min = mid + 1; + else + max = mid; + } + return 0; + } + + + FT_CALLBACK_DEF( int ) + pfr_compare_kern_pairs( const void* pair1, + const void* pair2 ) + { + FT_UInt32 p1 = PFR_KERN_PAIR_INDEX( (PFR_KernPair)pair1 ); + FT_UInt32 p2 = PFR_KERN_PAIR_INDEX( (PFR_KernPair)pair2 ); + + + if ( p1 < p2 ) + return -1; + if ( p1 > p2 ) + return 1; + return 0; + } + + + static FT_Error + pfr_sort_kerning_pairs( FT_Stream stream, + PFR_PhyFont phy_font ) + { + FT_Error error; + FT_Memory memory = stream->memory; + PFR_KernPair pairs; + PFR_KernItem item; + PFR_Char chars = phy_font->chars; + FT_UInt num_chars = phy_font->num_chars; + FT_UInt count; + + + /* create kerning pairs array + */ + if ( FT_NEW_ARRAY( phy_font->kern_pairs, phy_font->num_kern_pairs ) ) + goto Exit; + + /* load all kerning items into the array, + * converting character codes into glyph indices + */ + pairs = phy_font->kern_pairs; + item = phy_font->kern_items; + count = 0; + + for ( ; item; item = item->next ) + { + FT_UInt limit = count + item->pair_count; + FT_Byte* p; + + + if ( limit > phy_font->num_kern_pairs ) + { + error = PFR_Err_Invalid_Table; + goto Exit; + } + + if ( FT_STREAM_SEEK( item->offset ) || + FT_FRAME_ENTER( item->pair_count * item->pair_size ) ) + goto Exit; + + p = stream->cursor; + + for ( ; count < limit; count++ ) + { + PFR_KernPair pair = pairs + count; + FT_UInt char1, char2; + FT_Int kerning; + + + if ( item->flags & PFR_KERN_2BYTE_CHAR ) + { + char1 = FT_NEXT_USHORT( p ); + char2 = FT_NEXT_USHORT( p ); + } + else + { + char1 = FT_NEXT_BYTE( p ); + char2 = FT_NEXT_BYTE( p ); + } + + if ( item->flags & PFR_KERN_2BYTE_ADJ ) + kerning = item->base_adj + FT_NEXT_SHORT( p ); + else + kerning = item->base_adj + FT_NEXT_CHAR( p ); + + pair->glyph1 = pfr_get_gindex( chars, num_chars, char1 ); + pair->glyph2 = pfr_get_gindex( chars, num_chars, char2 ); + pair->kerning = kerning; + } + + FT_FRAME_EXIT(); + } + + /* sort the resulting array + */ + ft_qsort( pairs, count, + sizeof ( PFR_KernPairRec ), + pfr_compare_kern_pairs ); + + Exit: + if ( error ) + { + /* disable kerning data in case of error + */ + phy_font->num_kern_pairs = 0; + } + + return error; + } static const PFR_ExtraItemRec pfr_phy_font_extra_items[] = { - { 1, (PFR_ExtraItem_ParseFunc) pfr_extra_item_load_bitmap_info }, - { 2, (PFR_ExtraItem_ParseFunc) pfr_extra_item_load_font_id }, - { 3, (PFR_ExtraItem_ParseFunc) pfr_extra_item_load_stem_snaps }, - { 4, (PFR_ExtraItem_ParseFunc) pfr_extra_item_load_kerning_pairs }, + { 1, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_bitmap_info }, + { 2, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_font_id }, + { 3, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_stem_snaps }, + { 4, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_kerning_pairs }, { 0, NULL } }; - /* loads a name from the auxiliary data. Since this extracts undocumented - * strings from the font file, we need to be careful here - */ + /* Loads a name from the auxiliary data. Since this extracts undocumented + * strings from the font file, we need to be careful here. + */ static FT_Error pfr_aux_name_load( FT_Byte* p, FT_UInt len, @@ -715,13 +772,14 @@ FT_String* result = NULL; FT_UInt n, ok; - if ( len > 0 && p[len-1] == 0 ) + + if ( len > 0 && p[len - 1] == 0 ) len--; - /* check that each character is ASCII, that's to be sure - * to not load garbage.. - */ - ok = (len > 0); + /* check that each character is ASCII for making sure not to + load garbage + */ + ok = ( len > 0 ); for ( n = 0; n < len; n++ ) if ( p[n] < 32 || p[n] > 127 ) { @@ -731,7 +789,7 @@ if ( ok ) { - if ( FT_ALLOC( result, len+1 ) ) + if ( FT_ALLOC( result, len + 1 ) ) goto Exit; FT_MEM_COPY( result, p, len ); @@ -768,6 +826,7 @@ FT_FREE( phy_font->blue_values ); phy_font->num_blue_values = 0; + FT_FREE( phy_font->kern_pairs ); { PFR_KernItem item, next; @@ -787,7 +846,6 @@ } - FT_LOCAL_DEF( FT_Error ) pfr_phy_font_load( PFR_PhyFont phy_font, FT_Stream stream, @@ -842,9 +900,9 @@ goto Fail; } - /* in certain fonts, the auxiliary bytes contain interesting */ + /* In certain fonts, the auxiliary bytes contain interesting */ /* information. These are not in the specification but can be */ - /* guessed by looking at the content of a few PFR0 fonts */ + /* guessed by looking at the content of a few PFR0 fonts. */ PFR_CHECK( 3 ); num_aux = PFR_NEXT_ULONG( p ); @@ -853,6 +911,7 @@ FT_Byte* q = p; FT_Byte* q2; + PFR_CHECK( num_aux ); p += num_aux; @@ -860,58 +919,54 @@ { FT_UInt length, type; + if ( q + 4 > p ) break; - length = PFR_NEXT_USHORT(q); + length = PFR_NEXT_USHORT( q ); if ( length < 4 || length > num_aux ) break; q2 = q + length - 2; - type = PFR_NEXT_USHORT(q); + type = PFR_NEXT_USHORT( q ); switch ( type ) { - case 1: - { - /* this seems to correspond to the font's family name, - * padded to 16-bits with one zero when necessary - */ - error = pfr_aux_name_load( q, length-4U, memory, - &phy_font->family_name ); - if ( error ) - goto Exit; - } + case 1: + /* this seems to correspond to the font's family name, + * padded to 16-bits with one zero when necessary + */ + error = pfr_aux_name_load( q, length - 4U, memory, + &phy_font->family_name ); + if ( error ) + goto Exit; + break; + + case 2: + if ( q + 32 > q2 ) break; - case 2: - { - if ( q + 32 > q2 ) - break; + q += 10; + phy_font->ascent = PFR_NEXT_SHORT( q ); + phy_font->descent = PFR_NEXT_SHORT( q ); + phy_font->leading = PFR_NEXT_SHORT( q ); + q += 16; + break; - q += 10; - phy_font->ascent = PFR_NEXT_SHORT(q); - phy_font->descent = PFR_NEXT_SHORT(q); - phy_font->leading = PFR_NEXT_SHORT(q); - q += 16; - } - break; + case 3: + /* this seems to correspond to the font's style name, + * padded to 16-bits with one zero when necessary + */ + error = pfr_aux_name_load( q, length - 4U, memory, + &phy_font->style_name ); + if ( error ) + goto Exit; + break; - case 3: - { - /* this seems to correspond to the font's style name, - * padded to 16-bits with one zero when necessary - */ - error = pfr_aux_name_load( q, length-4U, memory, - &phy_font->style_name ); - if ( error ) - goto Exit; - } - break; - - default: - ; + default: + ; } + q = q2; num_aux -= length; } @@ -921,6 +976,7 @@ { FT_UInt n, count; + PFR_CHECK( 1 ); phy_font->num_blue_values = count = PFR_NEXT_BYTE( p ); @@ -1000,7 +1056,8 @@ } } - /* that's it !! */ + /* that's it! */ + Fail: FT_FRAME_EXIT(); @@ -1008,6 +1065,9 @@ phy_font->bct_offset = FT_STREAM_POS(); phy_font->cursor = NULL; + /* now sort kerning pairs */ + error = pfr_sort_kerning_pairs( stream, phy_font ); + Exit: return error; @@ -1018,4 +1078,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/pfr/pfrload.h b/src/libs/freetype2/pfr/pfrload.h index 2501138ac9..9e54b7d3fd 100644 --- a/src/libs/freetype2/pfr/pfrload.h +++ b/src/libs/freetype2/pfr/pfrload.h @@ -115,4 +115,4 @@ FT_END_HEADER #endif /* __PFRLOAD_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/pfr/pfrobjs.c b/src/libs/freetype2/pfr/pfrobjs.c index d6f4936d80..4c6179aa57 100644 --- a/src/libs/freetype2/pfr/pfrobjs.c +++ b/src/libs/freetype2/pfr/pfrobjs.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR object methods (body). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -41,7 +41,8 @@ FT_LOCAL_DEF( void ) pfr_face_done( PFR_Face face ) { - FT_Memory memory = face->root.driver->root.memory; + FT_Memory memory = face->root.driver->root.memory; + /* we don't want dangling pointers */ face->root.family_name = NULL; @@ -113,128 +114,127 @@ goto Exit; /* now load the physical font descriptor */ - error = pfr_phy_font_load( &face->phy_font, stream, - face->log_font.phys_offset, - face->log_font.phys_size ); - if ( error ) - goto Exit; + error = pfr_phy_font_load( &face->phy_font, stream, + face->log_font.phys_offset, + face->log_font.phys_size ); + if ( error ) + goto Exit; - /* now, set-up all root face fields */ - { - FT_Face root = FT_FACE( face ); - PFR_PhyFont phy_font = &face->phy_font; + /* now, set-up all root face fields */ + { + FT_Face root = FT_FACE( face ); + PFR_PhyFont phy_font = &face->phy_font; - root->face_index = face_index; - root->num_glyphs = phy_font->num_chars; - root->face_flags = FT_FACE_FLAG_SCALABLE; + root->face_index = face_index; + root->num_glyphs = phy_font->num_chars; + root->face_flags = FT_FACE_FLAG_SCALABLE; - if ( (phy_font->flags & PFR_PHY_PROPORTIONAL) == 0 ) - root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; + if ( (phy_font->flags & PFR_PHY_PROPORTIONAL) == 0 ) + root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; - if ( phy_font->flags & PFR_PHY_VERTICAL ) - root->face_flags |= FT_FACE_FLAG_VERTICAL; - else - root->face_flags |= FT_FACE_FLAG_HORIZONTAL; + if ( phy_font->flags & PFR_PHY_VERTICAL ) + root->face_flags |= FT_FACE_FLAG_VERTICAL; + else + root->face_flags |= FT_FACE_FLAG_HORIZONTAL; - if ( phy_font->num_strikes > 0 ) - root->face_flags |= FT_FACE_FLAG_FIXED_SIZES; + if ( phy_font->num_strikes > 0 ) + root->face_flags |= FT_FACE_FLAG_FIXED_SIZES; - if ( phy_font->num_kern_pairs > 0 ) - root->face_flags |= FT_FACE_FLAG_KERNING; + if ( phy_font->num_kern_pairs > 0 ) + root->face_flags |= FT_FACE_FLAG_KERNING; - /* if no family name was found in the "undocumented" auxiliary - * data, use the font ID instead. This sucks but is better than - * nothing + /* If no family name was found in the "undocumented" auxiliary + * data, use the font ID instead. This sucks but is better than + * nothing. */ - root->family_name = phy_font->family_name; - if ( root->family_name == NULL ) - root->family_name = phy_font->font_id; + root->family_name = phy_font->family_name; + if ( root->family_name == NULL ) + root->family_name = phy_font->font_id; /* note that the style name can be NULL in certain PFR fonts, * probably meaning "Regular" */ - root->style_name = phy_font->style_name; + root->style_name = phy_font->style_name; - root->num_fixed_sizes = 0; - root->available_sizes = 0; + root->num_fixed_sizes = 0; + root->available_sizes = 0; - root->bbox = phy_font->bbox; - root->units_per_EM = (FT_UShort)phy_font->outline_resolution; - root->ascender = (FT_Short) phy_font->bbox.yMax; - root->descender = (FT_Short) phy_font->bbox.yMin; - root->height = (FT_Short) - ( ( ( root->ascender - root->descender ) * 12 ) - / 10 ); + root->bbox = phy_font->bbox; + root->units_per_EM = (FT_UShort)phy_font->outline_resolution; + root->ascender = (FT_Short) phy_font->bbox.yMax; + root->descender = (FT_Short) phy_font->bbox.yMin; + root->height = (FT_Short)( + ( ( root->ascender - root->descender ) * 12 ) / 10 ); - if ( phy_font->num_strikes > 0 ) - { - FT_UInt n, count = phy_font->num_strikes; - FT_Bitmap_Size* size; - PFR_Strike strike; - FT_Memory memory = root->stream->memory; + if ( phy_font->num_strikes > 0 ) + { + FT_UInt n, count = phy_font->num_strikes; + FT_Bitmap_Size* size; + PFR_Strike strike; + FT_Memory memory = root->stream->memory; - if ( FT_NEW_ARRAY( root->available_sizes, count ) ) - goto Exit; + if ( FT_NEW_ARRAY( root->available_sizes, count ) ) + goto Exit; - size = root->available_sizes; - strike = phy_font->strikes; - for ( n = 0; n < count; n++, size++, strike++ ) - { - size->height = (FT_UShort) strike->y_ppm; - size->width = (FT_UShort) strike->x_ppm; - } - root->num_fixed_sizes = count; - } + size = root->available_sizes; + strike = phy_font->strikes; + for ( n = 0; n < count; n++, size++, strike++ ) + { + size->height = (FT_UShort)strike->y_ppm; + size->width = (FT_UShort)strike->x_ppm; + } + root->num_fixed_sizes = count; + } - /* now compute maximum advance width */ - if ( ( phy_font->flags & PFR_PHY_PROPORTIONAL ) == 0 ) - root->max_advance_width = (FT_Short)phy_font->standard_advance; - else - { - FT_Int max = 0; - FT_UInt count = phy_font->num_chars; - PFR_Char gchar = phy_font->chars; + /* now compute maximum advance width */ + if ( ( phy_font->flags & PFR_PHY_PROPORTIONAL ) == 0 ) + root->max_advance_width = (FT_Short)phy_font->standard_advance; + else + { + FT_Int max = 0; + FT_UInt count = phy_font->num_chars; + PFR_Char gchar = phy_font->chars; - for ( ; count > 0; count--, gchar++ ) - { - if ( max < gchar->advance ) - max = gchar->advance; - } + for ( ; count > 0; count--, gchar++ ) + { + if ( max < gchar->advance ) + max = gchar->advance; + } - root->max_advance_width = (FT_Short)max; - } + root->max_advance_width = (FT_Short)max; + } - root->max_advance_height = root->height; + root->max_advance_height = root->height; - root->underline_position = (FT_Short)( - root->units_per_EM / 10 ); - root->underline_thickness = (FT_Short)( root->units_per_EM / 30 ); + root->underline_position = (FT_Short)( - root->units_per_EM / 10 ); + root->underline_thickness = (FT_Short)( root->units_per_EM / 30 ); - /* create charmap */ - { - FT_CharMapRec charmap; + /* create charmap */ + { + FT_CharMapRec charmap; - charmap.face = root; - charmap.platform_id = 3; - charmap.encoding_id = 1; - charmap.encoding = FT_ENCODING_UNICODE; + charmap.face = root; + charmap.platform_id = 3; + charmap.encoding_id = 1; + charmap.encoding = FT_ENCODING_UNICODE; - FT_CMap_New( &pfr_cmap_class_rec, NULL, &charmap, NULL ); + FT_CMap_New( &pfr_cmap_class_rec, NULL, &charmap, NULL ); #if 0 - /* Select default charmap */ - if (root->num_charmaps) - root->charmap = root->charmaps[0]; + /* Select default charmap */ + if (root->num_charmaps) + root->charmap = root->charmaps[0]; #endif - } + } - /* check whether we've loaded any kerning pairs */ - if ( phy_font->num_kern_pairs ) - root->face_flags |= FT_FACE_FLAG_KERNING; - } + /* check whether we've loaded any kerning pairs */ + if ( phy_font->num_kern_pairs ) + root->face_flags |= FT_FACE_FLAG_KERNING; + } Exit: return error; @@ -279,7 +279,8 @@ FT_Outline* outline = &slot->root.outline; FT_ULong gps_offset; - if (gindex > 0) + + if ( gindex > 0 ) gindex--; /* check that the glyph index is correct */ @@ -295,7 +296,7 @@ if ( load_flags & FT_LOAD_SBITS_ONLY ) { - error = FT_Err_Invalid_Argument; + error = PFR_Err_Invalid_Argument; goto Exit; } @@ -352,6 +353,21 @@ metrics->vertBearingX = 0; metrics->vertBearingY = 0; + /* Apply the font matrix, if any. */ + /* TODO: Test existing fonts with unusual matrix */ + /* whether we have to adjust Units per EM. */ + { + FT_Matrix font_matrix; + + + font_matrix.xx = face->log_font.matrix[0] << 8; + font_matrix.yx = face->log_font.matrix[1] << 8; + font_matrix.xy = face->log_font.matrix[2] << 8; + font_matrix.yy = face->log_font.matrix[3] << 8; + + FT_Outline_Transform( outline, &font_matrix ); + } + /* scale when needed */ if ( scaling ) { @@ -395,87 +411,46 @@ /*************************************************************************/ /*************************************************************************/ - FT_LOCAL_DEF( FT_Error ) + FT_LOCAL_DEF( void ) pfr_face_get_kerning( PFR_Face face, FT_UInt glyph1, FT_UInt glyph2, FT_Vector* kerning ) { - FT_Error error; + FT_Error error = PFR_Err_Ok; PFR_PhyFont phy_font = &face->phy_font; - PFR_KernItem item = phy_font->kern_items; + PFR_KernPair pairs = phy_font->kern_pairs; FT_UInt32 idx = PFR_KERN_INDEX( glyph1, glyph2 ); + FT_UInt min, max; + + FT_UNUSED( error ); /* just needed as syntactical sugar */ kerning->x = 0; kerning->y = 0; - /* find the kerning item containing our pair */ - while ( item ) + min = 0; + max = phy_font->num_kern_pairs; + + while ( min < max ) { - if ( item->pair1 <= idx && idx <= item->pair2 ) - goto Found_Item; + FT_UInt mid = ( min + max ) >> 1; + PFR_KernPair pair = pairs + mid; + FT_UInt32 pidx = PFR_KERN_PAIR_INDEX( pair ); + - item = item->next; - } - - /* not found */ - goto Exit; - - Found_Item: - { - /* perform simply binary search within the item */ - FT_UInt min, mid, max; - FT_Stream stream = face->root.stream; - FT_Byte* p; - - - if ( FT_STREAM_SEEK( item->offset ) || - FT_FRAME_ENTER( item->pair_count * item->pair_size ) ) - goto Exit; - - min = 0; - max = item->pair_count; - while ( min < max ) + if ( pidx == idx ) { - FT_UInt char1, char2, charcode; - - - mid = ( min + max ) >> 1; - p = stream->cursor + mid*item->pair_size; - - if ( item->flags & PFR_KERN_2BYTE_CHAR ) - { - char1 = FT_NEXT_USHORT( p ); - char2 = FT_NEXT_USHORT( p ); - } - else - { - char1 = FT_NEXT_USHORT( p ); - char2 = FT_NEXT_USHORT( p ); - } - charcode = PFR_KERN_INDEX( char1, char2 ); - - if ( idx == charcode ) - { - if ( item->flags & PFR_KERN_2BYTE_ADJ ) - kerning->x = item->base_adj + FT_NEXT_SHORT( p ); - else - kerning->x = item->base_adj + FT_NEXT_CHAR( p ); - - break; - } - if ( idx > charcode ) - min = mid + 1; - else - max = mid; + kerning->x = pair->kerning; + break; } - - FT_FRAME_EXIT(); + + if ( pidx < idx ) + min = mid + 1; + else + max = mid; } - - Exit: - return 0; } -/* END */ + +/* END */ diff --git a/src/libs/freetype2/pfr/pfrobjs.h b/src/libs/freetype2/pfr/pfrobjs.h index 1d90b17658..efd7b7c6d3 100644 --- a/src/libs/freetype2/pfr/pfrobjs.h +++ b/src/libs/freetype2/pfr/pfrobjs.h @@ -4,7 +4,7 @@ /* */ /* FreeType PFR object methods (specification). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -67,11 +67,11 @@ FT_BEGIN_HEADER pfr_face_done( PFR_Face face ); - FT_LOCAL( FT_Error ) - pfr_face_get_kerning( PFR_Face face, - FT_UInt glyph1, - FT_UInt glyph2, - FT_Vector* kerning ); + FT_LOCAL( void ) + pfr_face_get_kerning( PFR_Face face, + FT_UInt glyph1, + FT_UInt glyph2, + FT_Vector* kerning ); FT_LOCAL( FT_Error ) @@ -93,4 +93,4 @@ FT_END_HEADER #endif /* __PFROBJS_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/pfr/pfrsbit.c b/src/libs/freetype2/pfr/pfrsbit.c index 65085bddd4..da8fdba337 100644 --- a/src/libs/freetype2/pfr/pfrsbit.c +++ b/src/libs/freetype2/pfr/pfrsbit.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR bitmap loader (body). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -49,7 +49,7 @@ static void pfr_bitwriter_init( PFR_BitWriter writer, FT_Bitmap* target, - FT_UInt decreasing ) + FT_Bool decreasing ) { writer->line = target->buffer; writer->pitch = target->pitch; @@ -115,7 +115,7 @@ } if ( mask != 0x80 ) - cur[0] = (FT_Byte) c; + cur[0] = (FT_Byte)c; } @@ -185,7 +185,7 @@ } else if ( mask == 0 ) { - cur[0] = (FT_Byte) c; + cur[0] = (FT_Byte)c; mask = 0x80; c = 0; cur ++; @@ -249,7 +249,7 @@ } else if ( mask == 0 ) { - cur[0] = (FT_Byte) c; + cur[0] = (FT_Byte)c; c = 0; mask = 0x80; cur ++; @@ -274,8 +274,8 @@ static void pfr_lookup_bitmap_data( FT_Byte* base, FT_Byte* limit, - FT_Int count, - FT_Byte flags, + FT_UInt count, + FT_UInt flags, FT_UInt char_code, FT_ULong* found_offset, FT_ULong* found_size ) @@ -481,7 +481,7 @@ pfr_load_bitmap_bits( FT_Byte* p, FT_Byte* limit, FT_UInt format, - FT_UInt decreasing, + FT_Bool decreasing, FT_Bitmap* target ) { FT_Error error = 0; @@ -508,7 +508,7 @@ default: FT_ERROR(( "pfr_read_bitmap_data: invalid image type\n" )); - error = FT_Err_Invalid_File_Format; + error = PFR_Err_Invalid_File_Format; } } @@ -560,7 +560,7 @@ } /* couldn't find it */ - return FT_Err_Invalid_Argument; + return PFR_Err_Invalid_Argument; } Found_Strike: @@ -583,7 +583,7 @@ pfr_lookup_bitmap_data( stream->cursor, stream->limit, strike->num_bitmaps, - (FT_Byte) strike->flags, + strike->flags, character->char_code, &gps_offset, &gps_size ); @@ -593,7 +593,7 @@ if ( gps_size == 0 ) { /* Could not find a bitmap program string for this glyph */ - error = FT_Err_Invalid_Argument; + error = PFR_Err_Invalid_Argument; goto Exit; } } @@ -635,7 +635,7 @@ glyph->root.metrics.height = (FT_Long)ysize << 6; glyph->root.metrics.horiBearingX = xpos << 6; glyph->root.metrics.horiBearingY = ypos << 6; - glyph->root.metrics.horiAdvance = ( ( advance >> 2 ) + 32 ) & -64; + glyph->root.metrics.horiAdvance = FT_PIX_ROUND( ( advance >> 2 ) ); glyph->root.metrics.vertBearingX = - glyph->root.metrics.width >> 1; glyph->root.metrics.vertBearingY = 0; glyph->root.metrics.vertAdvance = size->root.metrics.height; @@ -645,16 +645,18 @@ /* Allocate and read bitmap data */ { - FT_ULong len = glyph->root.bitmap.pitch * ysize; + FT_ULong len = glyph->root.bitmap.pitch * ysize; + error = ft_glyphslot_alloc_bitmap( &glyph->root, len ); if ( !error ) { - error = pfr_load_bitmap_bits( p, - stream->limit, - format, - face->header.color_flags & 2, - &glyph->root.bitmap ); + error = pfr_load_bitmap_bits( + p, + stream->limit, + format, + FT_BOOL(face->header.color_flags & 2), + &glyph->root.bitmap ); } } } @@ -666,4 +668,4 @@ return error; } -/* END */ +/* END */ diff --git a/src/libs/freetype2/pfr/pfrsbit.h b/src/libs/freetype2/pfr/pfrsbit.h index 2b66676694..015e9e6dad 100644 --- a/src/libs/freetype2/pfr/pfrsbit.h +++ b/src/libs/freetype2/pfr/pfrsbit.h @@ -33,4 +33,4 @@ FT_END_HEADER #endif /* __PFR_SBIT_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/pfr/pfrtypes.h b/src/libs/freetype2/pfr/pfrtypes.h index d43d306e74..a10a2b26c8 100644 --- a/src/libs/freetype2/pfr/pfrtypes.h +++ b/src/libs/freetype2/pfr/pfrtypes.h @@ -4,7 +4,7 @@ /* */ /* FreeType PFR data structures (specification only). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -209,11 +209,14 @@ FT_BEGIN_HEADER #define PFR_KERN_INDEX( g1, g2 ) \ ( ( (FT_UInt32)(g1) << 16 ) | (FT_UInt16)(g2) ) +#define PFR_KERN_PAIR_INDEX( pair ) \ + PFR_KERN_INDEX( (pair)->glyph1, (pair)->glyph2 ) + typedef struct PFR_KernPairRec_ { FT_UInt glyph1; FT_UInt glyph2; - FT_Vector kerning; + FT_Int kerning; } PFR_KernPairRec, *PFR_KernPair; @@ -230,7 +233,7 @@ FT_BEGIN_HEADER FT_BBox bbox; FT_UInt flags; FT_UInt standard_advance; - + FT_Int ascent; /* optional, bbox.yMax if not present */ FT_Int descent; /* optional, bbox.yMin if not present */ FT_Int leading; /* optional, 0 if not present */ @@ -258,6 +261,7 @@ FT_BEGIN_HEADER FT_UInt num_kern_pairs; PFR_KernItem kern_items; PFR_KernItem* kern_items_tail; + PFR_KernPair kern_pairs; /* not part of the spec, but used during load */ FT_UInt32 bct_offset; @@ -281,8 +285,8 @@ FT_BEGIN_HEADER typedef enum PFR_KernFlags_ { - PFR_KERN_2BYTE_ADJ = 0x01, - PFR_KERN_2BYTE_CHAR = 0x02 + PFR_KERN_2BYTE_CHAR = 0x01, + PFR_KERN_2BYTE_ADJ = 0x02 } PFR_KernFlags; @@ -357,4 +361,4 @@ FT_END_HEADER #endif /* __PFRTYPES_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/pfr/rules.mk b/src/libs/freetype2/pfr/rules.mk index 678b8561c4..60b96c7415 100644 --- a/src/libs/freetype2/pfr/rules.mk +++ b/src/libs/freetype2/pfr/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2002 by +# Copyright 2002, 2003 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -15,27 +15,28 @@ # pfr driver directory # -PFR_DIR := $(SRC_)pfr -PFR_DIR_ := $(PFR_DIR)$(SEP) +PFR_DIR := $(SRC_DIR)/pfr # compilation flags for the driver # -PFR_COMPILE := $(FT_COMPILE) $I$(PFR_DIR) +PFR_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(PFR_DIR)) # pfr driver sources (i.e., C files) # -PFR_DRV_SRC := $(PFR_DIR_)pfrload.c \ - $(PFR_DIR_)pfrgload.c \ - $(PFR_DIR_)pfrcmap.c \ - $(PFR_DIR_)pfrdrivr.c \ - $(PFR_DIR_)pfrobjs.c +PFR_DRV_SRC := $(PFR_DIR)/pfrload.c \ + $(PFR_DIR)/pfrgload.c \ + $(PFR_DIR)/pfrcmap.c \ + $(PFR_DIR)/pfrdrivr.c \ + $(PFR_DIR)/pfrsbit.c \ + $(PFR_DIR)/pfrobjs.c # pfr driver headers # PFR_DRV_H := $(PFR_DRV_SRC:%.c=%.h) \ - $(PFR_DIR_)pfrerror.h + $(PFR_DIR)/pfrerror.h \ + $(PFR_DIR)/pfrtypes.h # Pfr driver object(s) @@ -43,24 +44,24 @@ PFR_DRV_H := $(PFR_DRV_SRC:%.c=%.h) \ # PFR_DRV_OBJ_M is used during `multi' builds # PFR_DRV_OBJ_S is used during `single' builds # -PFR_DRV_OBJ_M := $(PFR_DRV_SRC:$(PFR_DIR_)%.c=$(OBJ_)%.$O) -PFR_DRV_OBJ_S := $(OBJ_)pfr.$O +PFR_DRV_OBJ_M := $(PFR_DRV_SRC:$(PFR_DIR)/%.c=$(OBJ_DIR)/%.$O) +PFR_DRV_OBJ_S := $(OBJ_DIR)/pfr.$O # pfr driver source file for single build # -PFR_DRV_SRC_S := $(PFR_DIR_)pfr.c +PFR_DRV_SRC_S := $(PFR_DIR)/pfr.c # pfr driver - single object # $(PFR_DRV_OBJ_S): $(PFR_DRV_SRC_S) $(PFR_DRV_SRC) $(FREETYPE_H) $(PFR_DRV_H) - $(PFR_COMPILE) $T$@ $(PFR_DRV_SRC_S) + $(PFR_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(PFR_DRV_SRC_S)) # pfr driver - multiple objects # -$(OBJ_)%.$O: $(PFR_DIR_)%.c $(FREETYPE_H) $(PFR_DRV_H) - $(PFR_COMPILE) $T$@ $< +$(OBJ_DIR)/%.$O: $(PFR_DIR)/%.c $(FREETYPE_H) $(PFR_DRV_H) + $(PFR_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) # update main driver object lists @@ -68,4 +69,5 @@ $(OBJ_)%.$O: $(PFR_DIR_)%.c $(FREETYPE_H) $(PFR_DRV_H) DRV_OBJS_S += $(PFR_DRV_OBJ_S) DRV_OBJS_M += $(PFR_DRV_OBJ_M) -# EOF + +# EOF diff --git a/src/libs/freetype2/psaux/descrip.mms b/src/libs/freetype2/psaux/descrip.mms index 403be66bb6..bff019243d 100644 --- a/src/libs/freetype2/psaux/descrip.mms +++ b/src/libs/freetype2/psaux/descrip.mms @@ -20,4 +20,4 @@ OBJS=psaux.obj all : $(OBJS) library [--.lib]freetype.olb $(OBJS) -# EOF +# EOF diff --git a/src/libs/freetype2/psaux/module.mk b/src/libs/freetype2/psaux/module.mk index 107323ae54..29c3e28a91 100644 --- a/src/libs/freetype2/psaux/module.mk +++ b/src/libs/freetype2/psaux/module.mk @@ -19,4 +19,4 @@ add_psaux_module: $(OPEN_DRIVER)psaux_module_class$(CLOSE_DRIVER) $(ECHO_DRIVER)psaux $(ECHO_DRIVER_DESC)Postscript Type 1 & Type 2 helper module$(ECHO_DRIVER_DONE) -# EOF +# EOF diff --git a/src/libs/freetype2/psaux/psaux.c b/src/libs/freetype2/psaux/psaux.c index 51f8cb19da..9928184143 100644 --- a/src/libs/freetype2/psaux/psaux.c +++ b/src/libs/freetype2/psaux/psaux.c @@ -25,4 +25,4 @@ #include "t1cmap.c" -/* END */ +/* END */ diff --git a/src/libs/freetype2/psaux/psauxerr.h b/src/libs/freetype2/psaux/psauxerr.h index bbc955258c..d0baa3cbb9 100644 --- a/src/libs/freetype2/psaux/psauxerr.h +++ b/src/libs/freetype2/psaux/psauxerr.h @@ -38,4 +38,4 @@ #endif /* __PSAUXERR_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/psaux/psauxmod.c b/src/libs/freetype2/psaux/psauxmod.c index 22df0ce6d4..756ec1c565 100644 --- a/src/libs/freetype2/psaux/psauxmod.c +++ b/src/libs/freetype2/psaux/psauxmod.c @@ -4,7 +4,7 @@ /* */ /* FreeType auxiliary PostScript module implementation (body). */ /* */ -/* Copyright 2000-2001, 2002 by */ +/* Copyright 2000-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -39,9 +39,10 @@ ps_parser_init, ps_parser_done, ps_parser_skip_spaces, - ps_parser_skip_alpha, + ps_parser_skip_PS_token, ps_parser_to_int, ps_parser_to_fixed, + ps_parser_to_bytes, ps_parser_to_coord_array, ps_parser_to_fixed_array, ps_parser_to_token, @@ -104,7 +105,7 @@ 0, sizeof( FT_ModuleRec ), "psaux", - 0x10000L, + 0x20000L, 0x20000L, &psaux_interface, /* module-specific interface */ @@ -115,4 +116,4 @@ }; -/* END */ +/* END */ diff --git a/src/libs/freetype2/psaux/psauxmod.h b/src/libs/freetype2/psaux/psauxmod.h index 04fcd21b2b..92ac056048 100644 --- a/src/libs/freetype2/psaux/psauxmod.h +++ b/src/libs/freetype2/psaux/psauxmod.h @@ -35,4 +35,4 @@ FT_END_HEADER #endif /* __PSAUXMOD_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/psaux/psobjs.c b/src/libs/freetype2/psaux/psobjs.c index ce4f291806..7087ca5aca 100644 --- a/src/libs/freetype2/psaux/psobjs.c +++ b/src/libs/freetype2/psaux/psobjs.c @@ -4,7 +4,7 @@ /* */ /* Auxiliary functions for PostScript fonts (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -142,7 +142,7 @@ /* table :: The target table. */ /* */ /* <Input> */ - /* idx :: The index of the object in the table. */ + /* idx :: The index of the object in the table. */ /* */ /* object :: The address of the object to copy in memory. */ /* */ @@ -153,10 +153,10 @@ /* reallocation fails. */ /* */ FT_LOCAL_DEF( FT_Error ) - ps_table_add( PS_Table table, - FT_Int idx, - void* object, - FT_Int length ) + ps_table_add( PS_Table table, + FT_Int idx, + void* object, + FT_PtrDist length ) { if ( idx < 0 || idx > table->max_elems ) { @@ -178,9 +178,10 @@ while ( new_size < table->cursor + length ) { - /* increase size by 25% and round up to the nearest multiple of 1024 */ - new_size += (new_size >> 2) + 1; - new_size = ( new_size + 1023 ) & -1024; + /* increase size by 25% and round up to the nearest multiple + of 1024 */ + new_size += ( new_size >> 2 ) + 1; + new_size = FT_PAD_CEIL( new_size, 1024 ); } error = reallocate_t1_table( table, new_size ); @@ -265,52 +266,277 @@ /*************************************************************************/ /*************************************************************************/ - + /* In the PostScript Language Reference Manual (PLRM) the following */ + /* characters are called `whitespace characters'. */ #define IS_T1_WHITESPACE( c ) ( (c) == ' ' || (c) == '\t' ) -#define IS_T1_LINESPACE( c ) ( (c) == '\r' || (c) == '\n' ) +#define IS_T1_LINESPACE( c ) ( (c) == '\r' || (c) == '\n' || (c) == '\f' ) +#define IS_T1_NULLSPACE( c ) ( (c) == '\0' ) -#define IS_T1_SPACE( c ) ( IS_T1_WHITESPACE( c ) || IS_T1_LINESPACE( c ) ) + /* According to the PLRM all whitespace characters are equivalent, */ + /* except in comments and strings. */ +#define IS_T1_SPACE( c ) ( IS_T1_WHITESPACE( c ) || \ + IS_T1_LINESPACE( c ) || \ + IS_T1_NULLSPACE( c ) ) + + + /* The following array is used by various functions to quickly convert */ + /* digits (both decimal and non-decimal) into numbers. */ + +#if 'A' == 65 + /* ASCII */ + + static const char ft_char_table[128] = + { + /* 0x00 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, + }; + + /* no character >= 0x80 can represent a valid number */ +#define OP >= + +#endif /* 'A' == 65 */ + +#if 'A' == 193 + /* EBCDIC */ + + static const char ft_char_table[128] = + { + /* 0x80 */ + -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, -1, -1, -1, -1, -1, + -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1, + -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, -1, -1, -1, -1, -1, + -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1, + -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, + } + + /* no character < 0x80 can represent a valid number */ +#define OP < + +#endif /* 'A' == 193 */ + + + /* first character must be already part of the comment */ + + static void + skip_comment( FT_Byte* *acur, + FT_Byte* limit ) + { + FT_Byte* cur = *acur; + + + while ( cur < limit ) + { + if ( IS_T1_LINESPACE( *cur ) ) + break; + cur++; + } + + *acur = cur; + } + + + static void + skip_spaces( FT_Byte* *acur, + FT_Byte* limit ) + { + FT_Byte* cur = *acur; + + + while ( cur < limit ) + { + if ( !IS_T1_SPACE( *cur ) ) + { + if ( *cur == '%' ) + /* According to the PLRM, a comment is equal to a space. */ + skip_comment( &cur, limit ); + else + break; + } + cur++; + } + + *acur = cur; + } + + + /* first character must be `(' */ + + static void + skip_literal_string( FT_Byte* *acur, + FT_Byte* limit ) + { + FT_Byte* cur = *acur; + FT_Int embed = 0; + + + while ( cur < limit ) + { + if ( *cur == '\\' ) + cur++; + else if ( *cur == '(' ) + embed++; + else if ( *cur == ')' ) + { + embed--; + if ( embed == 0 ) + { + cur++; + break; + } + } + cur++; + } + + *acur = cur; + } + + + /* first character must be `<' */ + + static void + skip_string( PS_Parser parser ) + { + FT_Byte* cur = parser->cursor; + FT_Byte* limit = parser->limit; + + + while ( ++cur < limit ) + { + int d; + + + /* All whitespace characters are ignored. */ + skip_spaces( &cur, limit ); + if ( cur >= limit ) + break; + + if ( *cur OP 0x80 ) + break; + + d = ft_char_table[*cur & 0x7F]; + if ( d < 0 || d >= 16 ) + break; + } + + if ( cur < limit && *cur != '>' ) + parser->error = PSaux_Err_Invalid_File_Format; + else + cur++; + + parser->cursor = cur; + } + + + /***********************************************************************/ + /* */ + /* All exported parsing routines handle leading whitespace and stop at */ + /* the first character which isn't part of the just handled token. */ + /* */ + /***********************************************************************/ + + + FT_LOCAL_DEF( void ) + ps_parser_skip_PS_token( PS_Parser parser ) + { + /* Note: PostScript allows any non-delimiting, non-whitespace */ + /* character in a name (PS Ref Manual, 3rd ed, p31). */ + /* PostScript delimiters are (, ), <, >, [, ], {, }, /, and %. */ + + FT_Byte* cur = parser->cursor; + FT_Byte* limit = parser->limit; + + + skip_spaces( &cur, limit ); /* this also skips comments */ + if ( cur >= limit ) + goto Exit; + + /* self-delimiting, single-character tokens */ + if ( *cur == '[' || *cur == ']' || + *cur == '{' || *cur == '}' ) + { + cur++; + goto Exit; + } + + if ( *cur == '(' ) /* (...) */ + { + skip_literal_string( &cur, limit ); + goto Exit; + } + + if ( *cur == '<' ) /* <...> */ + { + if ( cur + 1 < limit && *(cur + 1) == '<' ) /* << */ + { + cur++; + cur++; + goto Exit; + } + parser->cursor = cur; + skip_string( parser ); + return; + } + + if ( *cur == '>' ) + { + cur++; + if ( cur >= limit || *cur != '>' ) /* >> */ + { + parser->error = PSaux_Err_Invalid_File_Format; + goto Exit; + } + cur++; + goto Exit; + } + + if ( *cur == '/' ) + cur++; + + /* anything else */ + while ( cur < limit ) + { + if ( IS_T1_SPACE( *cur ) || + *cur == '(' || + *cur == '/' || + *cur == '%' || + *cur == '[' || *cur == ']' || + *cur == '{' || *cur == '}' || + *cur == '<' || *cur == '>' ) + break; + + if ( *cur == ')' ) + { + parser->error = PSaux_Err_Invalid_File_Format; + goto Exit; + } + + cur++; + } + + Exit: + parser->cursor = cur; + } FT_LOCAL_DEF( void ) ps_parser_skip_spaces( PS_Parser parser ) { - FT_Byte* cur = parser->cursor; - FT_Byte* limit = parser->limit; - - - while ( cur < limit ) - { - FT_Byte c = *cur; - - - if ( !IS_T1_SPACE( c ) ) - break; - cur++; - } - parser->cursor = cur; + skip_spaces( &parser->cursor, parser->limit ); } - FT_LOCAL_DEF( void ) - ps_parser_skip_alpha( PS_Parser parser ) - { - FT_Byte* cur = parser->cursor; - FT_Byte* limit = parser->limit; - - - while ( cur < limit ) - { - FT_Byte c = *cur; - - - if ( IS_T1_SPACE( c ) ) - break; - cur++; - } - parser->cursor = cur; - } - + /* `token' here means either something between balanced delimiters */ + /* or the next token; the delimiters are not removed. */ FT_LOCAL_DEF( void ) ps_parser_to_token( PS_Parser parser, @@ -326,72 +552,87 @@ token->start = 0; token->limit = 0; - /* first of all, skip space */ + /* first of all, skip leading whitespace */ ps_parser_skip_spaces( parser ); cur = parser->cursor; limit = parser->limit; - if ( cur < limit ) + if ( cur >= limit ) + return; + + switch ( *cur ) { - switch ( *cur ) - { - /************* check for strings ***********************/ - case '(': - token->type = T1_TOKEN_TYPE_STRING; - ender = ')'; - goto Lookup_Ender; - - /************* check for programs/array ****************/ - case '{': - token->type = T1_TOKEN_TYPE_ARRAY; - ender = '}'; - goto Lookup_Ender; - - /************* check for table/array ******************/ - case '[': - token->type = T1_TOKEN_TYPE_ARRAY; - ender = ']'; - - Lookup_Ender: - embed = 1; - starter = *cur++; - token->start = cur; - while ( cur < limit ) - { - if ( *cur == starter ) - embed++; - else if ( *cur == ender ) - { - embed--; - if ( embed <= 0 ) - { - token->limit = cur++; - break; - } - } - cur++; - } - break; - - /* **************** otherwise, it's any token **********/ - default: - token->start = cur++; - token->type = T1_TOKEN_TYPE_ANY; - while ( cur < limit && !IS_T1_SPACE( *cur ) ) - cur++; - + /************* check for literal string *****************/ + case '(': + token->type = T1_TOKEN_TYPE_STRING; + token->start = cur; + skip_literal_string( &cur, limit ); + if ( cur < limit ) token->limit = cur; - } + break; - if ( !token->limit ) - { - token->start = 0; - token->type = T1_TOKEN_TYPE_NONE; - } + /************* check for programs/array *****************/ + case '{': + token->type = T1_TOKEN_TYPE_ARRAY; + ender = '}'; + goto Lookup_Ender; + /************* check for table/array ********************/ + case '[': + token->type = T1_TOKEN_TYPE_ARRAY; + ender = ']'; + /* fall through */ + + Lookup_Ender: + embed = 1; + starter = *cur; + token->start = cur++; + + /* we need this to catch `[ ]' */ parser->cursor = cur; + ps_parser_skip_spaces( parser ); + cur = parser->cursor; + + while ( cur < limit && !parser->error ) + { + if ( *cur == starter ) + embed++; + else if ( *cur == ender ) + { + embed--; + if ( embed <= 0 ) + { + token->limit = ++cur; + break; + } + } + + parser->cursor = cur; + ps_parser_skip_PS_token( parser ); + /* we need this to catch `[XXX ]' */ + ps_parser_skip_spaces ( parser ); + cur = parser->cursor; + } + break; + + /* ************ otherwise, it is any token **************/ + default: + token->start = cur; + token->type = T1_TOKEN_TYPE_ANY; + ps_parser_skip_PS_token( parser ); + cur = parser->cursor; + if ( !parser->error ) + token->limit = cur; } + + if ( !token->limit ) + { + token->start = 0; + token->type = T1_TOKEN_TYPE_NONE; + } + + parser->cursor = cur; } @@ -406,7 +647,9 @@ *pnum_tokens = -1; + /* this also handles leading whitespace */ ps_parser_to_token( parser, &master ); + if ( master.type == T1_TOKEN_TYPE_ARRAY ) { FT_Byte* old_cursor = parser->cursor; @@ -415,8 +658,9 @@ T1_Token limit = cur + max_tokens; - parser->cursor = master.start; - parser->limit = master.limit; + /* don't include outermost delimiters */ + parser->cursor = master.start + 1; + parser->limit = master.limit - 1; while ( parser->cursor < parser->limit ) { @@ -441,111 +685,188 @@ } - static FT_Long - T1Radix( FT_Long radixBase, - FT_Byte** cur, - FT_Byte* limit ) - { - FT_Long result = 0; - FT_Byte radixEndChar0 = - (FT_Byte)( radixBase > 10 ? '9' + 1 : '0' + radixBase ); - FT_Byte radixEndChar1 = - (FT_Byte)( 'A' + radixBase - 10 ); - FT_Byte radixEndChar2 = - (FT_Byte)( 'a' + radixBase - 10 ); - - - while( *cur < limit ) - { - if ( (*cur)[0] >= '0' && (*cur)[0] < radixEndChar0 ) - result = result * radixBase + (*cur)[0] - '0'; - - else if ( radixBase > 10 && - (*cur)[0] >= 'A' && (*cur)[0] < radixEndChar1 ) - result = result * radixBase + ( (*cur)[0] - 'A' + 10 ); - - else if ( radixBase > 10 && - (*cur)[0] >= 'a' && (*cur)[0] < radixEndChar2 ) - result = result * radixBase + ( (*cur)[0] - 'a' + 10 ); - - else - return result; - - (*cur)++; - } - - return result; - } - + /* first character must be already part of the number */ static FT_Long - t1_toint( FT_Byte** cursor, + ps_radix( FT_Long radixBase, + FT_Byte* *acur, FT_Byte* limit ) { FT_Long result = 0; - FT_Byte* cur = *cursor; - FT_Byte c = '\0', d; + FT_Byte* cur = *acur; - for ( ; cur < limit; cur++ ) + if ( radixBase < 2 || radixBase > 36 ) + return 0; + + while ( cur < limit ) { - c = *cur; - d = (FT_Byte)( c - '0' ); - if ( d < 10 ) + int d; + + + if ( *cur OP 0x80 ) break; - if ( c == '-' ) - { - cur++; + d = ft_char_table[*cur & 0x7F]; + if ( d < 0 || d >= radixBase ) break; - } + + result = result * radixBase + d; + + cur++; } - if ( cur < limit ) - { - do - { - d = (FT_Byte)( cur[0] - '0' ); - if ( d >= 10 ) - { - if ( cur[0] == '#' ) - { - cur++; - result = T1Radix( result, &cur, limit ); - } - break; - } + *acur = cur; - result = result * 10 + d; - cur++; - - } while ( cur < limit ); - - if ( c == '-' ) - result = -result; - } - - *cursor = cur; return result; } + /* first character must be already part of the number */ + static FT_Long - t1_tofixed( FT_Byte** cursor, + ps_toint( FT_Byte* *acur, + FT_Byte* limit ) + { + FT_Long result = 0; + FT_Byte* cur = *acur; + FT_Byte c; + + + if ( cur >= limit ) + goto Exit; + + c = *cur; + if ( c == '-' ) + cur++; + + while ( cur < limit ) + { + int d; + + + if ( *cur == '#' ) + { + cur++; + result = ps_radix( result, &cur, limit ); + break; + } + + if ( *cur OP 0x80 ) + break; + + d = ft_char_table[*cur & 0x7F]; + if ( d < 0 || d >= 10 ) + break; + result = result * 10 + d; + + cur++; + }; + + if ( c == '-' ) + result = -result; + + Exit: + *acur = cur; + return result; + } + + + /* first character must be `<' if `delimiters' is non-zero */ + + static FT_Error + ps_tobytes( FT_Byte* *acur, + FT_Byte* limit, + FT_Long max_bytes, + FT_Byte* bytes, + FT_Long* pnum_bytes, + FT_Bool delimiters ) + { + FT_Error error = PSaux_Err_Ok; + + FT_Byte* cur = *acur; + FT_Long n = 0; + + + if ( cur >= limit ) + goto Exit; + + if ( delimiters ) + { + if ( *cur != '<' ) + { + error = PSaux_Err_Invalid_File_Format; + goto Exit; + } + + cur++; + } + + max_bytes = max_bytes * 2; + + for ( n = 0; cur < limit; n++, cur++ ) + { + int d; + + + if ( n >= max_bytes ) + /* buffer is full */ + goto Exit; + + /* All whitespace characters are ignored. */ + skip_spaces( &cur, limit ); + if ( cur >= limit ) + break; + + if ( *cur OP 0x80 ) + break; + + d = ft_char_table[*cur & 0x7F]; + if ( d < 0 || d >= 16 ) + break; + + /* <f> == <f0> != <0f> */ + bytes[n / 2] = (FT_Byte)( ( n % 2 ) ? bytes[n / 2] + d + : d * 16 ); + } + + if ( delimiters ) + { + if ( cur < limit && *cur != '>' ) + { + error = PSaux_Err_Invalid_File_Format; + goto Exit; + } + + cur++; + } + + *acur = cur; + + Exit: + *pnum_bytes = ( n + 1 ) / 2; + + return error; + } + + + /* first character must be already part of the number */ + + static FT_Long + ps_tofixed( FT_Byte* *acur, FT_Byte* limit, FT_Long power_ten ) { - FT_Byte* cur = *cursor; + FT_Byte* cur = *acur; FT_Long num, divider, result; FT_Int sign = 0; - FT_Byte d; if ( cur >= limit ) return 0; /* first of all, check the sign */ - if ( *cur == '-' ) + if ( *cur == '-' && cur + 1 < limit ) { sign = 1; cur++; @@ -553,7 +874,7 @@ /* then, read the integer part, if any */ if ( *cur != '.' ) - result = t1_toint( &cur, limit ) << 16; + result = ps_toint( &cur, limit ) << 16; else result = 0; @@ -570,8 +891,14 @@ for (;;) { - d = (FT_Byte)( *cur - '0' ); - if ( d >= 10 ) + int d; + + + if ( *cur OP 0x80 ) + break; + + d = ft_char_table[*cur & 0x7F]; + if ( d < 0 || d >= 10 ) break; if ( divider < 10000000L ) @@ -590,7 +917,7 @@ if ( cur + 1 < limit && ( *cur == 'e' || *cur == 'E' ) ) { cur++; - power_ten += t1_toint( &cur, limit ); + power_ten += ps_toint( &cur, limit ); } Exit: @@ -615,18 +942,20 @@ if ( sign ) result = -result; - *cursor = cur; + *acur = cur; return result; } + /* first character must be a delimiter or a part of a number */ + static FT_Int - t1_tocoordarray( FT_Byte** cursor, + ps_tocoordarray( FT_Byte* *acur, FT_Byte* limit, FT_Int max_coords, FT_Short* coords ) { - FT_Byte* cur = *cursor; + FT_Byte* cur = *acur; FT_Int count = 0; FT_Byte c, ender; @@ -634,8 +963,8 @@ if ( cur >= limit ) goto Exit; - /* check for the beginning of an array; if not, only one number will */ - /* be read */ + /* check for the beginning of an array; otherwise, only one number */ + /* will be read */ c = *cur; ender = 0; @@ -649,24 +978,23 @@ cur++; /* now, read the coordinates */ - for ( ; cur < limit; ) + while ( cur < limit ) { /* skip whitespace in front of data */ - for (;;) - { - c = *cur; - if ( c != ' ' && c != '\t' ) - break; + skip_spaces( &cur, limit ); + if ( cur >= limit ) + goto Exit; - cur++; - if ( cur >= limit ) - goto Exit; - } - - if ( count >= max_coords || c == ender ) + if ( count >= max_coords ) break; - coords[count] = (FT_Short)( t1_tofixed( &cur, limit, 0 ) >> 16 ); + if ( c == ender ) + { + cur++; + break; + } + + coords[count] = (FT_Short)( ps_tofixed( &cur, limit, 0 ) >> 16 ); count++; if ( !ender ) @@ -674,27 +1002,30 @@ } Exit: - *cursor = cur; + *acur = cur; return count; } + /* first character must be a delimiter or a part of a number */ + static FT_Int - t1_tofixedarray( FT_Byte** cursor, + ps_tofixedarray( FT_Byte* *acur, FT_Byte* limit, FT_Int max_values, FT_Fixed* values, FT_Int power_ten ) { - FT_Byte* cur = *cursor; + FT_Byte* cur = *acur; FT_Int count = 0; FT_Byte c, ender; - if ( cur >= limit ) goto Exit; + if ( cur >= limit ) + goto Exit; - /* check for the beginning of an array. If not, only one number will */ - /* be read */ + /* Check for the beginning of an array. Otherwise, only one number */ + /* will be read. */ c = *cur; ender = 0; @@ -708,24 +1039,23 @@ cur++; /* now, read the values */ - for ( ; cur < limit; ) + while ( cur < limit ) { /* skip whitespace in front of data */ - for (;;) - { - c = *cur; - if ( c != ' ' && c != '\t' ) - break; + skip_spaces( &cur, limit ); + if ( cur >= limit ) + goto Exit; - cur++; - if ( cur >= limit ) - goto Exit; - } - - if ( count >= max_values || c == ender ) + if ( count >= max_values ) break; - values[count] = t1_tofixed( &cur, limit, power_ten ); + if ( c == ender ) + { + cur++; + break; + } + + values[count] = ps_tofixed( &cur, limit, power_ten ); count++; if ( !ender ) @@ -733,7 +1063,7 @@ } Exit: - *cursor = cur; + *acur = cur; return count; } @@ -741,7 +1071,7 @@ #if 0 static FT_String* - t1_tostring( FT_Byte** cursor, + ps_tostring( FT_Byte** cursor, FT_Byte* limit, FT_Memory memory ) { @@ -801,40 +1131,41 @@ static int - t1_tobool( FT_Byte** cursor, + ps_tobool( FT_Byte* *acur, FT_Byte* limit ) { - FT_Byte* cur = *cursor; + FT_Byte* cur = *acur; FT_Bool result = 0; /* return 1 if we find `true', 0 otherwise */ if ( cur + 3 < limit && - cur[0] == 't' && - cur[1] == 'r' && - cur[2] == 'u' && - cur[3] == 'e' ) + cur[0] == 't' && + cur[1] == 'r' && + cur[2] == 'u' && + cur[3] == 'e' ) { result = 1; cur += 5; } else if ( cur + 4 < limit && - cur[0] == 'f' && - cur[1] == 'a' && - cur[2] == 'l' && - cur[3] == 's' && - cur[4] == 'e' ) + cur[0] == 'f' && + cur[1] == 'a' && + cur[2] == 'l' && + cur[3] == 's' && + cur[4] == 'e' ) { result = 0; cur += 6; } - *cursor = cur; + *acur = cur; return result; } - /* Load a simple field (i.e. non-table) into the current list of objects */ + /* load a simple field (i.e. non-table) into the current list of objects */ + FT_LOCAL_DEF( FT_Error ) ps_parser_load_field( PS_Parser parser, const T1_Field field, @@ -850,6 +1181,7 @@ FT_Error error; + /* this also skips leading whitespace */ ps_parser_to_token( parser, &token ); if ( !token.type ) goto Fail; @@ -859,7 +1191,7 @@ cur = token.start; limit = token.limit; - /* we must detect arrays */ + /* we must detect arrays in /FontBBox */ if ( field->type == T1_FIELD_TYPE_BBOX ) { T1_TokenRec token2; @@ -867,8 +1199,9 @@ FT_Byte* old_limit = parser->limit; - parser->cursor = token.start; - parser->limit = token.limit; + /* don't include delimiters */ + parser->cursor = token.start + 1; + parser->limit = token.limit - 1; ps_parser_to_token( parser, &token2 ); parser->cursor = old_cur; @@ -880,12 +1213,16 @@ else if ( token.type == T1_TOKEN_TYPE_ARRAY ) { FieldArray: - /* if this is an array, and we have no blend, an error occurs */ + /* if this is an array and we have no blend, an error occurs */ if ( max_objects == 0 ) goto Fail; count = max_objects; - idx = 1; + idx = 1; + + /* don't include delimiters */ + cur++; + limit--; } for ( ; count > 0; count--, idx++ ) @@ -895,18 +1232,25 @@ FT_String* string; + skip_spaces( &cur, limit ); + switch ( field->type ) { case T1_FIELD_TYPE_BOOL: - val = t1_tobool( &cur, limit ); + val = ps_tobool( &cur, limit ); goto Store_Integer; case T1_FIELD_TYPE_FIXED: - val = t1_tofixed( &cur, limit, 3 ); + val = ps_tofixed( &cur, limit, 0 ); + goto Store_Integer; + + case T1_FIELD_TYPE_FIXED_1000: + val = ps_tofixed( &cur, limit, 3 ); goto Store_Integer; case T1_FIELD_TYPE_INTEGER: - val = t1_toint( &cur, limit ); + val = ps_toint( &cur, limit ); + /* fall through */ Store_Integer: switch ( field->size ) @@ -929,15 +1273,28 @@ break; case T1_FIELD_TYPE_STRING: + case T1_FIELD_TYPE_KEY: { FT_Memory memory = parser->memory; FT_UInt len = (FT_UInt)( limit - cur ); - if ( *(FT_String**)q ) - /* with synthetic fonts, it's possible to find a field twice */ + if ( cur >= limit ) break; + if ( field->type == T1_FIELD_TYPE_KEY ) + { + /* don't include leading `/' */ + len--; + cur++; + } + else + { + /* don't include delimiting parentheses */ + cur++; + len -= 2; + } + if ( FT_ALLOC( string, len + 1 ) ) goto Exit; @@ -954,10 +1311,7 @@ FT_BBox* bbox = (FT_BBox*)q; - /* we need the '[' and ']' delimiters */ - token.start--; - token.limit++; - (void)t1_tofixedarray( &token.start, token.limit, 4, temp, 0 ); + (void)ps_tofixedarray( &token.start, token.limit, 4, temp, 0 ); bbox->xMin = FT_RoundFix( temp[0] ); bbox->yMin = FT_RoundFix( temp[1] ); @@ -972,7 +1326,7 @@ } } -#if 0 /* obsolete - keep for reference */ +#if 0 /* obsolete -- keep for reference */ if ( pflags ) *pflags |= 1L << field->flag_bit; #else @@ -1003,7 +1357,7 @@ T1_TokenRec elements[T1_MAX_TABLE_ELEMENTS]; T1_Token token; FT_Int num_elements; - FT_Error error = 0; + FT_Error error = PSaux_Err_Ok; FT_Byte* old_cursor; FT_Byte* old_limit; T1_FieldRec fieldrec = *(T1_Field)field; @@ -1015,10 +1369,13 @@ fieldrec.type = T1_FIELD_TYPE_FIXED; #endif - ps_parser_to_token_array( parser, elements, 32, &num_elements ); + ps_parser_to_token_array( parser, elements, + T1_MAX_TABLE_ELEMENTS, &num_elements ); if ( num_elements < 0 ) - goto Fail; - + { + error = PSaux_Err_Ignore; + goto Exit; + } if ( num_elements > T1_MAX_TABLE_ELEMENTS ) num_elements = T1_MAX_TABLE_ELEMENTS; @@ -1051,17 +1408,31 @@ Exit: return error; - - Fail: - error = PSaux_Err_Invalid_File_Format; - goto Exit; } FT_LOCAL_DEF( FT_Long ) ps_parser_to_int( PS_Parser parser ) { - return t1_toint( &parser->cursor, parser->limit ); + ps_parser_skip_spaces( parser ); + return ps_toint( &parser->cursor, parser->limit ); + } + + + FT_LOCAL_DEF( FT_Error ) + ps_parser_to_bytes( PS_Parser parser, + FT_Byte* bytes, + FT_Long max_bytes, + FT_Long* pnum_bytes, + FT_Bool delimiters ) + { + ps_parser_skip_spaces( parser ); + return ps_tobytes( &parser->cursor, + parser->limit, + max_bytes, + bytes, + pnum_bytes, + delimiters ); } @@ -1069,7 +1440,8 @@ ps_parser_to_fixed( PS_Parser parser, FT_Int power_ten ) { - return t1_tofixed( &parser->cursor, parser->limit, power_ten ); + ps_parser_skip_spaces( parser ); + return ps_tofixed( &parser->cursor, parser->limit, power_ten ); } @@ -1078,7 +1450,8 @@ FT_Int max_coords, FT_Short* coords ) { - return t1_tocoordarray( &parser->cursor, parser->limit, + ps_parser_skip_spaces( parser ); + return ps_tocoordarray( &parser->cursor, parser->limit, max_coords, coords ); } @@ -1089,7 +1462,8 @@ FT_Fixed* values, FT_Int power_ten ) { - return t1_tofixedarray( &parser->cursor, parser->limit, + ps_parser_skip_spaces( parser ); + return ps_tofixedarray( &parser->cursor, parser->limit, max_values, values, power_ten ); } @@ -1099,14 +1473,14 @@ FT_LOCAL_DEF( FT_String* ) T1_ToString( PS_Parser parser ) { - return t1_tostring( &parser->cursor, parser->limit, parser->memory ); + return ps_tostring( &parser->cursor, parser->limit, parser->memory ); } FT_LOCAL_DEF( FT_Bool ) T1_ToBool( PS_Parser parser ) { - return t1_tobool( &parser->cursor, parser->limit ); + return ps_tobool( &parser->cursor, parser->limit ); } #endif /* 0 */ @@ -1118,7 +1492,7 @@ FT_Byte* limit, FT_Memory memory ) { - parser->error = 0; + parser->error = PSaux_Err_Ok; parser->base = base; parser->limit = limit; parser->cursor = base; @@ -1292,7 +1666,7 @@ } - /* check room for a new contour, then add it */ + /* check space for a new contour, then add it */ FT_LOCAL_DEF( FT_Error ) t1_builder_add_contour( T1_Builder builder ) { @@ -1403,4 +1777,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/psaux/psobjs.h b/src/libs/freetype2/psaux/psobjs.h index 54b4a0735d..c2cbf2c79b 100644 --- a/src/libs/freetype2/psaux/psobjs.h +++ b/src/libs/freetype2/psaux/psobjs.h @@ -4,7 +4,7 @@ /* */ /* Auxiliary functions for PostScript fonts (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -52,10 +52,10 @@ FT_BEGIN_HEADER FT_Memory memory ); FT_LOCAL( FT_Error ) - ps_table_add( PS_Table table, - FT_Int idx, - void* object, - FT_Int length ); + ps_table_add( PS_Table table, + FT_Int idx, + void* object, + FT_PtrDist length ); FT_LOCAL( void ) ps_table_done( PS_Table table ); @@ -78,7 +78,7 @@ FT_BEGIN_HEADER ps_parser_skip_spaces( PS_Parser parser ); FT_LOCAL( void ) - ps_parser_skip_alpha( PS_Parser parser ); + ps_parser_skip_PS_token( PS_Parser parser ); FT_LOCAL( void ) ps_parser_to_token( PS_Parser parser, @@ -108,6 +108,14 @@ FT_BEGIN_HEADER ps_parser_to_int( PS_Parser parser ); + FT_LOCAL( FT_Error ) + ps_parser_to_bytes( PS_Parser parser, + FT_Byte* bytes, + FT_Long max_bytes, + FT_Long* pnum_bytes, + FT_Bool delimiters ); + + FT_LOCAL( FT_Fixed ) ps_parser_to_fixed( PS_Parser parser, FT_Int power_ten ); @@ -201,4 +209,4 @@ FT_END_HEADER #endif /* __PSOBJS_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/psaux/rules.mk b/src/libs/freetype2/psaux/rules.mk index f67d7c1ecb..7338d3657a 100644 --- a/src/libs/freetype2/psaux/rules.mk +++ b/src/libs/freetype2/psaux/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2002 by +# Copyright 1996-2000, 2002, 2003 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -15,26 +15,25 @@ # PSAUX driver directory # -PSAUX_DIR := $(SRC_)psaux -PSAUX_DIR_ := $(PSAUX_DIR)$(SEP) +PSAUX_DIR := $(SRC_DIR)/psaux # compilation flags for the driver # -PSAUX_COMPILE := $(FT_COMPILE) $I$(PSAUX_DIR) +PSAUX_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(PSAUX_DIR)) # PSAUX driver sources (i.e., C files) # -PSAUX_DRV_SRC := $(PSAUX_DIR_)psobjs.c \ - $(PSAUX_DIR_)t1decode.c \ - $(PSAUX_DIR_)t1cmap.c \ - $(PSAUX_DIR_)psauxmod.c +PSAUX_DRV_SRC := $(PSAUX_DIR)/psobjs.c \ + $(PSAUX_DIR)/t1decode.c \ + $(PSAUX_DIR)/t1cmap.c \ + $(PSAUX_DIR)/psauxmod.c # PSAUX driver headers # PSAUX_DRV_H := $(PSAUX_DRV_SRC:%c=%h) \ - $(PSAUX_DIR_)psauxerr.h + $(PSAUX_DIR)/psauxerr.h # PSAUX driver object(s) @@ -42,25 +41,25 @@ PSAUX_DRV_H := $(PSAUX_DRV_SRC:%c=%h) \ # PSAUX_DRV_OBJ_M is used during `multi' builds. # PSAUX_DRV_OBJ_S is used during `single' builds. # -PSAUX_DRV_OBJ_M := $(PSAUX_DRV_SRC:$(PSAUX_DIR_)%.c=$(OBJ_)%.$O) -PSAUX_DRV_OBJ_S := $(OBJ_)psaux.$O +PSAUX_DRV_OBJ_M := $(PSAUX_DRV_SRC:$(PSAUX_DIR)/%.c=$(OBJ_DIR)/%.$O) +PSAUX_DRV_OBJ_S := $(OBJ_DIR)/psaux.$O # PSAUX driver source file for single build # -PSAUX_DRV_SRC_S := $(PSAUX_DIR_)psaux.c +PSAUX_DRV_SRC_S := $(PSAUX_DIR)/psaux.c # PSAUX driver - single object # $(PSAUX_DRV_OBJ_S): $(PSAUX_DRV_SRC_S) $(PSAUX_DRV_SRC) \ $(FREETYPE_H) $(PSAUX_DRV_H) - $(PSAUX_COMPILE) $T$@ $(PSAUX_DRV_SRC_S) + $(PSAUX_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(PSAUX_DRV_SRC_S)) # PSAUX driver - multiple objects # -$(OBJ_)%.$O: $(PSAUX_DIR_)%.c $(FREETYPE_H) $(PSAUX_DRV_H) - $(PSAUX_COMPILE) $T$@ $< +$(OBJ_DIR)/%.$O: $(PSAUX_DIR)/%.c $(FREETYPE_H) $(PSAUX_DRV_H) + $(PSAUX_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) # update main driver object lists @@ -69,4 +68,4 @@ DRV_OBJS_S += $(PSAUX_DRV_OBJ_S) DRV_OBJS_M += $(PSAUX_DRV_OBJ_M) -# EOF +# EOF diff --git a/src/libs/freetype2/psaux/t1cmap.c b/src/libs/freetype2/psaux/t1cmap.c index 39c22138d0..dcd99be49f 100644 --- a/src/libs/freetype2/psaux/t1cmap.c +++ b/src/libs/freetype2/psaux/t1cmap.c @@ -4,7 +4,7 @@ /* */ /* Type 1 character map support (body). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,6 +20,8 @@ #include FT_INTERNAL_DEBUG_H +#include "psauxerr.h" + /*************************************************************************/ /*************************************************************************/ @@ -33,8 +35,8 @@ t1_cmap_std_init( T1_CMapStd cmap, FT_Int is_expert ) { - T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); - PSNames_Service psnames = (PSNames_Service)face->psnames; + T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; cmap->num_glyphs = face->type1.num_glyphs; @@ -261,26 +263,26 @@ { FT_UInt32 u1 = ((T1_CMapUniPair)pair1)->unicode; FT_UInt32 u2 = ((T1_CMapUniPair)pair2)->unicode; - + if ( u1 < u2 ) return -1; - + if ( u1 > u2 ) return +1; - + return 0; - } + } FT_CALLBACK_DEF( FT_Error ) t1_cmap_unicode_init( T1_CMapUnicode cmap ) { - FT_Error error; - FT_UInt count; - T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); - FT_Memory memory = FT_FACE_MEMORY( face ); - PSNames_Service psnames = (PSNames_Service)face->psnames; + FT_Error error; + FT_UInt count; + T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); + FT_Memory memory = FT_FACE_MEMORY( face ); + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; cmap->num_pairs = 0; @@ -314,13 +316,13 @@ } } } - + new_count = (FT_UInt)( pair - cmap->pairs ); if ( new_count == 0 ) { /* there are no unicode characters in here! */ FT_FREE( cmap->pairs ); - error = FT_Err_Invalid_Argument; + error = PSaux_Err_Invalid_Argument; } else { @@ -451,4 +453,4 @@ }; -/* END */ +/* END */ diff --git a/src/libs/freetype2/psaux/t1cmap.h b/src/libs/freetype2/psaux/t1cmap.h index 7fd2fbf751..aa93d746c1 100644 --- a/src/libs/freetype2/psaux/t1cmap.h +++ b/src/libs/freetype2/psaux/t1cmap.h @@ -4,7 +4,7 @@ /* */ /* Type 1 character map support (specification). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,7 +22,6 @@ #include <ft2build.h> #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_TYPE1_TYPES_H -#include FT_INTERNAL_POSTSCRIPT_NAMES_H FT_BEGIN_HEADER @@ -47,16 +46,16 @@ FT_BEGIN_HEADER FT_UInt num_glyphs; const char* const* glyph_names; - + } T1_CMapStdRec; FT_CALLBACK_TABLE const FT_CMap_ClassRec t1_cmap_standard_class_rec; - + FT_CALLBACK_TABLE const FT_CMap_ClassRec t1_cmap_expert_class_rec; - + /*************************************************************************/ /*************************************************************************/ @@ -67,20 +66,20 @@ FT_BEGIN_HEADER /*************************************************************************/ typedef struct T1_CMapCustomRec_* T1_CMapCustom; - + typedef struct T1_CMapCustomRec_ { FT_CMapRec cmap; FT_UInt first; FT_UInt count; FT_UShort* indices; - + } T1_CMapCustomRec; FT_CALLBACK_TABLE const FT_CMap_ClassRec t1_cmap_custom_class_rec; - + /*************************************************************************/ /*************************************************************************/ @@ -97,7 +96,7 @@ FT_BEGIN_HEADER { FT_UInt32 unicode; FT_UInt gindex; - + } T1_CMapUniPairRec, *T1_CMapUniPair; @@ -115,10 +114,10 @@ FT_BEGIN_HEADER /* */ - + FT_END_HEADER #endif /* __T1CMAP_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/psaux/t1decode.c b/src/libs/freetype2/psaux/t1decode.c index 5f5caf10a7..db1911e7bd 100644 --- a/src/libs/freetype2/psaux/t1decode.c +++ b/src/libs/freetype2/psaux/t1decode.c @@ -4,7 +4,7 @@ /* */ /* PostScript Type 1 decoding routines (body). */ /* */ -/* Copyright 2000-2001, 2002 by */ +/* Copyright 2000-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -125,9 +125,9 @@ t1_lookup_glyph_by_stdcharcode( T1_Decoder decoder, FT_Int charcode ) { - FT_UInt n; - const FT_String* glyph_name; - PSNames_Service psnames = decoder->psnames; + FT_UInt n; + const FT_String* glyph_name; + FT_Service_PsCMaps psnames = decoder->psnames; /* check range of standard char code */ @@ -143,7 +143,7 @@ if ( name && name[0] == glyph_name[0] && - ft_strcmp( name,glyph_name ) == 0 ) + ft_strcmp( name, glyph_name ) == 0 ) return n; } @@ -241,8 +241,8 @@ /* subglyph 1 = accent character */ subg->index = achar_index; subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES; - subg->arg1 = adx - asb; - subg->arg2 = ady; + subg->arg1 = (FT_Int)( adx - asb ); + subg->arg2 = (FT_Int)ady; /* set up remaining glyph fields */ glyph->num_subglyphs = 2; @@ -262,10 +262,6 @@ if ( error ) goto Exit; -#if 0 - n_base_points = base->n_points; -#endif - /* save the left bearing and width of the base character */ /* as they will be erased by the next load. */ @@ -290,23 +286,8 @@ decoder->builder.left_bearing = left_bearing; decoder->builder.advance = advance; - /* XXX: old code doesn't work with PostScript hinter */ -#if 0 - /* Finally, move the accent */ - if ( decoder->builder.load_points ) - { - FT_Outline dummy; - - - dummy.n_points = (short)( base->n_points - n_base_points ); - dummy.points = base->points + n_base_points; - - FT_Outline_Translate( &dummy, adx - asb, ady ); - } -#else decoder->builder.pos_x = 0; decoder->builder.pos_y = 0; -#endif Exit: return error; @@ -565,7 +546,7 @@ goto Stack_Underflow; top -= 2; - switch ( top[1] ) + switch ( (FT_Int)top[1] ) { case 1: /* start flex feature */ if ( top[0] != 0 ) @@ -706,7 +687,7 @@ values = top; for ( nn = 0; nn < num_points; nn++ ) { - FT_Int tmp = values[0]; + FT_Long tmp = values[0]; for ( mm = 1; mm < blend->num_designs; mm++ ) @@ -785,8 +766,8 @@ case op_seac: /* return immediately after the processing */ - return t1operator_seac( decoder, top[0], top[1], - top[2], top[3], top[4] ); + return t1operator_seac( decoder, top[0], top[1], top[2], + (FT_Int)top[3], (FT_Int)top[4] ); case op_sbw: FT_TRACE4(( " sbw" )); @@ -945,7 +926,7 @@ FT_TRACE4(( " callsubr" )); - idx = top[0]; + idx = (FT_Int)top[0]; if ( idx < 0 || idx >= (FT_Int)decoder->num_subrs ) { FT_ERROR(( "t1_decoder_parse_charstrings: " @@ -1129,11 +1110,10 @@ /* retrieve PSNames interface from list of current modules */ { - PSNames_Service psnames = 0; + FT_Service_PsCMaps psnames = 0; - psnames = (PSNames_Service)FT_Get_Module_Interface( - FT_FACE_LIBRARY(face), "psnames" ); + FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); if ( !psnames ) { FT_ERROR(( "t1_decoder_init: " )); @@ -1148,7 +1128,6 @@ decoder->num_glyphs = (FT_UInt)face->num_glyphs; decoder->glyph_names = glyph_names; - decoder->hint_flags = face->internal->hint_flags; decoder->hint_mode = hint_mode; decoder->blend = blend; decoder->parse_callback = parse_callback; @@ -1167,4 +1146,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/psaux/t1decode.h b/src/libs/freetype2/psaux/t1decode.h index d779f6135a..00728db501 100644 --- a/src/libs/freetype2/psaux/t1decode.h +++ b/src/libs/freetype2/psaux/t1decode.h @@ -4,7 +4,7 @@ /* */ /* PostScript Type 1 decoding routines (specification). */ /* */ -/* Copyright 2000-2001, 2002 by */ +/* Copyright 2000-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,7 +22,6 @@ #include <ft2build.h> #include FT_INTERNAL_POSTSCRIPT_AUX_H -#include FT_INTERNAL_POSTSCRIPT_NAMES_H #include FT_INTERNAL_TYPE1_TYPES_H @@ -62,4 +61,4 @@ FT_END_HEADER #endif /* __T1DECODE_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/pshinter/Jamfile b/src/libs/freetype2/pshinter/Jamfile index fc1fc1da85..b4baebbeaf 100644 --- a/src/libs/freetype2/pshinter/Jamfile +++ b/src/libs/freetype2/pshinter/Jamfile @@ -10,7 +10,7 @@ UseFreeTypeHeaders ; if $(FT2_MULTI) { - _sources = pshrec pshglob pshalgo1 pshalgo2 pshalgo3 pshmod ; + _sources = pshrec pshglob pshalgo pshmod ; } else { diff --git a/src/libs/freetype2/pshinter/descrip.mms b/src/libs/freetype2/pshinter/descrip.mms index 1e3079ebaf..205d6cfcc0 100644 --- a/src/libs/freetype2/pshinter/descrip.mms +++ b/src/libs/freetype2/pshinter/descrip.mms @@ -20,4 +20,4 @@ OBJS=pshinter.obj all : $(OBJS) library [--.lib]freetype.olb $(OBJS) -# EOF +# EOF diff --git a/src/libs/freetype2/pshinter/module.mk b/src/libs/freetype2/pshinter/module.mk index 3fac789192..63c7e217f1 100644 --- a/src/libs/freetype2/pshinter/module.mk +++ b/src/libs/freetype2/pshinter/module.mk @@ -19,4 +19,4 @@ add_pshinter_module: $(OPEN_DRIVER)pshinter_module_class$(CLOSE_DRIVER) $(ECHO_DRIVER)pshinter $(ECHO_DRIVER_DESC)Postscript hinter module$(ECHO_DRIVER_DONE) -# EOF +# EOF diff --git a/src/libs/freetype2/pshinter/pshalgo3.c b/src/libs/freetype2/pshinter/pshalgo.c similarity index 56% rename from src/libs/freetype2/pshinter/pshalgo3.c rename to src/libs/freetype2/pshinter/pshalgo.c index 6d60475fcd..5f077d54d1 100644 --- a/src/libs/freetype2/pshinter/pshalgo3.c +++ b/src/libs/freetype2/pshinter/pshalgo.c @@ -1,10 +1,10 @@ /***************************************************************************/ /* */ -/* pshalgo3.c */ +/* pshalgo.c */ /* */ -/* PostScript hinting algorithm 3 (body). */ +/* PostScript hinting algorithm (body). */ /* */ -/* Copyright 2001, 2002 by */ +/* Copyright 2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used */ @@ -19,7 +19,9 @@ #include <ft2build.h> #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H -#include "pshalgo3.h" +#include "pshalgo.h" + +#include "pshnterr.h" #undef FT_COMPONENT @@ -27,14 +29,17 @@ #ifdef DEBUG_HINTER - PSH3_Hint_Table ps3_debug_hint_table = 0; - PSH3_HintFunc ps3_debug_hint_func = 0; - PSH3_Glyph ps3_debug_glyph = 0; + PSH_Hint_Table ps_debug_hint_table = 0; + PSH_HintFunc ps_debug_hint_func = 0; + PSH_Glyph ps_debug_glyph = 0; #endif -#define COMPUTE_INFLEXS /* compute inflection points to optimize "S" and others */ -#define STRONGER /* slightly increase the contrast of smooth hinting */ +#define COMPUTE_INFLEXS /* compute inflection points to optimize `S' */ + /* and similar glyphs */ +#define STRONGER /* slightly increase the contrast of smooth */ + /* hinting */ + /*************************************************************************/ /*************************************************************************/ @@ -44,20 +49,20 @@ /*************************************************************************/ /*************************************************************************/ - /* return true iff two stem hints overlap */ + /* return true if two stem hints overlap */ static FT_Int - psh3_hint_overlap( PSH3_Hint hint1, - PSH3_Hint hint2 ) + psh_hint_overlap( PSH_Hint hint1, + PSH_Hint hint2 ) { - return ( hint1->org_pos + hint1->org_len >= hint2->org_pos && - hint2->org_pos + hint2->org_len >= hint1->org_pos ); + return hint1->org_pos + hint1->org_len >= hint2->org_pos && + hint2->org_pos + hint2->org_len >= hint1->org_pos; } /* destroy hints table */ static void - psh3_hint_table_done( PSH3_Hint_Table table, - FT_Memory memory ) + psh_hint_table_done( PSH_Hint_Table table, + FT_Memory memory ) { FT_FREE( table->zones ); table->num_zones = 0; @@ -73,46 +78,46 @@ /* deactivate all hints in a table */ static void - psh3_hint_table_deactivate( PSH3_Hint_Table table ) + psh_hint_table_deactivate( PSH_Hint_Table table ) { - FT_UInt count = table->max_hints; - PSH3_Hint hint = table->hints; + FT_UInt count = table->max_hints; + PSH_Hint hint = table->hints; for ( ; count > 0; count--, hint++ ) { - psh3_hint_deactivate( hint ); + psh_hint_deactivate( hint ); hint->order = -1; } } - /* internal function used to record a new hint */ + /* internal function to record a new hint */ static void - psh3_hint_table_record( PSH3_Hint_Table table, - FT_UInt idx ) + psh_hint_table_record( PSH_Hint_Table table, + FT_UInt idx ) { - PSH3_Hint hint = table->hints + idx; + PSH_Hint hint = table->hints + idx; if ( idx >= table->max_hints ) { - FT_ERROR(( "psh3_hint_table_record: invalid hint index %d\n", idx )); + FT_ERROR(( "psh_hint_table_record: invalid hint index %d\n", idx )); return; } /* ignore active hints */ - if ( psh3_hint_is_active( hint ) ) + if ( psh_hint_is_active( hint ) ) return; - psh3_hint_activate( hint ); + psh_hint_activate( hint ); - /* now scan the current active hint set in order to determine */ - /* if we are overlapping with another segment */ + /* now scan the current active hint set to check */ + /* whether `hint' overlaps with another hint */ { - PSH3_Hint* sorted = table->sort_global; - FT_UInt count = table->num_hints; - PSH3_Hint hint2; + PSH_Hint* sorted = table->sort_global; + FT_UInt count = table->num_hints; + PSH_Hint hint2; hint->parent = 0; @@ -120,7 +125,7 @@ { hint2 = sorted[0]; - if ( psh3_hint_overlap( hint, hint2 ) ) + if ( psh_hint_overlap( hint, hint2 ) ) { hint->parent = hint2; break; @@ -131,13 +136,13 @@ if ( table->num_hints < table->max_hints ) table->sort_global[table->num_hints++] = hint; else - FT_ERROR(( "psh3_hint_table_record: too many sorted hints! BUG!\n" )); + FT_ERROR(( "psh_hint_table_record: too many sorted hints! BUG!\n" )); } static void - psh3_hint_table_record_mask( PSH3_Hint_Table table, - PS_Mask hint_mask ) + psh_hint_table_record_mask( PSH_Hint_Table table, + PS_Mask hint_mask ) { FT_Int mask = 0, val = 0; FT_Byte* cursor = hint_mask->bytes; @@ -155,7 +160,7 @@ } if ( val & mask ) - psh3_hint_table_record( table, idx ); + psh_hint_table_record( table, idx ); mask >>= 1; } @@ -164,18 +169,20 @@ /* create hints table */ static FT_Error - psh3_hint_table_init( PSH3_Hint_Table table, - PS_Hint_Table hints, - PS_Mask_Table hint_masks, - PS_Mask_Table counter_masks, - FT_Memory memory ) + psh_hint_table_init( PSH_Hint_Table table, + PS_Hint_Table hints, + PS_Mask_Table hint_masks, + PS_Mask_Table counter_masks, + FT_Memory memory ) { - FT_UInt count = hints->num_hints; + FT_UInt count; FT_Error error; FT_UNUSED( counter_masks ); + count = hints->num_hints; + /* allocate our tables */ if ( FT_NEW_ARRAY( table->sort, 2 * count ) || FT_NEW_ARRAY( table->hints, count ) || @@ -188,10 +195,10 @@ table->num_zones = 0; table->zone = 0; - /* now, initialize the "hints" array */ + /* initialize the `table->hints' array */ { - PSH3_Hint write = table->hints; - PS_Hint read = hints->hints; + PSH_Hint write = table->hints; + PS_Hint read = hints->hints; for ( ; count > 0; count--, write++, read++ ) @@ -202,30 +209,31 @@ } } - /* we now need to determine the initial "parent" stems; first */ + /* we now need to determine the initial `parent' stems; first */ /* activate the hints that are given by the initial hint masks */ if ( hint_masks ) { - FT_UInt Count = hint_masks->num_masks; - PS_Mask Mask = hint_masks->masks; + PS_Mask mask = hint_masks->masks; + count = hint_masks->num_masks; table->hint_masks = hint_masks; - for ( ; Count > 0; Count--, Mask++ ) - psh3_hint_table_record_mask( table, Mask ); + for ( ; count > 0; count--, mask++ ) + psh_hint_table_record_mask( table, mask ); } - /* now, do a linear parse in case some hints were left alone */ + /* finally, do a linear parse in case some hints were left alone */ if ( table->num_hints != table->max_hints ) { - FT_UInt Index, Count; + FT_UInt idx; - FT_ERROR(( "psh3_hint_table_init: missing/incorrect hint masks!\n" )); - Count = table->max_hints; - for ( Index = 0; Index < Count; Index++ ) - psh3_hint_table_record( table, Index ); + FT_ERROR(( "psh_hint_table_init: missing/incorrect hint masks!\n" )); + + count = table->max_hints; + for ( idx = 0; idx < count; idx++ ) + psh_hint_table_record( table, idx ); } Exit: @@ -234,8 +242,8 @@ static void - psh3_hint_table_activate_mask( PSH3_Hint_Table table, - PS_Mask hint_mask ) + psh_hint_table_activate_mask( PSH_Hint_Table table, + PS_Mask hint_mask ) { FT_Int mask = 0, val = 0; FT_Byte* cursor = hint_mask->bytes; @@ -245,7 +253,7 @@ limit = hint_mask->num_bits; count = 0; - psh3_hint_table_deactivate( table ); + psh_hint_table_deactivate( table ); for ( idx = 0; idx < limit; idx++ ) { @@ -257,23 +265,23 @@ if ( val & mask ) { - PSH3_Hint hint = &table->hints[idx]; + PSH_Hint hint = &table->hints[idx]; - if ( !psh3_hint_is_active( hint ) ) + if ( !psh_hint_is_active( hint ) ) { FT_UInt count2; #if 0 - PSH3_Hint* sort = table->sort; - PSH3_Hint hint2; + PSH_Hint* sort = table->sort; + PSH_Hint hint2; for ( count2 = count; count2 > 0; count2--, sort++ ) { hint2 = sort[0]; - if ( psh3_hint_overlap( hint, hint2 ) ) - FT_ERROR(( "psh3_hint_table_activate_mask:" + if ( psh_hint_overlap( hint, hint2 ) ) + FT_ERROR(( "psh_hint_table_activate_mask:" " found overlapping hints\n" )) } #else @@ -282,11 +290,11 @@ if ( count2 == 0 ) { - psh3_hint_activate( hint ); + psh_hint_activate( hint ); if ( count < table->max_hints ) table->sort[count++] = hint; else - FT_ERROR(( "psh3_hint_tableactivate_mask:" + FT_ERROR(( "psh_hint_tableactivate_mask:" " too many active hints\n" )); } } @@ -299,9 +307,9 @@ /* now, sort the hints; they are guaranteed to not overlap */ /* so we can compare their "org_pos" field directly */ { - FT_Int i1, i2; - PSH3_Hint hint1, hint2; - PSH3_Hint* sort = table->sort; + FT_Int i1, i2; + PSH_Hint hint1, hint2; + PSH_Hint* sort = table->sort; /* a simple bubble sort will do, since in 99% of cases, the hints */ @@ -334,9 +342,9 @@ #if 1 static FT_Pos - psh3_dimension_quantize_len( PSH_Dimension dim, - FT_Pos len, - FT_Bool do_snapping ) + psh_dimension_quantize_len( PSH_Dimension dim, + FT_Pos len, + FT_Bool do_snapping ) { if ( len <= 64 ) len = 64; @@ -373,11 +381,11 @@ len += delta; } else - len = ( len + 32 ) & -64; + len = FT_PIX_ROUND( len ); } if ( do_snapping ) - len = ( len + 32 ) & -64; + len = FT_PIX_ROUND( len ); return len; } @@ -387,13 +395,13 @@ #ifdef DEBUG_HINTER static void - ps3_simple_scale( PSH3_Hint_Table table, - FT_Fixed scale, - FT_Fixed delta, - FT_Int dimension ) + ps_simple_scale( PSH_Hint_Table table, + FT_Fixed scale, + FT_Fixed delta, + FT_Int dimension ) { - PSH3_Hint hint; - FT_UInt count; + PSH_Hint hint; + FT_UInt count; for ( count = 0; count < table->max_hints; count++ ) @@ -403,8 +411,8 @@ hint->cur_pos = FT_MulFix( hint->org_pos, scale ) + delta; hint->cur_len = FT_MulFix( hint->org_len, scale ); - if ( ps3_debug_hint_func ) - ps3_debug_hint_func( hint, dimension ); + if ( ps_debug_hint_func ) + ps_debug_hint_func( hint, dimension ); } } @@ -412,14 +420,14 @@ static FT_Fixed - psh3_hint_snap_stem_side_delta( FT_Fixed pos, - FT_Fixed len ) + psh_hint_snap_stem_side_delta( FT_Fixed pos, + FT_Fixed len ) { - FT_Fixed delta1 = ( ( pos + 32 ) & -64 ) - pos; - FT_Fixed delta2 = ( ( pos + len + 32 ) & -64 ) - pos - len; + FT_Fixed delta1 = FT_PIX_ROUND( pos ) - pos; + FT_Fixed delta2 = FT_PIX_ROUND( pos + len ) - pos - len; - if ( ABS( delta1 ) <= ABS( delta2 ) ) + if ( FT_ABS( delta1 ) <= FT_ABS( delta2 ) ) return delta1; else return delta2; @@ -427,17 +435,17 @@ static void - psh3_hint_align( PSH3_Hint hint, - PSH_Globals globals, - FT_Int dimension, - PSH3_Glyph glyph ) + psh_hint_align( PSH_Hint hint, + PSH_Globals globals, + FT_Int dimension, + PSH_Glyph glyph ) { PSH_Dimension dim = &globals->dimension[dimension]; FT_Fixed scale = dim->scale_mult; FT_Fixed delta = dim->scale_delta; - if ( !psh3_hint_is_fitted( hint ) ) + if ( !psh_hint_is_fitted( hint ) ) { FT_Pos pos = FT_MulFix( hint->org_pos, scale ) + delta; FT_Pos len = FT_MulFix( hint->org_len, scale ); @@ -454,13 +462,13 @@ hint->cur_pos = pos; hint->cur_len = len; - psh3_hint_set_fitted( hint ); + psh_hint_set_fitted( hint ); return; } - /* perform stem snapping when requested - this is necessary - * for monochrome and LCD hinting modes only - */ + /* perform stem snapping when requested - this is necessary + * for monochrome and LCD hinting modes only + */ do_snapping = ( dimension == 0 && glyph->do_horz_snapping ) || ( dimension == 1 && glyph->do_vert_snapping ); @@ -496,7 +504,7 @@ default: { - PSH3_Hint parent = hint->parent; + PSH_Hint parent = hint->parent; if ( parent ) @@ -506,9 +514,12 @@ /* ensure that parent is already fitted */ - if ( !psh3_hint_is_fitted( parent ) ) - psh3_hint_align( parent, globals, dimension, glyph ); + if ( !psh_hint_is_fitted( parent ) ) + psh_hint_align( parent, globals, dimension, glyph ); + /* keep original relation between hints, this is, use the */ + /* scaled distance between the centers of the hints to */ + /* compute the new position */ par_org_center = parent->org_pos + ( parent->org_len >> 1 ); par_cur_center = parent->cur_pos + ( parent->cur_len >> 1 ); cur_org_center = hint->org_pos + ( hint->org_len >> 1 ); @@ -520,34 +531,34 @@ hint->cur_pos = pos; hint->cur_len = fit_len; - /* stem adjustment tries to snap stem widths to standard - * ones. this is important to prevent unpleasant rounding - * artefacts... - */ + /* Stem adjustment tries to snap stem widths to standard + * ones. This is important to prevent unpleasant rounding + * artefacts. + */ if ( glyph->do_stem_adjust ) { if ( len <= 64 ) { - /* the stem is less than one pixel, we will center it - * around the nearest pixel center - */ + /* the stem is less than one pixel; we will center it + * around the nearest pixel center + */ #if 1 - pos = ( pos + (len >> 1) ) & -64; + pos = FT_PIX_FLOOR( pos + ( len >> 1 ) ); #else - /* this seems to be a bug !! */ - pos = ( pos + ( (len >> 1) & -64 ) ); + /* this seems to be a bug! */ + pos = pos + FT_PIX_FLOOR( len >> 1 ); #endif len = 64; } else { - len = psh3_dimension_quantize_len( dim, len, 0 ); + len = psh_dimension_quantize_len( dim, len, 0 ); } } /* now that we have a good hinted stem width, try to position */ /* the stem along a pixel grid integer coordinate */ - hint->cur_pos = pos + psh3_hint_snap_stem_side_delta( pos, len ); + hint->cur_pos = pos + psh_hint_snap_stem_side_delta( pos, len ); hint->cur_len = len; } } @@ -560,7 +571,7 @@ if ( len < 64 ) len = 64; else - len = ( len + 32 ) & -64; + len = FT_PIX_ROUND( len ); switch ( align.align ) { @@ -581,20 +592,20 @@ default: hint->cur_len = len; if ( len & 64 ) - pos = ( ( pos + ( len >> 1 ) ) & -64 ) + 32; + pos = FT_PIX_FLOOR( pos + ( len >> 1 ) ) + 32; else - pos = ( pos + ( len >> 1 ) + 32 ) & -64; + pos = FT_PIX_ROUND( pos + ( len >> 1 ) ); hint->cur_pos = pos - ( len >> 1 ); hint->cur_len = len; } } - psh3_hint_set_fitted( hint ); + psh_hint_set_fitted( hint ); #ifdef DEBUG_HINTER - if ( ps3_debug_hint_func ) - ps3_debug_hint_func( hint, dimension ); + if ( ps_debug_hint_func ) + ps_debug_hint_func( hint, dimension ); #endif } } @@ -607,17 +618,17 @@ * of stems */ static void - psh3_hint_align_light( PSH3_Hint hint, - PSH_Globals globals, - FT_Int dimension, - PSH3_Glyph glyph ) + psh_hint_align_light( PSH_Hint hint, + PSH_Globals globals, + FT_Int dimension, + PSH_Glyph glyph ) { PSH_Dimension dim = &globals->dimension[dimension]; FT_Fixed scale = dim->scale_mult; FT_Fixed delta = dim->scale_delta; - if ( !psh3_hint_is_fitted(hint) ) + if ( !psh_hint_is_fitted( hint ) ) { FT_Pos pos = FT_MulFix( hint->org_pos, scale ) + delta; FT_Pos len = FT_MulFix( hint->org_len, scale ); @@ -626,6 +637,7 @@ PSH_AlignmentRec align; + /* ignore stem alignments when requested through the hint flags */ if ( ( dimension == 0 && !glyph->do_horz_hints ) || ( dimension == 1 && !glyph->do_vert_hints ) ) @@ -633,7 +645,7 @@ hint->cur_pos = pos; hint->cur_len = len; - psh3_hint_set_fitted( hint ); + psh_hint_set_fitted( hint ); return; } @@ -671,7 +683,7 @@ default: { - PSH3_Hint parent = hint->parent; + PSH_Hint parent = hint->parent; if ( parent ) @@ -681,82 +693,85 @@ /* ensure that parent is already fitted */ - if ( !psh3_hint_is_fitted( parent ) ) - psh3_hint_align_light( parent, globals, dimension, glyph ); + if ( !psh_hint_is_fitted( parent ) ) + psh_hint_align_light( parent, globals, dimension, glyph ); - par_org_center = parent->org_pos + ( parent->org_len / 2); - par_cur_center = parent->cur_pos + ( parent->cur_len / 2); - cur_org_center = hint->org_pos + ( hint->org_len / 2); + par_org_center = parent->org_pos + ( parent->org_len / 2 ); + par_cur_center = parent->cur_pos + ( parent->cur_len / 2 ); + cur_org_center = hint->org_pos + ( hint->org_len / 2 ); cur_delta = FT_MulFix( cur_org_center - par_org_center, scale ); pos = par_cur_center + cur_delta - ( len >> 1 ); } - /* Stems less than one pixel wide are easy - we want to - * make them as dark as possible, so they must fall within - * one pixel. If the stem is split between two pixels - * then snap the edge that is nearer to the pixel boundary - * to the pixel boundary - */ - if (len <= 64) + /* Stems less than one pixel wide are easy -- we want to + * make them as dark as possible, so they must fall within + * one pixel. If the stem is split between two pixels + * then snap the edge that is nearer to the pixel boundary + * to the pixel boundary. + */ + if ( len <= 64 ) { if ( ( pos + len + 63 ) / 64 != pos / 64 + 1 ) - pos += psh3_hint_snap_stem_side_delta ( pos, len ); + pos += psh_hint_snap_stem_side_delta ( pos, len ); } - /* Position stems other to minimize the amount of mid-grays. - * There are, in general, two positions that do this, - * illustrated as A) and B) below. - * - * + + + + - * - * A) |--------------------------------| - * B) |--------------------------------| - * C) |--------------------------------| - * - * Position A) (split the excess stem equally) should be better - * for stems of width N + f where f < 0.5 - * - * Position B) (split the deficiency equally) should be better - * for stems of width N + f where f > 0.5 - * - * It turns out though that minimizing the total number of lit - * pixels is also important, so position C), with one edge - * aligned with a pixel boundary is actually preferable - * to A). There are also more possibile positions for C) than - * for A) or B), so it involves less distortion of the overall - * character shape. - */ + + /* Position stems other to minimize the amount of mid-grays. + * There are, in general, two positions that do this, + * illustrated as A) and B) below. + * + * + + + + + * + * A) |--------------------------------| + * B) |--------------------------------| + * C) |--------------------------------| + * + * Position A) (split the excess stem equally) should be better + * for stems of width N + f where f < 0.5. + * + * Position B) (split the deficiency equally) should be better + * for stems of width N + f where f > 0.5. + * + * It turns out though that minimizing the total number of lit + * pixels is also important, so position C), with one edge + * aligned with a pixel boundary is actually preferable + * to A). There are also more possibile positions for C) than + * for A) or B), so it involves less distortion of the overall + * character shape. + */ else /* len > 64 */ { - FT_Fixed frac_len = len & 63; - FT_Fixed center = pos + ( len >> 1 ); - FT_Fixed delta_a, delta_b; + FT_Fixed frac_len = len & 63; + FT_Fixed center = pos + ( len >> 1 ); + FT_Fixed delta_a, delta_b; + if ( ( len / 64 ) & 1 ) { - delta_a = ( center & -64 ) + 32 - center; - delta_b = ( ( center + 32 ) & - 64 ) - center; + delta_a = FT_PIX_FLOOR( center ) + 32 - center; + delta_b = FT_PIX_ROUND( center ) - center; } else { - delta_a = ( ( center + 32 ) & - 64 ) - center; - delta_b = ( center & -64 ) + 32 - center; + delta_a = FT_PIX_ROUND( center ) - center; + delta_b = FT_PIX_FLOOR( center ) + 32 - center; } - /* We choose between B) and C) above based on the amount - * of fractinal stem width; for small amounts, choose - * C) always, for large amounts, B) always, and inbetween, - * pick whichever one involves less stem movement. - */ - if (frac_len < 32) + /* We choose between B) and C) above based on the amount + * of fractinal stem width; for small amounts, choose + * C) always, for large amounts, B) always, and inbetween, + * pick whichever one involves less stem movement. + */ + if ( frac_len < 32 ) { - pos += psh3_hint_snap_stem_side_delta ( pos, len ); + pos += psh_hint_snap_stem_side_delta ( pos, len ); } - else if (frac_len < 48) + else if ( frac_len < 48 ) { - FT_Fixed side_delta = psh3_hint_snap_stem_side_delta ( pos, len ); + FT_Fixed side_delta = psh_hint_snap_stem_side_delta ( pos, + len ); - if ( ABS( side_delta ) < ABS( delta_b ) ) + if ( FT_ABS( side_delta ) < FT_ABS( delta_b ) ) pos += side_delta; else pos += delta_b; @@ -771,11 +786,11 @@ } } /* switch */ - psh3_hint_set_fitted( hint ); + psh_hint_set_fitted( hint ); #ifdef DEBUG_HINTER - if ( ps3_debug_hint_func ) - ps3_debug_hint_func( hint, dimension ); + if ( ps_debug_hint_func ) + ps_debug_hint_func( hint, dimension ); #endif } } @@ -784,12 +799,12 @@ static void - psh3_hint_table_align_hints( PSH3_Hint_Table table, - PSH_Globals globals, - FT_Int dimension, - PSH3_Glyph glyph ) + psh_hint_table_align_hints( PSH_Hint_Table table, + PSH_Globals globals, + FT_Int dimension, + PSH_Glyph glyph ) { - PSH3_Hint hint; + PSH_Hint hint; FT_UInt count; #ifdef DEBUG_HINTER @@ -801,13 +816,13 @@ if ( ps_debug_no_vert_hints && dimension == 0 ) { - ps3_simple_scale( table, scale, delta, dimension ); + ps_simple_scale( table, scale, delta, dimension ); return; } if ( ps_debug_no_horz_hints && dimension == 1 ) { - ps3_simple_scale( table, scale, delta, dimension ); + ps_simple_scale( table, scale, delta, dimension ); return; } @@ -817,7 +832,7 @@ count = table->max_hints; for ( ; count > 0; count--, hint++ ) - psh3_hint_align( hint, globals, dimension, glyph ); + psh_hint_align( hint, globals, dimension, glyph ); } @@ -829,8 +844,8 @@ /*************************************************************************/ /*************************************************************************/ -#define PSH3_ZONE_MIN -3200000L -#define PSH3_ZONE_MAX +3200000L +#define PSH_ZONE_MIN -3200000L +#define PSH_ZONE_MAX +3200000L #define xxDEBUG_ZONES @@ -840,7 +855,7 @@ #include <stdio.h> static void - psh3_print_zone( PSH3_Zone zone ) + psh_print_zone( PSH_Zone zone ) { printf( "zone [scale,delta,min,max] = [%.3f,%.3f,%d,%d]\n", zone->scale / 65536.0, @@ -851,7 +866,7 @@ #else -#define psh3_print_zone( x ) do { } while ( 0 ) +#define psh_print_zone( x ) do { } while ( 0 ) #endif /* DEBUG_ZONES */ @@ -868,17 +883,17 @@ /* compute all inflex points in a given glyph */ static void - psh3_glyph_compute_inflections( PSH3_Glyph glyph ) + psh_glyph_compute_inflections( PSH_Glyph glyph ) { FT_UInt n; for ( n = 0; n < glyph->num_contours; n++ ) { - PSH3_Point first, start, end, before, after; - FT_Angle angle_in, angle_seg, angle_out; - FT_Angle diff_in, diff_out; - FT_Int finished = 0; + PSH_Point first, start, end, before, after; + FT_Angle angle_in, angle_seg, angle_out; + FT_Angle diff_in, diff_out; + FT_Int finished = 0; /* we need at least 4 points to create an inflection point */ @@ -895,9 +910,9 @@ if ( end == first ) goto Skip; - } while ( PSH3_POINT_EQUAL_ORG( end, first ) ); + } while ( PSH_POINT_EQUAL_ORG( end, first ) ); - angle_seg = PSH3_POINT_ANGLE( start, end ); + angle_seg = PSH_POINT_ANGLE( start, end ); /* extend the segment start whenever possible */ before = start; @@ -910,9 +925,9 @@ if ( before == first ) goto Skip; - } while ( PSH3_POINT_EQUAL_ORG( before, start ) ); + } while ( PSH_POINT_EQUAL_ORG( before, start ) ); - angle_in = PSH3_POINT_ANGLE( before, start ); + angle_in = PSH_POINT_ANGLE( before, start ); } while ( angle_in == angle_seg ); @@ -933,9 +948,9 @@ if ( after == first ) finished = 1; - } while ( PSH3_POINT_EQUAL_ORG( end, after ) ); + } while ( PSH_POINT_EQUAL_ORG( end, after ) ); - angle_out = PSH3_POINT_ANGLE( end, after ); + angle_out = PSH_POINT_ANGLE( end, after ); } while ( angle_out == angle_seg ); @@ -948,12 +963,12 @@ do { - psh3_point_set_inflex( start ); + psh_point_set_inflex( start ); start = start->next; } while ( start != end ); - psh3_point_set_inflex( start ); + psh_point_set_inflex( start ); } start = end; @@ -972,13 +987,13 @@ static void - psh3_glyph_done( PSH3_Glyph glyph ) + psh_glyph_done( PSH_Glyph glyph ) { FT_Memory memory = glyph->memory; - psh3_hint_table_done( &glyph->hint_tables[1], memory ); - psh3_hint_table_done( &glyph->hint_tables[0], memory ); + psh_hint_table_done( &glyph->hint_tables[1], memory ); + psh_hint_table_done( &glyph->hint_tables[0], memory ); FT_FREE( glyph->points ); FT_FREE( glyph->contours ); @@ -991,11 +1006,11 @@ static int - psh3_compute_dir( FT_Pos dx, - FT_Pos dy ) + psh_compute_dir( FT_Pos dx, + FT_Pos dy ) { FT_Pos ax, ay; - int result = PSH3_DIR_NONE; + int result = PSH_DIR_NONE; ax = ( dx >= 0 ) ? dx : -dx; @@ -1004,12 +1019,12 @@ if ( ay * 12 < ax ) { /* |dy| <<< |dx| means a near-horizontal segment */ - result = ( dx >= 0 ) ? PSH3_DIR_RIGHT : PSH3_DIR_LEFT; + result = ( dx >= 0 ) ? PSH_DIR_RIGHT : PSH_DIR_LEFT; } else if ( ax * 12 < ay ) { /* |dx| <<< |dy| means a near-vertical segment */ - result = ( dy >= 0 ) ? PSH3_DIR_UP : PSH3_DIR_DOWN; + result = ( dy >= 0 ) ? PSH_DIR_UP : PSH_DIR_DOWN; } return result; @@ -1018,11 +1033,11 @@ /* load outline point coordinates into hinter glyph */ static void - psh3_glyph_load_points( PSH3_Glyph glyph, - FT_Int dimension ) + psh_glyph_load_points( PSH_Glyph glyph, + FT_Int dimension ) { FT_Vector* vec = glyph->outline->points; - PSH3_Point point = glyph->points; + PSH_Point point = glyph->points; FT_UInt count = glyph->num_points; @@ -1052,11 +1067,11 @@ /* save hinted point coordinates back to outline */ static void - psh3_glyph_save_points( PSH3_Glyph glyph, - FT_Int dimension ) + psh_glyph_save_points( PSH_Glyph glyph, + FT_Int dimension ) { FT_UInt n; - PSH3_Point point = glyph->points; + PSH_Point point = glyph->points; FT_Vector* vec = glyph->outline->points; char* tags = glyph->outline->tags; @@ -1068,7 +1083,7 @@ else vec[n].y = point->cur_u; - if ( psh3_point_is_strong( point ) ) + if ( psh_point_is_strong( point ) ) tags[n] |= (char)( ( dimension == 0 ) ? 32 : 64 ); #ifdef DEBUG_HINTER @@ -1092,10 +1107,10 @@ static FT_Error - psh3_glyph_init( PSH3_Glyph glyph, - FT_Outline* outline, - PS_Hints ps_hints, - PSH_Globals globals ) + psh_glyph_init( PSH_Glyph glyph, + FT_Outline* outline, + PS_Hints ps_hints, + PSH_Globals globals ) { FT_Error error; FT_Memory memory; @@ -1104,7 +1119,7 @@ /* clear all fields */ FT_MEM_ZERO( glyph, sizeof ( *glyph ) ); - memory = globals->memory; + memory = glyph->memory = globals->memory; /* allocate and setup points + contours arrays */ if ( FT_NEW_ARRAY( glyph->points, outline->n_points ) || @@ -1115,15 +1130,15 @@ glyph->num_contours = outline->n_contours; { - FT_UInt first = 0, next, n; - PSH3_Point points = glyph->points; - PSH3_Contour contour = glyph->contours; + FT_UInt first = 0, next, n; + PSH_Point points = glyph->points; + PSH_Contour contour = glyph->contours; for ( n = 0; n < glyph->num_contours; n++ ) { - FT_Int count; - PSH3_Point point; + FT_Int count; + PSH_Point point; next = outline->contours[n] + 1; @@ -1155,40 +1170,40 @@ } { - PSH3_Point points = glyph->points; - PSH3_Point point = points; + PSH_Point points = glyph->points; + PSH_Point point = points; FT_Vector* vec = outline->points; FT_UInt n; for ( n = 0; n < glyph->num_points; n++, point++ ) { - FT_Int n_prev = point->prev - points; - FT_Int n_next = point->next - points; + FT_Int n_prev = (FT_Int)( point->prev - points ); + FT_Int n_next = (FT_Int)( point->next - points ); FT_Pos dxi, dyi, dxo, dyo; if ( !( outline->tags[n] & FT_CURVE_TAG_ON ) ) - point->flags = PSH3_POINT_OFF; + point->flags = PSH_POINT_OFF; dxi = vec[n].x - vec[n_prev].x; dyi = vec[n].y - vec[n_prev].y; - point->dir_in = (FT_Char)psh3_compute_dir( dxi, dyi ); + point->dir_in = (FT_Char)psh_compute_dir( dxi, dyi ); dxo = vec[n_next].x - vec[n].x; dyo = vec[n_next].y - vec[n].y; - point->dir_out = (FT_Char)psh3_compute_dir( dxo, dyo ); + point->dir_out = (FT_Char)psh_compute_dir( dxo, dyo ); /* detect smooth points */ - if ( point->flags & PSH3_POINT_OFF ) - point->flags |= PSH3_POINT_SMOOTH; - else if ( point->dir_in != PSH3_DIR_NONE || - point->dir_out != PSH3_DIR_NONE ) + if ( point->flags & PSH_POINT_OFF ) + point->flags |= PSH_POINT_SMOOTH; + else if ( point->dir_in != PSH_DIR_NONE || + point->dir_out != PSH_DIR_NONE ) { if ( point->dir_in == point->dir_out ) - point->flags |= PSH3_POINT_SMOOTH; + point->flags |= PSH_POINT_SMOOTH; } else { @@ -1206,34 +1221,33 @@ diff = FT_ANGLE_2PI - diff; if ( diff < FT_ANGLE_PI / 16 ) - point->flags |= PSH3_POINT_SMOOTH; + point->flags |= PSH_POINT_SMOOTH; } } } - glyph->memory = memory; glyph->outline = outline; glyph->globals = globals; #ifdef COMPUTE_INFLEXS - psh3_glyph_load_points( glyph, 0 ); - psh3_glyph_compute_inflections( glyph ); + psh_glyph_load_points( glyph, 0 ); + psh_glyph_compute_inflections( glyph ); #endif /* COMPUTE_INFLEXS */ /* now deal with hints tables */ - error = psh3_hint_table_init( &glyph->hint_tables [0], - &ps_hints->dimension[0].hints, - &ps_hints->dimension[0].masks, - &ps_hints->dimension[0].counters, - memory ); + error = psh_hint_table_init( &glyph->hint_tables [0], + &ps_hints->dimension[0].hints, + &ps_hints->dimension[0].masks, + &ps_hints->dimension[0].counters, + memory ); if ( error ) goto Exit; - error = psh3_hint_table_init( &glyph->hint_tables [1], - &ps_hints->dimension[1].hints, - &ps_hints->dimension[1].masks, - &ps_hints->dimension[1].counters, - memory ); + error = psh_hint_table_init( &glyph->hint_tables [1], + &ps_hints->dimension[1].hints, + &ps_hints->dimension[1].masks, + &ps_hints->dimension[1].counters, + memory ); if ( error ) goto Exit; @@ -1244,7 +1258,7 @@ /* compute all extrema in a glyph for a given dimension */ static void - psh3_glyph_compute_extrema( PSH3_Glyph glyph ) + psh_glyph_compute_extrema( PSH_Glyph glyph ) { FT_UInt n; @@ -1252,10 +1266,13 @@ /* first of all, compute all local extrema */ for ( n = 0; n < glyph->num_contours; n++ ) { - PSH3_Point first = glyph->contours[n].start; - PSH3_Point point, before, after; + PSH_Point first = glyph->contours[n].start; + PSH_Point point, before, after; + if ( glyph->contours[n].count == 0 ) + continue; + point = first; before = point; after = point; @@ -1297,7 +1314,7 @@ Extremum: do { - psh3_point_set_extremum( point ); + psh_point_set_extremum( point ); point = point->next; } while ( point != after ); @@ -1313,18 +1330,18 @@ ; } - /* for each extrema, determine its direction along the */ - /* orthogonal axis */ + /* for each extremum, determine its direction along the */ + /* orthogonal axis */ for ( n = 0; n < glyph->num_points; n++ ) { - PSH3_Point point, before, after; + PSH_Point point, before, after; point = &glyph->points[n]; before = point; after = point; - if ( psh3_point_is_extremum( point ) ) + if ( psh_point_is_extremum( point ) ) { do { @@ -1346,12 +1363,12 @@ if ( before->org_v < point->org_v && after->org_v > point->org_v ) { - psh3_point_set_positive( point ); + psh_point_set_positive( point ); } else if ( before->org_v > point->org_v && after->org_v < point->org_v ) { - psh3_point_set_negative( point ); + psh_point_set_negative( point ); } Skip: @@ -1360,27 +1377,25 @@ } -#define PSH3_STRONG_THRESHOLD 30 - - /* major_dir is the direction for points on the bottom/left of the stem; */ /* Points on the top/right of the stem will have a direction of */ /* -major_dir. */ static void - psh3_hint_table_find_strong_point( PSH3_Hint_Table table, - PSH3_Point point, - FT_Int major_dir ) + psh_hint_table_find_strong_point( PSH_Hint_Table table, + PSH_Point point, + FT_Int threshold, + FT_Int major_dir ) { - PSH3_Hint* sort = table->sort; - FT_UInt num_hints = table->num_hints; - FT_Int point_dir = 0; + PSH_Hint* sort = table->sort; + FT_UInt num_hints = table->num_hints; + FT_Int point_dir = 0; - if ( PSH3_DIR_COMPARE( point->dir_in, major_dir ) ) + if ( PSH_DIR_COMPARE( point->dir_in, major_dir ) ) point_dir = point->dir_in; - else if ( PSH3_DIR_COMPARE( point->dir_out, major_dir ) ) + else if ( PSH_DIR_COMPARE( point->dir_out, major_dir ) ) point_dir = point->dir_out; if ( point_dir ) @@ -1390,19 +1405,19 @@ for ( ; num_hints > 0; num_hints--, sort++ ) { - PSH3_Hint hint = sort[0]; - FT_Pos d; + PSH_Hint hint = sort[0]; + FT_Pos d; if ( point_dir == major_dir ) { - flag = PSH3_POINT_EDGE_MIN; + flag = PSH_POINT_EDGE_MIN; d = point->org_u - hint->org_pos; - if ( ABS( d ) < PSH3_STRONG_THRESHOLD ) + if ( FT_ABS( d ) < threshold ) { Is_Strong: - psh3_point_set_strong( point ); + psh_point_set_strong( point ); point->flags2 |= flag; point->hint = hint; break; @@ -1410,59 +1425,60 @@ } else if ( point_dir == -major_dir ) { - flag = PSH3_POINT_EDGE_MAX; - d = point->org_u - hint->org_pos - hint->org_len; + flag = PSH_POINT_EDGE_MAX; + d = point->org_u - hint->org_pos - hint->org_len; - if ( ABS( d ) < PSH3_STRONG_THRESHOLD ) + if ( FT_ABS( d ) < threshold ) goto Is_Strong; } } } #if 1 - else if ( psh3_point_is_extremum( point ) ) + else if ( psh_point_is_extremum( point ) ) { /* treat extrema as special cases for stem edge alignment */ FT_UInt min_flag, max_flag; - if ( major_dir == PSH3_DIR_HORIZONTAL ) + if ( major_dir == PSH_DIR_HORIZONTAL ) { - min_flag = PSH3_POINT_POSITIVE; - max_flag = PSH3_POINT_NEGATIVE; + min_flag = PSH_POINT_POSITIVE; + max_flag = PSH_POINT_NEGATIVE; } else { - min_flag = PSH3_POINT_NEGATIVE; - max_flag = PSH3_POINT_POSITIVE; + min_flag = PSH_POINT_NEGATIVE; + max_flag = PSH_POINT_POSITIVE; } for ( ; num_hints > 0; num_hints--, sort++ ) { - PSH3_Hint hint = sort[0]; - FT_Pos d, flag; + PSH_Hint hint = sort[0]; + FT_Pos d; + FT_Int flag; if ( point->flags2 & min_flag ) { - flag = PSH3_POINT_EDGE_MIN; + flag = PSH_POINT_EDGE_MIN; d = point->org_u - hint->org_pos; - if ( ABS( d ) < PSH3_STRONG_THRESHOLD ) + if ( FT_ABS( d ) < threshold ) { Is_Strong2: point->flags2 |= flag; point->hint = hint; - psh3_point_set_strong( point ); + psh_point_set_strong( point ); break; } } else if ( point->flags2 & max_flag ) { - flag = PSH3_POINT_EDGE_MAX; + flag = PSH_POINT_EDGE_MAX; d = point->org_u - hint->org_pos - hint->org_len; - if ( ABS( d ) < PSH3_STRONG_THRESHOLD ) + if ( FT_ABS( d ) < threshold ) goto Is_Strong2; } @@ -1478,74 +1494,165 @@ } + /* the accepted shift for strong points in fractional pixels */ +#define PSH_STRONG_THRESHOLD 32 + + /* the maximum shift value in font units */ +#define PSH_STRONG_THRESHOLD_MAXIMUM 30 + + /* find strong points in a glyph */ static void - psh3_glyph_find_strong_points( PSH3_Glyph glyph, - FT_Int dimension ) + psh_glyph_find_strong_points( PSH_Glyph glyph, + FT_Int dimension ) { - /* a point is strong if it is located on a stem */ - /* edge and has an "in" or "out" tangent to the hint's direction */ + /* a point is `strong' if it is located on a stem edge and */ + /* has an `in' or `out' tangent parallel to the hint's direction */ + + PSH_Hint_Table table = &glyph->hint_tables[dimension]; + PS_Mask mask = table->hint_masks->masks; + FT_UInt num_masks = table->hint_masks->num_masks; + FT_UInt first = 0; + FT_Int major_dir = dimension == 0 ? PSH_DIR_VERTICAL + : PSH_DIR_HORIZONTAL; + PSH_Dimension dim = &glyph->globals->dimension[dimension]; + FT_Fixed scale = dim->scale_mult; + FT_Int threshold; + + + threshold = (FT_Int)FT_DivFix( PSH_STRONG_THRESHOLD, scale ); + if ( threshold > PSH_STRONG_THRESHOLD_MAXIMUM ) + threshold = PSH_STRONG_THRESHOLD_MAXIMUM; + + /* process secondary hints to `selected' points */ + if ( num_masks > 1 && glyph->num_points > 0 ) { - PSH3_Hint_Table table = &glyph->hint_tables[dimension]; - PS_Mask mask = table->hint_masks->masks; - FT_UInt num_masks = table->hint_masks->num_masks; - FT_UInt first = 0; - FT_Int major_dir = dimension == 0 ? PSH3_DIR_VERTICAL - : PSH3_DIR_HORIZONTAL; - - - /* process secondary hints to "selected" points */ - if ( num_masks > 1 && glyph->num_points > 0 ) + first = mask->end_point; + mask++; + for ( ; num_masks > 1; num_masks--, mask++ ) { - first = mask->end_point; - mask++; - for ( ; num_masks > 1; num_masks--, mask++ ) + FT_UInt next; + FT_Int count; + + + next = mask->end_point; + count = next - first; + if ( count > 0 ) { - FT_UInt next; - FT_Int count; + PSH_Point point = glyph->points + first; - next = mask->end_point; - count = next - first; - if ( count > 0 ) + psh_hint_table_activate_mask( table, mask ); + + for ( ; count > 0; count--, point++ ) + psh_hint_table_find_strong_point( table, point, + threshold, major_dir ); + } + first = next; + } + } + + /* process primary hints for all points */ + if ( num_masks == 1 ) + { + FT_UInt count = glyph->num_points; + PSH_Point point = glyph->points; + + + psh_hint_table_activate_mask( table, table->hint_masks->masks ); + for ( ; count > 0; count--, point++ ) + { + if ( !psh_point_is_strong( point ) ) + psh_hint_table_find_strong_point( table, point, + threshold, major_dir ); + } + } + + /* now, certain points may have been attached to a hint and */ + /* not marked as strong; update their flags then */ + { + FT_UInt count = glyph->num_points; + PSH_Point point = glyph->points; + + + for ( ; count > 0; count--, point++ ) + if ( point->hint && !psh_point_is_strong( point ) ) + psh_point_set_strong( point ); + } + } + + + /* find points in a glyph which are in a blue zone and have `in' or */ + /* `out' tangents parallel to the horizontal axis */ + static void + psh_glyph_find_blue_points( PSH_Blues blues, + PSH_Glyph glyph ) + { + PSH_Blue_Table table; + PSH_Blue_Zone zone; + FT_UInt glyph_count = glyph->num_points; + FT_UInt blue_count; + PSH_Point point = glyph->points; + + + for ( ; glyph_count > 0; glyph_count--, point++ ) + { + FT_Pos y; + + + /* check tangents */ + if ( !PSH_DIR_COMPARE( point->dir_in, PSH_DIR_HORIZONTAL ) && + !PSH_DIR_COMPARE( point->dir_out, PSH_DIR_HORIZONTAL ) ) + continue; + + /* skip strong points */ + if ( psh_point_is_strong( point ) ) + continue; + + y = point->org_u; + + /* look up top zones */ + table = &blues->normal_top; + blue_count = table->count; + zone = table->zones; + + for ( ; blue_count > 0; blue_count--, zone++ ) + { + FT_Pos delta = y - zone->org_bottom; + + + if ( delta < -blues->blue_fuzz ) + break; + + if ( y <= zone->org_top + blues->blue_fuzz ) + if ( blues->no_overshoots || delta <= blues->blue_threshold ) { - PSH3_Point point = glyph->points + first; - - - psh3_hint_table_activate_mask( table, mask ); - - for ( ; count > 0; count--, point++ ) - psh3_hint_table_find_strong_point( table, point, major_dir ); + point->cur_u = zone->cur_bottom; + psh_point_set_strong( point ); + psh_point_set_fitted( point ); } - first = next; - } } - /* process primary hints for all points */ - if ( num_masks == 1 ) + /* look up bottom zones */ + table = &blues->normal_bottom; + blue_count = table->count; + zone = table->zones + blue_count - 1; + + for ( ; blue_count > 0; blue_count--, zone-- ) { - FT_UInt count = glyph->num_points; - PSH3_Point point = glyph->points; + FT_Pos delta = zone->org_top - y; - psh3_hint_table_activate_mask( table, table->hint_masks->masks ); - for ( ; count > 0; count--, point++ ) - { - if ( !psh3_point_is_strong( point ) ) - psh3_hint_table_find_strong_point( table, point, major_dir ); - } - } + if ( delta < -blues->blue_fuzz ) + break; - /* now, certain points may have been attached to hint and */ - /* not marked as strong; update their flags then */ - { - FT_UInt count = glyph->num_points; - PSH3_Point point = glyph->points; - - - for ( ; count > 0; count--, point++ ) - if ( point->hint && !psh3_point_is_strong( point ) ) - psh3_point_set_strong( point ); + if ( y >= zone->org_bottom - blues->blue_fuzz ) + if ( blues->no_overshoots || delta < blues->blue_threshold ) + { + point->cur_u = zone->cur_top; + psh_point_set_strong( point ); + psh_point_set_fitted( point ); + } } } } @@ -1553,170 +1660,163 @@ /* interpolate strong points with the help of hinted coordinates */ static void - psh3_glyph_interpolate_strong_points( PSH3_Glyph glyph, - FT_Int dimension ) + psh_glyph_interpolate_strong_points( PSH_Glyph glyph, + FT_Int dimension ) { PSH_Dimension dim = &glyph->globals->dimension[dimension]; FT_Fixed scale = dim->scale_mult; + FT_UInt count = glyph->num_points; + PSH_Point point = glyph->points; + + for ( ; count > 0; count--, point++ ) { - FT_UInt count = glyph->num_points; - PSH3_Point point = glyph->points; + PSH_Hint hint = point->hint; - for ( ; count > 0; count--, point++ ) + if ( hint ) { - PSH3_Hint hint = point->hint; + FT_Pos delta; - if ( hint ) + if ( psh_point_is_edge_min( point ) ) + point->cur_u = hint->cur_pos; + + else if ( psh_point_is_edge_max( point ) ) + point->cur_u = hint->cur_pos + hint->cur_len; + + else { - FT_Pos delta; + delta = point->org_u - hint->org_pos; + if ( delta <= 0 ) + point->cur_u = hint->cur_pos + FT_MulFix( delta, scale ); - if ( psh3_point_is_edge_min( point ) ) - { - point->cur_u = hint->cur_pos; - } - else if ( psh3_point_is_edge_max( point ) ) - { - point->cur_u = hint->cur_pos + hint->cur_len; - } + else if ( delta >= hint->org_len ) + point->cur_u = hint->cur_pos + hint->cur_len + + FT_MulFix( delta - hint->org_len, scale ); + + else if ( hint->org_len > 0 ) + point->cur_u = hint->cur_pos + + FT_MulDiv( delta, hint->cur_len, + hint->org_len ); else - { - delta = point->org_u - hint->org_pos; - - if ( delta <= 0 ) - point->cur_u = hint->cur_pos + FT_MulFix( delta, scale ); - - else if ( delta >= hint->org_len ) - point->cur_u = hint->cur_pos + hint->cur_len + - FT_MulFix( delta - hint->org_len, scale ); - - else if ( hint->org_len > 0 ) - point->cur_u = hint->cur_pos + - FT_MulDiv( delta, hint->cur_len, - hint->org_len ); - else - point->cur_u = hint->cur_pos; - } - psh3_point_set_fitted( point ); + point->cur_u = hint->cur_pos; } + psh_point_set_fitted( point ); } } } static void - psh3_glyph_interpolate_normal_points( PSH3_Glyph glyph, - FT_Int dimension ) + psh_glyph_interpolate_normal_points( PSH_Glyph glyph, + FT_Int dimension ) { #if 1 + /* first technique: a point is strong if it is a local extremum */ PSH_Dimension dim = &glyph->globals->dimension[dimension]; FT_Fixed scale = dim->scale_mult; + FT_UInt count = glyph->num_points; + PSH_Point point = glyph->points; - /* first technique: a point is strong if it is a local extrema */ + + for ( ; count > 0; count--, point++ ) { - FT_UInt count = glyph->num_points; - PSH3_Point point = glyph->points; + if ( psh_point_is_strong( point ) ) + continue; - - for ( ; count > 0; count--, point++ ) + /* sometimes, some local extrema are smooth points */ + if ( psh_point_is_smooth( point ) ) { - if ( psh3_point_is_strong( point ) ) + if ( point->dir_in == PSH_DIR_NONE || + point->dir_in != point->dir_out ) continue; - /* sometimes, some local extremas are smooth points */ - if ( psh3_point_is_smooth( point ) ) + if ( !psh_point_is_extremum( point ) && + !psh_point_is_inflex( point ) ) + continue; + + point->flags &= ~PSH_POINT_SMOOTH; + } + + /* find best enclosing point coordinates */ + { + PSH_Point before = 0; + PSH_Point after = 0; + + FT_Pos diff_before = -32000; + FT_Pos diff_after = 32000; + FT_Pos u = point->org_u; + + FT_Int count2 = glyph->num_points; + PSH_Point cur = glyph->points; + + + for ( ; count2 > 0; count2--, cur++ ) { - if ( point->dir_in == PSH3_DIR_NONE || - point->dir_in != point->dir_out ) - continue; - - if ( !psh3_point_is_extremum( point ) && - !psh3_point_is_inflex( point ) ) - continue; - - point->flags &= ~PSH3_POINT_SMOOTH; - } - - /* find best enclosing point coordinates */ - { - PSH3_Point before = 0; - PSH3_Point after = 0; - - FT_Pos diff_before = -32000; - FT_Pos diff_after = 32000; - FT_Pos u = point->org_u; - - FT_Int count2 = glyph->num_points; - PSH3_Point cur = glyph->points; - - - for ( ; count2 > 0; count2--, cur++ ) + if ( psh_point_is_strong( cur ) ) { - if ( psh3_point_is_strong( cur ) ) + FT_Pos diff = cur->org_u - u; + + + if ( diff <= 0 ) { - FT_Pos diff = cur->org_u - u;; - - - if ( diff <= 0 ) + if ( diff > diff_before ) { - if ( diff > diff_before ) - { - diff_before = diff; - before = cur; - } + diff_before = diff; + before = cur; } - else if ( diff >= 0 ) + } + + else if ( diff >= 0 ) + { + if ( diff < diff_after ) { - if ( diff < diff_after ) - { - diff_after = diff; - after = cur; - } + diff_after = diff; + after = cur; } } } + } - if ( !before ) - { - if ( !after ) - continue; + if ( !before ) + { + if ( !after ) + continue; - /* we are before the first strong point coordinate; */ - /* simply translate the point */ - point->cur_u = after->cur_u + + /* we are before the first strong point coordinate; */ + /* simply translate the point */ + point->cur_u = after->cur_u + FT_MulFix( point->org_u - after->org_u, scale ); - } - else if ( !after ) - { - /* we are after the last strong point coordinate; */ - /* simply translate the point */ - point->cur_u = before->cur_u + + } + else if ( !after ) + { + /* we are after the last strong point coordinate; */ + /* simply translate the point */ + point->cur_u = before->cur_u + FT_MulFix( point->org_u - before->org_u, scale ); - } + } + else + { + if ( diff_before == 0 ) + point->cur_u = before->cur_u; + + else if ( diff_after == 0 ) + point->cur_u = after->cur_u; + else - { - if ( diff_before == 0 ) - point->cur_u = before->cur_u; - - else if ( diff_after == 0 ) - point->cur_u = after->cur_u; - - else - point->cur_u = before->cur_u + + point->cur_u = before->cur_u + FT_MulDiv( u - before->org_u, after->cur_u - before->cur_u, after->org_u - before->org_u ); - } - - psh3_point_set_fitted( point ); } + + psh_point_set_fitted( point ); } } @@ -1727,21 +1827,21 @@ /* interpolate other points */ static void - psh3_glyph_interpolate_other_points( PSH3_Glyph glyph, - FT_Int dimension ) + psh_glyph_interpolate_other_points( PSH_Glyph glyph, + FT_Int dimension ) { PSH_Dimension dim = &glyph->globals->dimension[dimension]; FT_Fixed scale = dim->scale_mult; FT_Fixed delta = dim->scale_delta; - PSH3_Contour contour = glyph->contours; + PSH_Contour contour = glyph->contours; FT_UInt num_contours = glyph->num_contours; for ( ; num_contours > 0; num_contours--, contour++ ) { - PSH3_Point start = contour->start; - PSH3_Point first, next, point; - FT_UInt fit_count; + PSH_Point start = contour->start; + PSH_Point first, next, point; + FT_UInt fit_count; /* count the number of strong points in this contour */ @@ -1750,7 +1850,7 @@ first = 0; for ( point = start; point < next; point++ ) - if ( psh3_point_is_fitted( point ) ) + if ( psh_point_is_fitted( point ) ) { if ( !first ) first = point; @@ -1786,7 +1886,7 @@ if ( next == start ) goto Next_Contour; - if ( !psh3_point_is_fitted( next ) ) + if ( !psh_point_is_fitted( next ) ) break; first = next; @@ -1796,7 +1896,7 @@ for (;;) { next = next->next; - if ( psh3_point_is_fitted( next ) ) + if ( psh_point_is_fitted( next ) ) break; } @@ -1875,41 +1975,72 @@ /*************************************************************************/ FT_Error - ps3_hints_apply( PS_Hints ps_hints, - FT_Outline* outline, - PSH_Globals globals, - FT_Render_Mode hint_mode ) + ps_hints_apply( PS_Hints ps_hints, + FT_Outline* outline, + PSH_Globals globals, + FT_Render_Mode hint_mode ) { - PSH3_GlyphRec glyphrec; - PSH3_Glyph glyph = &glyphrec; - FT_Error error; + PSH_GlyphRec glyphrec; + PSH_Glyph glyph = &glyphrec; + FT_Error error; #ifdef DEBUG_HINTER - FT_Memory memory; + FT_Memory memory; #endif - FT_Int dimension; + FT_Int dimension; + /* something to do? */ + if ( outline->n_points == 0 || outline->n_contours == 0 ) + return PSH_Err_Ok; + #ifdef DEBUG_HINTER memory = globals->memory; - if ( ps3_debug_glyph ) + if ( ps_debug_glyph ) { - psh3_glyph_done( ps3_debug_glyph ); - FT_FREE( ps3_debug_glyph ); + psh_glyph_done( ps_debug_glyph ); + FT_FREE( ps_debug_glyph ); } if ( FT_NEW( glyph ) ) return error; - ps3_debug_glyph = glyph; + ps_debug_glyph = glyph; #endif /* DEBUG_HINTER */ - error = psh3_glyph_init( glyph, outline, ps_hints, globals ); + error = psh_glyph_init( glyph, outline, ps_hints, globals ); if ( error ) goto Exit; + /* try to optimize the y_scale so that the top of non-capital letters + * is aligned on a pixel boundary whenever possible + */ + { + PSH_Dimension dim_x = &glyph->globals->dimension[0]; + PSH_Dimension dim_y = &glyph->globals->dimension[1]; + + FT_Fixed x_scale = dim_x->scale_mult; + FT_Fixed y_scale = dim_y->scale_mult; + + FT_Fixed scaled; + FT_Fixed fitted; + + + scaled = FT_MulFix( globals->blues.normal_top.zones->org_ref, y_scale ); + fitted = FT_PIX_ROUND( scaled ); + + if (scaled != fitted ) { + y_scale = FT_MulDiv( y_scale, fitted, scaled ); + + if ( fitted < scaled ) + x_scale -= x_scale / 50; + + psh_globals_set_scale( glyph->globals, x_scale, y_scale, 0, 0 ); + } + } + glyph->do_horz_hints = 1; glyph->do_vert_hints = 1; @@ -1924,35 +2055,37 @@ for ( dimension = 0; dimension < 2; dimension++ ) { /* load outline coordinates into glyph */ - psh3_glyph_load_points( glyph, dimension ); + psh_glyph_load_points( glyph, dimension ); /* compute local extrema */ - psh3_glyph_compute_extrema( glyph ); + psh_glyph_compute_extrema( glyph ); /* compute aligned stem/hints positions */ - psh3_hint_table_align_hints( &glyph->hint_tables[dimension], - glyph->globals, - dimension, - glyph ); + psh_hint_table_align_hints( &glyph->hint_tables[dimension], + glyph->globals, + dimension, + glyph ); /* find strong points, align them, then interpolate others */ - psh3_glyph_find_strong_points( glyph, dimension ); - psh3_glyph_interpolate_strong_points( glyph, dimension ); - psh3_glyph_interpolate_normal_points( glyph, dimension ); - psh3_glyph_interpolate_other_points( glyph, dimension ); + psh_glyph_find_strong_points( glyph, dimension ); + if ( dimension == 1 ) + psh_glyph_find_blue_points( &globals->blues, glyph ); + psh_glyph_interpolate_strong_points( glyph, dimension ); + psh_glyph_interpolate_normal_points( glyph, dimension ); + psh_glyph_interpolate_other_points( glyph, dimension ); /* save hinted coordinates back to outline */ - psh3_glyph_save_points( glyph, dimension ); + psh_glyph_save_points( glyph, dimension ); } Exit: #ifndef DEBUG_HINTER - psh3_glyph_done( glyph ); + psh_glyph_done( glyph ); #endif return error; } -/* END */ +/* END */ diff --git a/src/libs/freetype2/pshinter/pshalgo.h b/src/libs/freetype2/pshinter/pshalgo.h index 767c00bfd7..f68de71202 100644 --- a/src/libs/freetype2/pshinter/pshalgo.h +++ b/src/libs/freetype2/pshinter/pshalgo.h @@ -2,13 +2,13 @@ /* */ /* pshalgo.h */ /* */ -/* This header file defines the used hinting algorithm. */ +/* PostScript hinting algorithm (specification). */ /* */ -/* Copyright 2001 by */ +/* Copyright 2001, 2002, 2003 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 */ +/* 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. */ @@ -19,35 +19,237 @@ #ifndef __PSHALGO_H__ #define __PSHALGO_H__ + +#include "pshrec.h" +#include "pshglob.h" +#include FT_TRIGONOMETRY_H + + FT_BEGIN_HEADER -/* define to choose hinting algorithm */ -#define PSH_ALGORITHM_3 -#if defined(PSH_ALGORITHM_1) + /* handle to Hint structure */ + typedef struct PSH_HintRec_* PSH_Hint; -# include "pshalgo1.h" -# define PS_HINTS_APPLY_FUNC ps1_hints_apply + /* hint bit-flags */ + typedef enum + { + PSH_HINT_GHOST = PS_HINT_FLAG_GHOST, + PSH_HINT_BOTTOM = PS_HINT_FLAG_BOTTOM, + PSH_HINT_ACTIVE = 4, + PSH_HINT_FITTED = 8 -#elif defined(PSH_ALGORITHM_2) + } PSH_Hint_Flags; -# include "pshalgo2.h" -# define PS_HINTS_APPLY_FUNC ps2_hints_apply -#elif defined(PSH_ALGORITHM_3) +#define psh_hint_is_active( x ) ( ( (x)->flags & PSH_HINT_ACTIVE ) != 0 ) +#define psh_hint_is_ghost( x ) ( ( (x)->flags & PSH_HINT_GHOST ) != 0 ) +#define psh_hint_is_fitted( x ) ( ( (x)->flags & PSH_HINT_FITTED ) != 0 ) -# include "pshalgo3.h" -# define PS_HINTS_APPLY_FUNC ps3_hints_apply +#define psh_hint_activate( x ) (x)->flags |= PSH_HINT_ACTIVE +#define psh_hint_deactivate( x ) (x)->flags &= ~PSH_HINT_ACTIVE +#define psh_hint_set_fitted( x ) (x)->flags |= PSH_HINT_FITTED -#else + /* hint structure */ + typedef struct PSH_HintRec_ + { + FT_Int org_pos; + FT_Int org_len; + FT_Pos cur_pos; + FT_Pos cur_len; + FT_UInt flags; + PSH_Hint parent; + FT_Int order; -# error "invalid Postscript Hinter algorithm selection" + } PSH_HintRec; + + /* this is an interpolation zone used for strong points; */ + /* weak points are interpolated according to their strong */ + /* neighbours */ + typedef struct PSH_ZoneRec_ + { + FT_Fixed scale; + FT_Fixed delta; + FT_Pos min; + FT_Pos max; + + } PSH_ZoneRec, *PSH_Zone; + + + typedef struct PSH_Hint_TableRec_ + { + FT_UInt max_hints; + FT_UInt num_hints; + PSH_Hint hints; + PSH_Hint* sort; + PSH_Hint* sort_global; + FT_UInt num_zones; + PSH_ZoneRec* zones; + PSH_Zone zone; + PS_Mask_Table hint_masks; + PS_Mask_Table counter_masks; + + } PSH_Hint_TableRec, *PSH_Hint_Table; + + + typedef struct PSH_PointRec_* PSH_Point; + typedef struct PSH_ContourRec_* PSH_Contour; + + enum + { + PSH_DIR_NONE = 4, + PSH_DIR_UP = -1, + PSH_DIR_DOWN = 1, + PSH_DIR_LEFT = -2, + PSH_DIR_RIGHT = 2 + }; + +#define PSH_DIR_HORIZONTAL 2 +#define PSH_DIR_VERTICAL 1 + +#define PSH_DIR_COMPARE( d1, d2 ) ( (d1) == (d2) || (d1) == -(d2) ) +#define PSH_DIR_IS_HORIZONTAL( d ) PSH_DIR_COMPARE( d, PSH_DIR_HORIZONTAL ) +#define PSH_DIR_IS_VERTICAL( d ) PSH_DIR_COMPARE( d, PSH_DIR_VERTICAL ) + + + /* the following bit-flags are computed once by the glyph */ + /* analyzer, for both dimensions */ + enum + { + PSH_POINT_OFF = 1, /* point is off the curve */ + PSH_POINT_SMOOTH = 2, /* point is smooth */ + PSH_POINT_INFLEX = 4 /* point is inflection */ + }; + +#define psh_point_is_smooth( p ) ( (p)->flags & PSH_POINT_SMOOTH ) +#define psh_point_is_off( p ) ( (p)->flags & PSH_POINT_OFF ) +#define psh_point_is_inflex( p ) ( (p)->flags & PSH_POINT_INFLEX ) + +#define psh_point_set_smooth( p ) (p)->flags |= PSH_POINT_SMOOTH +#define psh_point_set_off( p ) (p)->flags |= PSH_POINT_OFF +#define psh_point_set_inflex( p ) (p)->flags |= PSH_POINT_INFLEX + + /* the following bit-flags are re-computed for each dimension */ + enum + { + PSH_POINT_STRONG = 16, /* point is strong */ + PSH_POINT_FITTED = 32, /* point is already fitted */ + PSH_POINT_EXTREMUM = 64, /* point is local extremum */ + PSH_POINT_POSITIVE = 128, /* extremum has positive contour flow */ + PSH_POINT_NEGATIVE = 256, /* extremum has negative contour flow */ + PSH_POINT_EDGE_MIN = 512, /* point is aligned to left/bottom stem edge */ + PSH_POINT_EDGE_MAX = 1024 /* point is aligned to top/right stem edge */ + }; + +#define psh_point_is_strong( p ) ( (p)->flags2 & PSH_POINT_STRONG ) +#define psh_point_is_fitted( p ) ( (p)->flags2 & PSH_POINT_FITTED ) +#define psh_point_is_extremum( p ) ( (p)->flags2 & PSH_POINT_EXTREMUM ) +#define psh_point_is_positive( p ) ( (p)->flags2 & PSH_POINT_POSITIVE ) +#define psh_point_is_negative( p ) ( (p)->flags2 & PSH_POINT_NEGATIVE ) +#define psh_point_is_edge_min( p ) ( (p)->flags2 & PSH_POINT_EDGE_MIN ) +#define psh_point_is_edge_max( p ) ( (p)->flags2 & PSH_POINT_EDGE_MAX ) + +#define psh_point_set_strong( p ) (p)->flags2 |= PSH_POINT_STRONG +#define psh_point_set_fitted( p ) (p)->flags2 |= PSH_POINT_FITTED +#define psh_point_set_extremum( p ) (p)->flags2 |= PSH_POINT_EXTREMUM +#define psh_point_set_positive( p ) (p)->flags2 |= PSH_POINT_POSITIVE +#define psh_point_set_negative( p ) (p)->flags2 |= PSH_POINT_NEGATIVE +#define psh_point_set_edge_min( p ) (p)->flags2 |= PSH_POINT_EDGE_MIN +#define psh_point_set_edge_max( p ) (p)->flags2 |= PSH_POINT_EDGE_MAX + + + typedef struct PSH_PointRec_ + { + PSH_Point prev; + PSH_Point next; + PSH_Contour contour; + FT_UInt flags; + FT_UInt flags2; + FT_Char dir_in; + FT_Char dir_out; + FT_Angle angle_in; + FT_Angle angle_out; + PSH_Hint hint; + FT_Pos org_u; + FT_Pos org_v; + FT_Pos cur_u; +#ifdef DEBUG_HINTER + FT_Pos org_x; + FT_Pos cur_x; + FT_Pos org_y; + FT_Pos cur_y; + FT_UInt flags_x; + FT_UInt flags_y; #endif + } PSH_PointRec; + + +#define PSH_POINT_EQUAL_ORG( a, b ) ( (a)->org_u == (b)->org_u && \ + (a)->org_v == (b)->org_v ) + +#define PSH_POINT_ANGLE( a, b ) FT_Atan2( (b)->org_u - (a)->org_u, \ + (b)->org_v - (a)->org_v ) + + typedef struct PSH_ContourRec_ + { + PSH_Point start; + FT_UInt count; + + } PSH_ContourRec; + + + typedef struct PSH_GlyphRec_ + { + FT_UInt num_points; + FT_UInt num_contours; + + PSH_Point points; + PSH_Contour contours; + + FT_Memory memory; + FT_Outline* outline; + PSH_Globals globals; + PSH_Hint_TableRec hint_tables[2]; + + FT_Bool vertical; + FT_Int major_dir; + FT_Int minor_dir; + + FT_Bool do_horz_hints; + FT_Bool do_vert_hints; + FT_Bool do_horz_snapping; + FT_Bool do_vert_snapping; + FT_Bool do_stem_adjust; + + } PSH_GlyphRec, *PSH_Glyph; + + +#ifdef DEBUG_HINTER + extern PSH_Hint_Table ps_debug_hint_table; + + typedef void + (*PSH_HintFunc)( PSH_Hint hint, + FT_Bool vertical ); + + extern PSH_HintFunc ps_debug_hint_func; + + extern PSH_Glyph ps_debug_glyph; +#endif + + + extern FT_Error + ps_hints_apply( PS_Hints ps_hints, + FT_Outline* outline, + PSH_Globals globals, + FT_Render_Mode hint_mode ); + + FT_END_HEADER + #endif /* __PSHALGO_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/pshinter/pshalgo1.c b/src/libs/freetype2/pshinter/pshalgo1.c deleted file mode 100644 index 4dea3e5caa..0000000000 --- a/src/libs/freetype2/pshinter/pshalgo1.c +++ /dev/null @@ -1,785 +0,0 @@ -/***************************************************************************/ -/* */ -/* pshalgo1.c */ -/* */ -/* PostScript hinting algorithm 1 (body). */ -/* */ -/* Copyright 2001, 2002 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. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_DEBUG_H -#include "pshalgo1.h" - -#undef FT_COMPONENT -#define FT_COMPONENT trace_pshalgo1 - -#ifdef DEBUG_HINTER - PSH1_Hint_Table ps1_debug_hint_table = 0; - PSH1_HintFunc ps1_debug_hint_func = 0; -#endif - - - /************************************************************************/ - /************************************************************************/ - /***** *****/ - /***** BASIC HINTS RECORDINGS *****/ - /***** *****/ - /************************************************************************/ - /************************************************************************/ - - /* return true iff two stem hints overlap */ - static FT_Int - psh1_hint_overlap( PSH1_Hint hint1, - PSH1_Hint hint2 ) - { - return ( hint1->org_pos + hint1->org_len >= hint2->org_pos && - hint2->org_pos + hint2->org_len >= hint1->org_pos ); - } - - - /* destroy hints table */ - static void - psh1_hint_table_done( PSH1_Hint_Table table, - FT_Memory memory ) - { - FT_FREE( table->zones ); - table->num_zones = 0; - table->zone = 0; - - FT_FREE( table->sort ); - FT_FREE( table->hints ); - table->num_hints = 0; - table->max_hints = 0; - table->sort_global = 0; - } - - - /* deactivate all hints in a table */ - static void - psh1_hint_table_deactivate( PSH1_Hint_Table table ) - { - FT_UInt count = table->max_hints; - PSH1_Hint hint = table->hints; - - - for ( ; count > 0; count--, hint++ ) - { - psh1_hint_deactivate( hint ); - hint->order = -1; - } - } - - - /* internal function used to record a new hint */ - static void - psh1_hint_table_record( PSH1_Hint_Table table, - FT_UInt idx ) - { - PSH1_Hint hint = table->hints + idx; - - - if ( idx >= table->max_hints ) - { - FT_ERROR(( "%s.activate: invalid hint index %d\n", idx )); - return; - } - - /* ignore active hints */ - if ( psh1_hint_is_active( hint ) ) - return; - - psh1_hint_activate( hint ); - - /* now scan the current active hint set in order to determine */ - /* if we are overlapping with another segment */ - { - PSH1_Hint* sorted = table->sort_global; - FT_UInt count = table->num_hints; - PSH1_Hint hint2; - - - hint->parent = 0; - for ( ; count > 0; count--, sorted++ ) - { - hint2 = sorted[0]; - - if ( psh1_hint_overlap( hint, hint2 ) ) - { - hint->parent = hint2; - break; - } - } - } - - if ( table->num_hints < table->max_hints ) - table->sort_global[table->num_hints++] = hint; - else - FT_ERROR(( "%s.activate: too many sorted hints! BUG!\n", - "ps.fitter" )); - } - - - static void - psh1_hint_table_record_mask( PSH1_Hint_Table table, - PS_Mask hint_mask ) - { - FT_Int mask = 0, val = 0; - FT_Byte* cursor = hint_mask->bytes; - FT_UInt idx, limit; - - - limit = hint_mask->num_bits; - - if ( limit != table->max_hints ) - FT_ERROR(( "%s.activate_mask: invalid bit count (%d instead of %d)\n", - "ps.fitter", hint_mask->num_bits, table->max_hints )); - - for ( idx = 0; idx < limit; idx++ ) - { - if ( mask == 0 ) - { - val = *cursor++; - mask = 0x80; - } - - if ( val & mask ) - psh1_hint_table_record( table, idx ); - - mask >>= 1; - } - } - - - /* create hints table */ - static FT_Error - psh1_hint_table_init( PSH1_Hint_Table table, - PS_Hint_Table hints, - PS_Mask_Table hint_masks, - PS_Mask_Table counter_masks, - FT_Memory memory ) - { - FT_UInt count = hints->num_hints; - FT_Error error; - - FT_UNUSED( counter_masks ); - - - /* allocate our tables */ - if ( FT_NEW_ARRAY( table->sort, 2 * count ) || - FT_NEW_ARRAY( table->hints, count ) || - FT_NEW_ARRAY( table->zones, 2 * count + 1 ) ) - goto Exit; - - table->max_hints = count; - table->sort_global = table->sort + count; - table->num_hints = 0; - table->num_zones = 0; - table->zone = 0; - - /* now, initialize the "hints" array */ - { - PSH1_Hint write = table->hints; - PS_Hint read = hints->hints; - - - for ( ; count > 0; count--, write++, read++ ) - { - write->org_pos = read->pos; - write->org_len = read->len; - write->flags = read->flags; - } - } - - /* we now need to determine the initial "parent" stems; first */ - /* activate the hints that are given by the initial hint masks */ - if ( hint_masks ) - { - FT_UInt Count = hint_masks->num_masks; - PS_Mask Mask = hint_masks->masks; - - - table->hint_masks = hint_masks; - - for ( ; Count > 0; Count--, Mask++ ) - psh1_hint_table_record_mask( table, Mask ); - } - - /* now, do a linear parse in case some hints were left alone */ - if ( table->num_hints != table->max_hints ) - { - FT_UInt Index, Count; - - - FT_ERROR(( "%s.init: missing/incorrect hint masks!\n" )); - Count = table->max_hints; - for ( Index = 0; Index < Count; Index++ ) - psh1_hint_table_record( table, Index ); - } - - Exit: - return error; - } - - - static void - psh1_hint_table_activate_mask( PSH1_Hint_Table table, - PS_Mask hint_mask ) - { - FT_Int mask = 0, val = 0; - FT_Byte* cursor = hint_mask->bytes; - FT_UInt idx, limit, count; - - - limit = hint_mask->num_bits; - count = 0; - - psh1_hint_table_deactivate( table ); - - for ( idx = 0; idx < limit; idx++ ) - { - if ( mask == 0 ) - { - val = *cursor++; - mask = 0x80; - } - - if ( val & mask ) - { - PSH1_Hint hint = &table->hints[idx]; - - - if ( !psh1_hint_is_active( hint ) ) - { - PSH1_Hint* sort = table->sort; - FT_UInt count2; - PSH1_Hint hint2; - - - for ( count2 = count; count2 > 0; count2--, sort++ ) - { - hint2 = sort[0]; - if ( psh1_hint_overlap( hint, hint2 ) ) - { - FT_ERROR(( "%s.activate_mask: found overlapping hints\n", - "psf.hint" )); - break; - } - } - - if ( count2 == 0 ) - { - psh1_hint_activate( hint ); - if ( count < table->max_hints ) - table->sort[count++] = hint; - else - FT_ERROR(( "%s.activate_mask: too many active hints\n", - "psf.hint" )); - } - } - } - - mask >>= 1; - } - table->num_hints = count; - - /* now, sort the hints; they are guaranteed to not overlap */ - /* so we can compare their "org_pos" field directly */ - { - FT_Int i1, i2; - PSH1_Hint hint1, hint2; - PSH1_Hint* sort = table->sort; - - - /* a simple bubble sort will do, since in 99% of cases, the hints */ - /* will be already sorted; and the sort will be linear */ - for ( i1 = 1; i1 < (FT_Int)count; i1++ ) - { - hint1 = sort[i1]; - - for ( i2 = i1 - 1; i2 >= 0; i2-- ) - { - hint2 = sort[i2]; - if ( hint2->org_pos < hint1->org_pos ) - break; - - sort[i2 + 1] = hint2; - sort[i2] = hint1; - } - } - } - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** HINTS GRID-FITTING AND OPTIMIZATION *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - -#ifdef DEBUG_HINTER - void - ps_simple_scale( PSH1_Hint_Table table, - FT_Fixed scale, - FT_Fixed delta, - FT_Int vertical ) - { - PSH1_Hint hint; - FT_UInt count; - - - for ( count = 0; count < table->num_hints; count++ ) - { - hint = table->sort[count]; - if ( psh1_hint_is_active( hint ) ) - { - hint->cur_pos = FT_MulFix( hint->org_pos, scale ) + delta; - hint->cur_len = FT_MulFix( hint->org_len, scale ); - - if ( ps1_debug_hint_func ) - ps1_debug_hint_func( hint, vertical ); - } - } - } -#endif - - - FT_LOCAL_DEF( FT_Error ) - psh1_hint_table_optimize( PSH1_Hint_Table table, - PSH_Globals globals, - FT_Outline* outline, - FT_Int vertical ) - { - PSH_Dimension dim = &globals->dimension[vertical]; - FT_Fixed scale = dim->scale_mult; - FT_Fixed delta = dim->scale_delta; - - FT_UNUSED( outline ); - - -#ifdef DEBUG_HINTER - if ( ps_debug_no_vert_hints && vertical ) - { - ps_simple_scale( table, scale, delta, vertical ); - return 0; - } - - if ( ps_debug_no_horz_hints && !vertical ) - { - ps_simple_scale( table, scale, delta, vertical ); - return 0; - } -#endif - - /* XXXX: for now, we only scale the hints to test all other aspects */ - /* of the PostScript hinter */ - { - PSH1_Hint hint; - FT_UInt count; - - - for ( count = 0; count < table->num_hints; count++ ) - { - hint = table->sort[count]; - if ( psh1_hint_is_active( hint ) ) - { -#if 1 - FT_Pos pos = FT_MulFix( hint->org_pos, scale ) + delta; - FT_Pos len = FT_MulFix( hint->org_len, scale ); - - FT_Pos fit_center; - FT_Pos fit_len; - - PSH_AlignmentRec align; - - - /* compute fitted width/height */ - fit_len = psh_dimension_snap_width( dim, hint->org_len ); - if ( fit_len < 64 ) - fit_len = 64; - else - fit_len = ( fit_len + 32 ) & -64; - - hint->cur_len = fit_len; - - /* check blue zones for horizontal stems */ - align.align = PSH_BLUE_ALIGN_NONE; - align.align_bot = align.align_top = 0; - if ( !vertical ) - { - psh_blues_snap_stem( &globals->blues, - hint->org_pos + hint->org_len, - hint->org_pos, - &align ); - } - - switch ( align.align ) - { - case PSH_BLUE_ALIGN_TOP: - /* the top of the stem is aligned against a blue zone */ - hint->cur_pos = align.align_top - fit_len; - break; - - case PSH_BLUE_ALIGN_BOT: - /* the bottom of the stem is aligned against a blue zone */ - hint->cur_pos = align.align_bot; - break; - - case PSH_BLUE_ALIGN_TOP | PSH_BLUE_ALIGN_BOT: - /* both edges of the stem are aligned against blue zones */ - hint->cur_pos = align.align_bot; - hint->cur_len = align.align_top - align.align_bot; - break; - - default: - /* normal processing */ - if ( ( fit_len / 64 ) & 1 ) - { - /* odd number of pixels */ - fit_center = ( ( pos + ( len >> 1 ) ) & -64 ) + 32; - } - else - { - /* even number of pixels */ - fit_center = ( pos + ( len >> 1 ) + 32 ) & -64; - } - - hint->cur_pos = fit_center - ( fit_len >> 1 ); - } - -# else - - hint->cur_pos = ( FT_MulFix( hint->org_pos, scale ) + delta + 32 ) - & -64; - hint->cur_len = FT_MulFix( hint->org_len, scale ); - -# endif - -#ifdef DEBUG_HINTER - if ( ps1_debug_hint_func ) - ps1_debug_hint_func( hint, vertical ); -#endif - } - } - } - - return 0; - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** POINTS INTERPOLATION ROUTINES *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - -#define PSH1_ZONE_MIN -3200000 -#define PSH1_ZONE_MAX +3200000 - -#define xxDEBUG_ZONES - - -#ifdef DEBUG_ZONES - -#include <stdio.h> - - static void - psh1_print_zone( PSH1_Zone zone ) - { - printf( "zone [scale,delta,min,max] = [%.3f,%.3f,%d,%d]\n", - zone->scale / 65536.0, - zone->delta / 64.0, - zone->min, - zone->max ); - } - -#else -#define psh1_print_zone( x ) do { } while ( 0 ) -#endif - - /* setup interpolation zones once the hints have been grid-fitted */ - /* by the optimizer */ - static void - psh1_hint_table_setup_zones( PSH1_Hint_Table table, - FT_Fixed scale, - FT_Fixed delta ) - { - FT_UInt count; - PSH1_Zone zone; - PSH1_Hint *sort, hint, hint2; - - - zone = table->zones; - - /* special case, no hints defined */ - if ( table->num_hints == 0 ) - { - zone->scale = scale; - zone->delta = delta; - zone->min = PSH1_ZONE_MIN; - zone->max = PSH1_ZONE_MAX; - - table->num_zones = 1; - table->zone = zone; - return; - } - - /* the first zone is before the first hint */ - /* x' = (x-x0)*s + x0' = x*s + ( x0' - x0*s ) */ - - sort = table->sort; - hint = sort[0]; - - zone->scale = scale; - zone->delta = hint->cur_pos - FT_MulFix( hint->org_pos, scale ); - zone->min = PSH1_ZONE_MIN; - zone->max = hint->org_pos; - - psh1_print_zone( zone ); - - zone++; - - for ( count = table->num_hints; count > 0; count-- ) - { - FT_Fixed scale2; - - - if ( hint->org_len > 0 ) - { - /* setup a zone for inner-stem interpolation */ - /* (x' - x0') = (x - x0)*(x1'-x0')/(x1-x0) */ - /* x' = x*s2 + x0' - x0*s2 */ - - scale2 = FT_DivFix( hint->cur_len, hint->org_len ); - zone->scale = scale2; - zone->min = hint->org_pos; - zone->max = hint->org_pos + hint->org_len; - zone->delta = hint->cur_pos - FT_MulFix( zone->min, scale2 ); - - psh1_print_zone( zone ); - - zone++; - } - - if ( count == 1 ) - break; - - sort++; - hint2 = sort[0]; - - /* setup zone for inter-stem interpolation */ - /* (x'-x1') = (x-x1)*(x2'-x1')/(x2-x1) */ - /* x' = x*s3 + x1' - x1*s3 */ - - scale2 = FT_DivFix( hint2->cur_pos - (hint->cur_pos + hint->cur_len), - hint2->org_pos - (hint->org_pos + hint->org_len) ); - zone->scale = scale2; - zone->min = hint->org_pos + hint->org_len; - zone->max = hint2->org_pos; - zone->delta = hint->cur_pos + hint->cur_len - - FT_MulFix( zone->min, scale2 ); - - psh1_print_zone( zone ); - - zone++; - - hint = hint2; - } - - /* the last zone */ - zone->scale = scale; - zone->min = hint->org_pos + hint->org_len; - zone->max = PSH1_ZONE_MAX; - zone->delta = hint->cur_pos + hint->cur_len - - FT_MulFix( zone->min, scale ); - - psh1_print_zone( zone ); - - zone++; - - table->num_zones = zone - table->zones; - table->zone = table->zones; - } - - - /* tune a single coordinate with the current interpolation zones */ - static FT_Pos - psh1_hint_table_tune_coord( PSH1_Hint_Table table, - FT_Int coord ) - { - PSH1_Zone zone; - - - zone = table->zone; - - if ( coord < zone->min ) - { - do - { - if ( zone == table->zones ) - break; - - zone--; - - } while ( coord < zone->min ); - table->zone = zone; - } - else if ( coord > zone->max ) - { - do - { - if ( zone == table->zones + table->num_zones - 1 ) - break; - - zone++; - - } while ( coord > zone->max ); - table->zone = zone; - } - - return FT_MulFix( coord, zone->scale ) + zone->delta; - } - - - /* tune a given outline with current interpolation zones. */ - /* The function only works in a single dimension. */ - static void - psh1_hint_table_tune_outline( PSH1_Hint_Table table, - FT_Outline* outline, - PSH_Globals globals, - FT_Int vertical ) - - { - FT_UInt count, first, last; - PS_Mask_Table hint_masks = table->hint_masks; - PS_Mask mask; - PSH_Dimension dim = &globals->dimension[vertical]; - FT_Fixed scale = dim->scale_mult; - FT_Fixed delta = dim->scale_delta; - - - if ( hint_masks && hint_masks->num_masks > 0 ) - { - first = 0; - mask = hint_masks->masks; - count = hint_masks->num_masks; - - for ( ; count > 0; count--, mask++ ) - { - last = mask->end_point; - - if ( last > first ) - { - FT_Vector* vec; - FT_Int count2; - - - psh1_hint_table_activate_mask( table, mask ); - psh1_hint_table_optimize( table, globals, outline, vertical ); - psh1_hint_table_setup_zones( table, scale, delta ); - last = mask->end_point; - - vec = outline->points + first; - count2 = last - first; - - for ( ; count2 > 0; count2--, vec++ ) - { - FT_Pos x, *px; - - - px = vertical ? &vec->x : &vec->y; - x = *px; - - *px = psh1_hint_table_tune_coord( table, (FT_Int)x ); - } - } - - first = last; - } - } - else /* no hints in this glyph, simply scale the outline */ - { - FT_Vector* vec; - - - vec = outline->points; - count = outline->n_points; - - if ( vertical ) - { - for ( ; count > 0; count--, vec++ ) - vec->x = FT_MulFix( vec->x, scale ) + delta; - } - else - { - for ( ; count > 0; count--, vec++ ) - vec->y = FT_MulFix( vec->y, scale ) + delta; - } - } - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** HIGH-LEVEL INTERFACE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_Error - ps1_hints_apply( PS_Hints ps_hints, - FT_Outline* outline, - PSH_Globals globals, - FT_Render_Mode hint_mode ) - { - PSH1_Hint_TableRec hints; - FT_Error error = 0; - FT_Int dimension; - - - FT_UNUSED( hint_mode ); - - for ( dimension = 1; dimension >= 0; dimension-- ) - { - PS_Dimension dim = &ps_hints->dimension[dimension]; - - - /* initialize hints table */ - FT_MEM_ZERO( &hints, sizeof ( hints ) ); - error = psh1_hint_table_init( &hints, - &dim->hints, - &dim->masks, - &dim->counters, - ps_hints->memory ); - if ( error ) - goto Exit; - - psh1_hint_table_tune_outline( &hints, - outline, - globals, - dimension ); - - psh1_hint_table_done( &hints, ps_hints->memory ); - } - - Exit: - return error; - } - - -/* END */ diff --git a/src/libs/freetype2/pshinter/pshalgo1.h b/src/libs/freetype2/pshinter/pshalgo1.h deleted file mode 100644 index 64d12dec18..0000000000 --- a/src/libs/freetype2/pshinter/pshalgo1.h +++ /dev/null @@ -1,110 +0,0 @@ -/***************************************************************************/ -/* */ -/* pshalgo1.h */ -/* */ -/* PostScript hinting algorithm 1 (specification). */ -/* */ -/* Copyright 2001 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. */ -/* */ -/***************************************************************************/ - - -#ifndef __PSHALGO1_H__ -#define __PSHALGO1_H__ - -#include "pshrec.h" - -FT_BEGIN_HEADER - - typedef struct PSH1_HintRec_* PSH1_Hint; - - typedef enum - { - PSH1_HINT_FLAG_GHOST = PS_HINT_FLAG_GHOST, - PSH1_HINT_FLAG_BOTTOM = PS_HINT_FLAG_BOTTOM, - PSH1_HINT_FLAG_ACTIVE = 4 - - } PSH1_Hint_Flags; - -#define psh1_hint_is_active( x ) \ - ( ( (x)->flags & PSH1_HINT_FLAG_ACTIVE ) != 0 ) -#define psh1_hint_is_ghost( x ) \ - ( ( (x)->flags & PSH1_HINT_FLAG_GHOST ) != 0 ) - -#define psh1_hint_activate( x ) (x)->flags |= PSH1_HINT_FLAG_ACTIVE -#define psh1_hint_deactivate( x ) (x)->flags &= ~PSH1_HINT_FLAG_ACTIVE - - typedef struct PSH1_HintRec_ - { - FT_Int org_pos; - FT_Int org_len; - FT_Pos cur_pos; - FT_Pos cur_len; - - FT_UInt flags; - - PSH1_Hint parent; - FT_Int order; - - } PSH1_HintRec; - - - /* this is an interpolation zone used for strong points; */ - /* weak points are interpolated according to their strong */ - /* neighbours */ - typedef struct PSH1_ZoneRec_ - { - FT_Fixed scale; - FT_Fixed delta; - FT_Pos min; - FT_Pos max; - - } PSH1_ZoneRec, *PSH1_Zone; - - - typedef struct PSH1_Hint_TableRec_ - { - FT_UInt max_hints; - FT_UInt num_hints; - PSH1_Hint hints; - PSH1_Hint* sort; - PSH1_Hint* sort_global; - FT_UInt num_zones; - PSH1_Zone zones; - PSH1_Zone zone; - PS_Mask_Table hint_masks; - PS_Mask_Table counter_masks; - - } PSH1_Hint_TableRec, *PSH1_Hint_Table; - - - extern FT_Error - ps1_hints_apply( PS_Hints ps_hints, - FT_Outline* outline, - PSH_Globals globals, - FT_Render_Mode hint_mode ); - - -#ifdef DEBUG_HINTER - extern PSH1_Hint_Table ps1_debug_hint_table; - - typedef void - (*PSH1_HintFunc)( PSH1_Hint hint, - FT_Bool vertical ); - - extern PSH1_HintFunc ps1_debug_hint_func; -#endif - -FT_END_HEADER - -#endif /* __PSHALGO1_H__ */ - - -/* END */ diff --git a/src/libs/freetype2/pshinter/pshalgo2.c b/src/libs/freetype2/pshinter/pshalgo2.c deleted file mode 100644 index e24897f6dc..0000000000 --- a/src/libs/freetype2/pshinter/pshalgo2.c +++ /dev/null @@ -1,1557 +0,0 @@ -/***************************************************************************/ -/* */ -/* pshalgo2.c */ -/* */ -/* PostScript hinting algorithm 2 (body). */ -/* */ -/* Copyright 2001, 2002 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. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_DEBUG_H -#include "pshalgo2.h" - -#undef FT_COMPONENT -#define FT_COMPONENT trace_pshalgo2 - -#ifdef DEBUG_HINTER - PSH2_Hint_Table ps2_debug_hint_table = 0; - PSH2_HintFunc ps2_debug_hint_func = 0; - PSH2_Glyph ps2_debug_glyph = 0; -#endif - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** BASIC HINTS RECORDINGS *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - /* return true iff two stem hints overlap */ - static FT_Int - psh2_hint_overlap( PSH2_Hint hint1, - PSH2_Hint hint2 ) - { - return ( hint1->org_pos + hint1->org_len >= hint2->org_pos && - hint2->org_pos + hint2->org_len >= hint1->org_pos ); - } - - - /* destroy hints table */ - static void - psh2_hint_table_done( PSH2_Hint_Table table, - FT_Memory memory ) - { - FT_FREE( table->zones ); - table->num_zones = 0; - table->zone = 0; - - FT_FREE( table->sort ); - FT_FREE( table->hints ); - table->num_hints = 0; - table->max_hints = 0; - table->sort_global = 0; - } - - - /* deactivate all hints in a table */ - static void - psh2_hint_table_deactivate( PSH2_Hint_Table table ) - { - FT_UInt count = table->max_hints; - PSH2_Hint hint = table->hints; - - - for ( ; count > 0; count--, hint++ ) - { - psh2_hint_deactivate( hint ); - hint->order = -1; - } - } - - - /* internal function used to record a new hint */ - static void - psh2_hint_table_record( PSH2_Hint_Table table, - FT_UInt idx ) - { - PSH2_Hint hint = table->hints + idx; - - - if ( idx >= table->max_hints ) - { - FT_ERROR(( "%s.activate: invalid hint index %d\n", idx )); - return; - } - - /* ignore active hints */ - if ( psh2_hint_is_active( hint ) ) - return; - - psh2_hint_activate( hint ); - - /* now scan the current active hint set in order to determine */ - /* if we are overlapping with another segment */ - { - PSH2_Hint* sorted = table->sort_global; - FT_UInt count = table->num_hints; - PSH2_Hint hint2; - - - hint->parent = 0; - for ( ; count > 0; count--, sorted++ ) - { - hint2 = sorted[0]; - - if ( psh2_hint_overlap( hint, hint2 ) ) - { - hint->parent = hint2; - break; - } - } - } - - if ( table->num_hints < table->max_hints ) - table->sort_global[table->num_hints++] = hint; - else - FT_ERROR(( "%s.activate: too many sorted hints! BUG!\n", - "ps.fitter" )); - } - - - static void - psh2_hint_table_record_mask( PSH2_Hint_Table table, - PS_Mask hint_mask ) - { - FT_Int mask = 0, val = 0; - FT_Byte* cursor = hint_mask->bytes; - FT_UInt idx, limit; - - - limit = hint_mask->num_bits; - - for ( idx = 0; idx < limit; idx++ ) - { - if ( mask == 0 ) - { - val = *cursor++; - mask = 0x80; - } - - if ( val & mask ) - psh2_hint_table_record( table, idx ); - - mask >>= 1; - } - } - - - /* create hints table */ - static FT_Error - psh2_hint_table_init( PSH2_Hint_Table table, - PS_Hint_Table hints, - PS_Mask_Table hint_masks, - PS_Mask_Table counter_masks, - FT_Memory memory ) - { - FT_UInt count = hints->num_hints; - FT_Error error; - - FT_UNUSED( counter_masks ); - - - /* allocate our tables */ - if ( FT_NEW_ARRAY( table->sort, 2 * count ) || - FT_NEW_ARRAY( table->hints, count ) || - FT_NEW_ARRAY( table->zones, 2 * count + 1 ) ) - goto Exit; - - table->max_hints = count; - table->sort_global = table->sort + count; - table->num_hints = 0; - table->num_zones = 0; - table->zone = 0; - - /* now, initialize the "hints" array */ - { - PSH2_Hint write = table->hints; - PS_Hint read = hints->hints; - - - for ( ; count > 0; count--, write++, read++ ) - { - write->org_pos = read->pos; - write->org_len = read->len; - write->flags = read->flags; - } - } - - /* we now need to determine the initial "parent" stems; first */ - /* activate the hints that are given by the initial hint masks */ - if ( hint_masks ) - { - FT_UInt Count = hint_masks->num_masks; - PS_Mask Mask = hint_masks->masks; - - - table->hint_masks = hint_masks; - - for ( ; Count > 0; Count--, Mask++ ) - psh2_hint_table_record_mask( table, Mask ); - } - - /* now, do a linear parse in case some hints were left alone */ - if ( table->num_hints != table->max_hints ) - { - FT_UInt Index, Count; - - - FT_ERROR(( "%s.init: missing/incorrect hint masks!\n" )); - Count = table->max_hints; - for ( Index = 0; Index < Count; Index++ ) - psh2_hint_table_record( table, Index ); - } - - Exit: - return error; - } - - - static void - psh2_hint_table_activate_mask( PSH2_Hint_Table table, - PS_Mask hint_mask ) - { - FT_Int mask = 0, val = 0; - FT_Byte* cursor = hint_mask->bytes; - FT_UInt idx, limit, count; - - - limit = hint_mask->num_bits; - count = 0; - - psh2_hint_table_deactivate( table ); - - for ( idx = 0; idx < limit; idx++ ) - { - if ( mask == 0 ) - { - val = *cursor++; - mask = 0x80; - } - - if ( val & mask ) - { - PSH2_Hint hint = &table->hints[idx]; - - - if ( !psh2_hint_is_active( hint ) ) - { - FT_UInt count2; - -#if 0 - PSH2_Hint* sort = table->sort; - PSH2_Hint hint2; - - for ( count2 = count; count2 > 0; count2--, sort++ ) - { - hint2 = sort[0]; - if ( psh2_hint_overlap( hint, hint2 ) ) - FT_ERROR(( "%s.activate_mask: found overlapping hints\n", - "psf.hint" )); - } -#else - count2 = 0; -#endif - - if ( count2 == 0 ) - { - psh2_hint_activate( hint ); - if ( count < table->max_hints ) - table->sort[count++] = hint; - else - FT_ERROR(( "%s.activate_mask: too many active hints\n", - "psf.hint" )); - } - } - } - - mask >>= 1; - } - table->num_hints = count; - - /* now, sort the hints; they are guaranteed to not overlap */ - /* so we can compare their "org_pos" field directly */ - { - FT_Int i1, i2; - PSH2_Hint hint1, hint2; - PSH2_Hint* sort = table->sort; - - - /* a simple bubble sort will do, since in 99% of cases, the hints */ - /* will be already sorted -- and the sort will be linear */ - for ( i1 = 1; i1 < (FT_Int)count; i1++ ) - { - hint1 = sort[i1]; - for ( i2 = i1 - 1; i2 >= 0; i2-- ) - { - hint2 = sort[i2]; - - if ( hint2->org_pos < hint1->org_pos ) - break; - - sort[i2 + 1] = hint2; - sort[i2] = hint1; - } - } - } - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** HINTS GRID-FITTING AND OPTIMIZATION *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - -#ifdef DEBUG_HINTER - static void - ps2_simple_scale( PSH2_Hint_Table table, - FT_Fixed scale, - FT_Fixed delta, - FT_Int dimension ) - { - PSH2_Hint hint; - FT_UInt count; - - - for ( count = 0; count < table->max_hints; count++ ) - { - hint = table->hints + count; - - hint->cur_pos = FT_MulFix( hint->org_pos, scale ) + delta; - hint->cur_len = FT_MulFix( hint->org_len, scale ); - - if ( ps2_debug_hint_func ) - ps2_debug_hint_func( hint, dimension ); - } - } -#endif - - - static void - psh2_hint_align( PSH2_Hint hint, - PSH_Globals globals, - FT_Int dimension ) - { - PSH_Dimension dim = &globals->dimension[dimension]; - FT_Fixed scale = dim->scale_mult; - FT_Fixed delta = dim->scale_delta; - - - if ( !psh2_hint_is_fitted(hint) ) - { - FT_Pos pos = FT_MulFix( hint->org_pos, scale ) + delta; - FT_Pos len = FT_MulFix( hint->org_len, scale ); - - FT_Pos fit_center; - FT_Pos fit_len; - - PSH_AlignmentRec align; - - - /* compute fitted width/height */ - fit_len = 0; - if ( hint->org_len ) - { - fit_len = psh_dimension_snap_width( dim, hint->org_len ); - if ( fit_len < 64 ) - fit_len = 64; - else - fit_len = ( fit_len + 32 ) & -64; - } - - hint->cur_len = fit_len; - - /* check blue zones for horizontal stems */ - align.align = PSH_BLUE_ALIGN_NONE; - align.align_bot = align.align_top = 0; - - if ( dimension == 1 ) - psh_blues_snap_stem( &globals->blues, - hint->org_pos + hint->org_len, - hint->org_pos, - &align ); - - switch ( align.align ) - { - case PSH_BLUE_ALIGN_TOP: - /* the top of the stem is aligned against a blue zone */ - hint->cur_pos = align.align_top - fit_len; - break; - - case PSH_BLUE_ALIGN_BOT: - /* the bottom of the stem is aligned against a blue zone */ - hint->cur_pos = align.align_bot; - break; - - case PSH_BLUE_ALIGN_TOP | PSH_BLUE_ALIGN_BOT: - /* both edges of the stem are aligned against blue zones */ - hint->cur_pos = align.align_bot; - hint->cur_len = align.align_top - align.align_bot; - break; - - default: - { - PSH2_Hint parent = hint->parent; - - - if ( parent ) - { - FT_Pos par_org_center, par_cur_center; - FT_Pos cur_org_center, cur_delta; - - - /* ensure that parent is already fitted */ - if ( !psh2_hint_is_fitted( parent ) ) - psh2_hint_align( parent, globals, dimension ); - - par_org_center = parent->org_pos + ( parent->org_len / 2); - par_cur_center = parent->cur_pos + ( parent->cur_len / 2); - cur_org_center = hint->org_pos + ( hint->org_len / 2); - - cur_delta = FT_MulFix( cur_org_center - par_org_center, scale ); -#if 0 - if ( cur_delta >= 0 ) - cur_delta = ( cur_delta + 16 ) & -64; - else - cur_delta = -( (-cur_delta + 16 ) & -64 ); -#endif - pos = par_cur_center + cur_delta - ( len >> 1 ); - } - - /* normal processing */ - if ( ( fit_len / 64 ) & 1 ) - { - /* odd number of pixels */ - fit_center = ( ( pos + ( len >> 1 ) ) & -64 ) + 32; - } - else - { - /* even number of pixels */ - fit_center = ( pos + ( len >> 1 ) + 32 ) & -64; - } - - hint->cur_pos = fit_center - ( fit_len >> 1 ); - } - } - - psh2_hint_set_fitted( hint ); - -#ifdef DEBUG_HINTER - if ( ps2_debug_hint_func ) - ps2_debug_hint_func( hint, dimension ); -#endif - } - } - - - static void - psh2_hint_table_align_hints( PSH2_Hint_Table table, - PSH_Globals globals, - FT_Int dimension ) - { - PSH2_Hint hint; - FT_UInt count; - -#ifdef DEBUG_HINTER - PSH_Dimension dim = &globals->dimension[dimension]; - FT_Fixed scale = dim->scale_mult; - FT_Fixed delta = dim->scale_delta; - - - if ( ps_debug_no_vert_hints && dimension == 0 ) - { - ps2_simple_scale( table, scale, delta, dimension ); - return; - } - - if ( ps_debug_no_horz_hints && dimension == 1 ) - { - ps2_simple_scale( table, scale, delta, dimension ); - return; - } -#endif - - hint = table->hints; - count = table->max_hints; - - for ( ; count > 0; count--, hint++ ) - psh2_hint_align( hint, globals, dimension ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** POINTS INTERPOLATION ROUTINES *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - -#define PSH2_ZONE_MIN -3200000 -#define PSH2_ZONE_MAX +3200000 - -#define xxDEBUG_ZONES - - -#ifdef DEBUG_ZONES - -#include <stdio.h> - - static void - psh2_print_zone( PSH2_Zone zone ) - { - printf( "zone [scale,delta,min,max] = [%.3f,%.3f,%d,%d]\n", - zone->scale/65536.0, - zone->delta/64.0, - zone->min, - zone->max ); - } - -#else - -#define psh2_print_zone( x ) do { } while ( 0 ) - -#endif - -#if 0 - /* setup interpolation zones once the hints have been grid-fitted */ - /* by the optimizer */ - static void - psh2_hint_table_setup_zones( PSH2_Hint_Table table, - FT_Fixed scale, - FT_Fixed delta ) - { - FT_UInt count; - PSH2_Zone zone; - PSH2_Hint *sort, hint, hint2; - - - zone = table->zones; - - /* special case, no hints defined */ - if ( table->num_hints == 0 ) - { - zone->scale = scale; - zone->delta = delta; - zone->min = PSH2_ZONE_MIN; - zone->max = PSH2_ZONE_MAX; - - table->num_zones = 1; - table->zone = zone; - return; - } - - /* the first zone is before the first hint */ - /* x' = (x-x0)*s + x0' = x*s + ( x0' - x0*s ) */ - sort = table->sort; - hint = sort[0]; - - zone->scale = scale; - zone->delta = hint->cur_pos - FT_MulFix( hint->org_pos, scale ); - zone->min = PSH2_ZONE_MIN; - zone->max = hint->org_pos; - - psh2_print_zone( zone ); - - zone++; - - for ( count = table->num_hints; count > 0; count-- ) - { - FT_Fixed scale2; - - - if ( hint->org_len > 0 ) - { - /* setup a zone for inner-stem interpolation */ - /* (x' - x0') = (x - x0)*(x1'-x0')/(x1-x0) */ - /* x' = x*s2 + x0' - x0*s2 */ - - scale2 = FT_DivFix( hint->cur_len, hint->org_len ); - zone->scale = scale2; - zone->min = hint->org_pos; - zone->max = hint->org_pos + hint->org_len; - zone->delta = hint->cur_pos - FT_MulFix( zone->min, scale2 ); - - psh2_print_zone( zone ); - - zone++; - } - - if ( count == 1 ) - break; - - sort++; - hint2 = sort[0]; - - /* setup zone for inter-stem interpolation */ - /* (x'-x1') = (x-x1)*(x2'-x1')/(x2-x1) */ - /* x' = x*s3 + x1' - x1*s3 */ - - scale2 = FT_DivFix( hint2->cur_pos - (hint->cur_pos + hint->cur_len), - hint2->org_pos - (hint->org_pos + hint->org_len) ); - zone->scale = scale2; - zone->min = hint->org_pos + hint->org_len; - zone->max = hint2->org_pos; - zone->delta = hint->cur_pos + hint->cur_len - - FT_MulFix( zone->min, scale2 ); - - psh2_print_zone( zone ); - - zone++; - - hint = hint2; - } - - /* the last zone */ - zone->scale = scale; - zone->min = hint->org_pos + hint->org_len; - zone->max = PSH2_ZONE_MAX; - zone->delta = hint->cur_pos + hint->cur_len - - FT_MulFix( zone->min, scale ); - - psh2_print_zone( zone ); - - zone++; - - table->num_zones = zone - table->zones; - table->zone = table->zones; - } -#endif - -#if 0 - /* tune a single coordinate with the current interpolation zones */ - static FT_Pos - psh2_hint_table_tune_coord( PSH2_Hint_Table table, - FT_Int coord ) - { - PSH2_Zone zone; - - - zone = table->zone; - - if ( coord < zone->min ) - { - do - { - if ( zone == table->zones ) - break; - - zone--; - - } while ( coord < zone->min ); - table->zone = zone; - } - else if ( coord > zone->max ) - { - do - { - if ( zone == table->zones + table->num_zones - 1 ) - break; - - zone++; - - } while ( coord > zone->max ); - table->zone = zone; - } - - return FT_MulFix( coord, zone->scale ) + zone->delta; - } -#endif - -#if 0 - /* tune a given outline with current interpolation zones */ - /* the function only works in a single dimension.. */ - static void - psh2_hint_table_tune_outline( PSH2_Hint_Table table, - FT_Outline* outline, - PSH_Globals globals, - FT_Int dimension ) - - { - FT_UInt count, first, last; - PS_Mask_Table hint_masks = table->hint_masks; - PS_Mask mask; - PSH_Dimension dim = &globals->dimension[dimension]; - FT_Fixed scale = dim->scale_mult; - FT_Fixed delta = dim->scale_delta; - - - if ( hint_masks && hint_masks->num_masks > 0 ) - { - first = 0; - mask = hint_masks->masks; - count = hint_masks->num_masks; - - for ( ; count > 0; count--, mask++ ) - { - last = mask->end_point; - - if ( last > first ) - { - FT_Vector* vec; - FT_Int count2; - - - psh2_hint_table_activate_mask( table, mask ); - psh2_hint_table_optimize( table, globals, outline, dimension ); - psh2_hint_table_setup_zones( table, scale, delta ); - last = mask->end_point; - - vec = outline->points + first; - count2 = last - first; - - for ( ; count2 > 0; count2--, vec++ ) - { - FT_Pos x, *px; - - - px = dimension ? &vec->y : &vec->x; - x = *px; - - *px = psh2_hint_table_tune_coord( table, (FT_Int)x ); - } - } - - first = last; - } - } - else /* no hints in this glyph, simply scale the outline */ - { - FT_Vector* vec; - - - vec = outline->points; - count = outline->n_points; - - if ( dimension == 0 ) - { - for ( ; count > 0; count--, vec++ ) - vec->x = FT_MulFix( vec->x, scale ) + delta; - } - else - { - for ( ; count > 0; count--, vec++ ) - vec->y = FT_MulFix( vec->y, scale ) + delta; - } - } - } -#endif - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** HINTER GLYPH MANAGEMENT *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static int - psh2_point_is_extremum( PSH2_Point point ) - { - PSH2_Point before = point; - PSH2_Point after = point; - FT_Pos d_before; - FT_Pos d_after; - - - do - { - before = before->prev; - if ( before == point ) - return 0; - - d_before = before->org_u - point->org_u; - - } while ( d_before == 0 ); - - do - { - after = after->next; - if ( after == point ) - return 0; - - d_after = after->org_u - point->org_u; - - } while ( d_after == 0 ); - - return ( ( d_before > 0 && d_after > 0 ) || - ( d_before < 0 && d_after < 0 ) ); - } - - - static void - psh2_glyph_done( PSH2_Glyph glyph ) - { - FT_Memory memory = glyph->memory; - - - psh2_hint_table_done( &glyph->hint_tables[1], memory ); - psh2_hint_table_done( &glyph->hint_tables[0], memory ); - - FT_FREE( glyph->points ); - FT_FREE( glyph->contours ); - - glyph->num_points = 0; - glyph->num_contours = 0; - - glyph->memory = 0; - } - - - static int - psh2_compute_dir( FT_Pos dx, - FT_Pos dy ) - { - FT_Pos ax, ay; - int result = PSH2_DIR_NONE; - - - ax = ( dx >= 0 ) ? dx : -dx; - ay = ( dy >= 0 ) ? dy : -dy; - - if ( ay * 12 < ax ) - { - /* |dy| <<< |dx| means a near-horizontal segment */ - result = ( dx >= 0 ) ? PSH2_DIR_RIGHT : PSH2_DIR_LEFT; - } - else if ( ax * 12 < ay ) - { - /* |dx| <<< |dy| means a near-vertical segment */ - result = ( dy >= 0 ) ? PSH2_DIR_UP : PSH2_DIR_DOWN; - } - - return result; - } - - - static FT_Error - psh2_glyph_init( PSH2_Glyph glyph, - FT_Outline* outline, - PS_Hints ps_hints, - PSH_Globals globals ) - { - FT_Error error; - FT_Memory memory; - - - /* clear all fields */ - FT_MEM_ZERO( glyph, sizeof ( *glyph ) ); - - memory = globals->memory; - - /* allocate and setup points + contours arrays */ - if ( FT_NEW_ARRAY( glyph->points, outline->n_points ) || - FT_NEW_ARRAY( glyph->contours, outline->n_contours ) ) - goto Exit; - - glyph->num_points = outline->n_points; - glyph->num_contours = outline->n_contours; - - { - FT_UInt first = 0, next, n; - PSH2_Point points = glyph->points; - PSH2_Contour contour = glyph->contours; - - - for ( n = 0; n < glyph->num_contours; n++ ) - { - FT_Int count; - PSH2_Point point; - - - next = outline->contours[n] + 1; - count = next - first; - - contour->start = points + first; - contour->count = (FT_UInt)count; - - if ( count > 0 ) - { - point = points + first; - - point->prev = points + next - 1; - point->contour = contour; - - for ( ; count > 1; count-- ) - { - point[0].next = point + 1; - point[1].prev = point; - point++; - point->contour = contour; - } - point->next = points + first; - } - - contour++; - first = next; - } - } - - { - PSH2_Point points = glyph->points; - PSH2_Point point = points; - FT_Vector* vec = outline->points; - FT_UInt n; - - - for ( n = 0; n < glyph->num_points; n++, point++ ) - { - FT_Int n_prev = point->prev - points; - FT_Int n_next = point->next - points; - FT_Pos dxi, dyi, dxo, dyo; - - - if ( !( outline->tags[n] & FT_CURVE_TAG_ON ) ) - point->flags = PSH2_POINT_OFF; - - dxi = vec[n].x - vec[n_prev].x; - dyi = vec[n].y - vec[n_prev].y; - - point->dir_in = (FT_Char)psh2_compute_dir( dxi, dyi ); - - dxo = vec[n_next].x - vec[n].x; - dyo = vec[n_next].y - vec[n].y; - - point->dir_out = (FT_Char)psh2_compute_dir( dxo, dyo ); - - /* detect smooth points */ - if ( point->flags & PSH2_POINT_OFF ) - point->flags |= PSH2_POINT_SMOOTH; - else if ( point->dir_in != PSH2_DIR_NONE || - point->dir_out != PSH2_DIR_NONE ) - { - if ( point->dir_in == point->dir_out ) - point->flags |= PSH2_POINT_SMOOTH; - } - else - { - FT_Angle angle_in, angle_out, diff; - - - angle_in = FT_Atan2( dxi, dyi ); - angle_out = FT_Atan2( dxo, dyo ); - - diff = angle_in - angle_out; - if ( diff < 0 ) - diff = -diff; - - if ( diff > FT_ANGLE_PI ) - diff = FT_ANGLE_2PI - diff; - - if ( diff < FT_ANGLE_PI / 16 ) - point->flags |= PSH2_POINT_SMOOTH; - } - } - } - - glyph->memory = memory; - glyph->outline = outline; - glyph->globals = globals; - - /* now deal with hints tables */ - error = psh2_hint_table_init( &glyph->hint_tables [0], - &ps_hints->dimension[0].hints, - &ps_hints->dimension[0].masks, - &ps_hints->dimension[0].counters, - memory ); - if ( error ) - goto Exit; - - error = psh2_hint_table_init( &glyph->hint_tables [1], - &ps_hints->dimension[1].hints, - &ps_hints->dimension[1].masks, - &ps_hints->dimension[1].counters, - memory ); - if ( error ) - goto Exit; - - Exit: - return error; - } - - - /* load outline point coordinates into hinter glyph */ - static void - psh2_glyph_load_points( PSH2_Glyph glyph, - FT_Int dimension ) - { - FT_Vector* vec = glyph->outline->points; - PSH2_Point point = glyph->points; - FT_UInt count = glyph->num_points; - - - for ( ; count > 0; count--, point++, vec++ ) - { - point->flags &= PSH2_POINT_OFF | PSH2_POINT_SMOOTH; - point->hint = 0; - if ( dimension == 0 ) - point->org_u = vec->x; - else - point->org_u = vec->y; - -#ifdef DEBUG_HINTER - point->org_x = vec->x; - point->org_y = vec->y; -#endif - } - } - - - /* save hinted point coordinates back to outline */ - static void - psh2_glyph_save_points( PSH2_Glyph glyph, - FT_Int dimension ) - { - FT_UInt n; - PSH2_Point point = glyph->points; - FT_Vector* vec = glyph->outline->points; - char* tags = glyph->outline->tags; - - - for ( n = 0; n < glyph->num_points; n++ ) - { - if ( dimension == 0 ) - vec[n].x = point->cur_u; - else - vec[n].y = point->cur_u; - - if ( psh2_point_is_strong( point ) ) - tags[n] |= (char)( ( dimension == 0 ) ? 32 : 64 ); - -#ifdef DEBUG_HINTER - if ( dimension == 0 ) - { - point->cur_x = point->cur_u; - point->flags_x = point->flags; - } - else - { - point->cur_y = point->cur_u; - point->flags_y = point->flags; - } -#endif - point++; - } - } - - -#define PSH2_STRONG_THRESHOLD 10 - - - static void - psh2_hint_table_find_strong_point( PSH2_Hint_Table table, - PSH2_Point point, - FT_Int major_dir ) - { - PSH2_Hint* sort = table->sort; - FT_UInt num_hints = table->num_hints; - - - for ( ; num_hints > 0; num_hints--, sort++ ) - { - PSH2_Hint hint = sort[0]; - - - if ( ABS( point->dir_in ) == major_dir || - ABS( point->dir_out ) == major_dir ) - { - FT_Pos d; - - - d = point->org_u - hint->org_pos; - if ( ABS( d ) < PSH2_STRONG_THRESHOLD ) - { - Is_Strong: - psh2_point_set_strong( point ); - point->hint = hint; - break; - } - - d -= hint->org_len; - if ( ABS( d ) < PSH2_STRONG_THRESHOLD ) - goto Is_Strong; - } - -#if 1 - if ( point->org_u >= hint->org_pos && - point->org_u <= hint->org_pos + hint->org_len && - psh2_point_is_extremum( point ) ) - { - /* attach to hint, but don't mark as strong */ - point->hint = hint; - break; - } -#endif - } - } - - - /* find strong points in a glyph */ - static void - psh2_glyph_find_strong_points( PSH2_Glyph glyph, - FT_Int dimension ) - { - /* a point is strong if it is located on a stem */ - /* edge and has an "in" or "out" tangent to the hint's direction */ - { - PSH2_Hint_Table table = &glyph->hint_tables[dimension]; - PS_Mask mask = table->hint_masks->masks; - FT_UInt num_masks = table->hint_masks->num_masks; - FT_UInt first = 0; - FT_Int major_dir = dimension == 0 ? PSH2_DIR_UP : PSH2_DIR_RIGHT; - - - /* process secondary hints to "selected" points */ - if ( num_masks > 1 && glyph->num_points > 0 ) - { - first = mask->end_point; - mask++; - for ( ; num_masks > 1; num_masks--, mask++ ) - { - FT_UInt next; - FT_Int count; - - - next = mask->end_point; - count = next - first; - if ( count > 0 ) - { - PSH2_Point point = glyph->points + first; - - - psh2_hint_table_activate_mask( table, mask ); - - for ( ; count > 0; count--, point++ ) - psh2_hint_table_find_strong_point( table, point, major_dir ); - } - first = next; - } - } - - /* process primary hints for all points */ - if ( num_masks == 1 ) - { - FT_UInt count = glyph->num_points; - PSH2_Point point = glyph->points; - - - psh2_hint_table_activate_mask( table, table->hint_masks->masks ); - for ( ; count > 0; count--, point++ ) - { - if ( !psh2_point_is_strong( point ) ) - psh2_hint_table_find_strong_point( table, point, major_dir ); - } - } - - /* now, certain points may have been attached to hint and */ - /* not marked as strong; update their flags then */ - { - FT_UInt count = glyph->num_points; - PSH2_Point point = glyph->points; - - - for ( ; count > 0; count--, point++ ) - if ( point->hint && !psh2_point_is_strong( point ) ) - psh2_point_set_strong( point ); - } - } - } - - - /* interpolate strong points with the help of hinted coordinates */ - static void - psh2_glyph_interpolate_strong_points( PSH2_Glyph glyph, - FT_Int dimension ) - { - PSH_Dimension dim = &glyph->globals->dimension[dimension]; - FT_Fixed scale = dim->scale_mult; - - - { - FT_UInt count = glyph->num_points; - PSH2_Point point = glyph->points; - - - for ( ; count > 0; count--, point++ ) - { - PSH2_Hint hint = point->hint; - - - if ( hint ) - { - FT_Pos delta; - - - delta = point->org_u - hint->org_pos; - - if ( delta <= 0 ) - point->cur_u = hint->cur_pos + FT_MulFix( delta, scale ); - - else if ( delta >= hint->org_len ) - point->cur_u = hint->cur_pos + hint->cur_len + - FT_MulFix( delta - hint->org_len, scale ); - - else if ( hint->org_len > 0 ) - point->cur_u = hint->cur_pos + - FT_MulDiv( delta, hint->cur_len, hint->org_len ); - else - point->cur_u = hint->cur_pos; - - psh2_point_set_fitted( point ); - } - } - } - } - - - static void - psh2_glyph_interpolate_normal_points( PSH2_Glyph glyph, - FT_Int dimension ) - { -#if 1 - PSH_Dimension dim = &glyph->globals->dimension[dimension]; - FT_Fixed scale = dim->scale_mult; - - - /* first technique: a point is strong if it is a local extrema */ - { - FT_UInt count = glyph->num_points; - PSH2_Point point = glyph->points; - - - for ( ; count > 0; count--, point++ ) - { - if ( psh2_point_is_strong( point ) ) - continue; - - /* sometimes, some local extremas are smooth points */ - if ( psh2_point_is_smooth( point ) ) - { - if ( point->dir_in == PSH2_DIR_NONE || - point->dir_in != point->dir_out ) - continue; - - if ( !psh2_point_is_extremum( point ) ) - continue; - - point->flags &= ~PSH2_POINT_SMOOTH; - } - - /* find best enclosing point coordinates */ - { - PSH2_Point before = 0; - PSH2_Point after = 0; - - FT_Pos diff_before = -32000; - FT_Pos diff_after = 32000; - FT_Pos u = point->org_u; - - FT_Int count2 = glyph->num_points; - PSH2_Point cur = glyph->points; - - - for ( ; count2 > 0; count2--, cur++ ) - { - if ( psh2_point_is_strong( cur ) ) - { - FT_Pos diff = cur->org_u - u;; - - - if ( diff <= 0 ) - { - if ( diff > diff_before ) - { - diff_before = diff; - before = cur; - } - } - else if ( diff >= 0 ) - { - if ( diff < diff_after ) - { - diff_after = diff; - after = cur; - } - } - } - } - - if ( !before ) - { - if ( !after ) - continue; - - /* we are before the first strong point coordinate; */ - /* simply translate the point */ - point->cur_u = after->cur_u + - FT_MulFix( point->org_u - after->org_u, scale ); - } - else if ( !after ) - { - /* we are after the last strong point coordinate; */ - /* simply translate the point */ - point->cur_u = before->cur_u + - FT_MulFix( point->org_u - before->org_u, scale ); - } - else - { - if ( diff_before == 0 ) - point->cur_u = before->cur_u; - - else if ( diff_after == 0 ) - point->cur_u = after->cur_u; - - else - point->cur_u = before->cur_u + - FT_MulDiv( u - before->org_u, - after->cur_u - before->cur_u, - after->org_u - before->org_u ); - } - - psh2_point_set_fitted( point ); - } - } - } -#endif - } - - - /* interpolate other points */ - static void - psh2_glyph_interpolate_other_points( PSH2_Glyph glyph, - FT_Int dimension ) - { - PSH_Dimension dim = &glyph->globals->dimension[dimension]; - FT_Fixed scale = dim->scale_mult; - FT_Fixed delta = dim->scale_delta; - PSH2_Contour contour = glyph->contours; - FT_UInt num_contours = glyph->num_contours; - - - for ( ; num_contours > 0; num_contours--, contour++ ) - { - PSH2_Point start = contour->start; - PSH2_Point first, next, point; - FT_UInt fit_count; - - - /* count the number of strong points in this contour */ - next = start + contour->count; - fit_count = 0; - first = 0; - - for ( point = start; point < next; point++ ) - if ( psh2_point_is_fitted( point ) ) - { - if ( !first ) - first = point; - - fit_count++; - } - - /* if there are less than 2 fitted points in the contour, we */ - /* simply scale and eventually translate the contour points */ - if ( fit_count < 2 ) - { - if ( fit_count == 1 ) - delta = first->cur_u - FT_MulFix( first->org_u, scale ); - - for ( point = start; point < next; point++ ) - if ( point != first ) - point->cur_u = FT_MulFix( point->org_u, scale ) + delta; - - goto Next_Contour; - } - - /* there are more than 2 strong points in this contour; we */ - /* need to interpolate weak points between them */ - start = first; - do - { - point = first; - - /* skip consecutive fitted points */ - for (;;) - { - next = first->next; - if ( next == start ) - goto Next_Contour; - - if ( !psh2_point_is_fitted( next ) ) - break; - - first = next; - } - - /* find next fitted point after unfitted one */ - for (;;) - { - next = next->next; - if ( psh2_point_is_fitted( next ) ) - break; - } - - /* now interpolate between them */ - { - FT_Pos org_a, org_ab, cur_a, cur_ab; - FT_Pos org_c, org_ac, cur_c; - FT_Fixed scale_ab; - - - if ( first->org_u <= next->org_u ) - { - org_a = first->org_u; - cur_a = first->cur_u; - org_ab = next->org_u - org_a; - cur_ab = next->cur_u - cur_a; - } - else - { - org_a = next->org_u; - cur_a = next->cur_u; - org_ab = first->org_u - org_a; - cur_ab = first->cur_u - cur_a; - } - - scale_ab = 0x10000L; - if ( org_ab > 0 ) - scale_ab = FT_DivFix( cur_ab, org_ab ); - - point = first->next; - do - { - org_c = point->org_u; - org_ac = org_c - org_a; - - if ( org_ac <= 0 ) - { - /* on the left of the interpolation zone */ - cur_c = cur_a + FT_MulFix( org_ac, scale ); - } - else if ( org_ac >= org_ab ) - { - /* on the right on the interpolation zone */ - cur_c = cur_a + cur_ab + FT_MulFix( org_ac - org_ab, scale ); - } - else - { - /* within the interpolation zone */ - cur_c = cur_a + FT_MulFix( org_ac, scale_ab ); - } - - point->cur_u = cur_c; - - point = point->next; - - } while ( point != next ); - } - - /* keep going until all points in the contours have been processed */ - first = next; - - } while ( first != start ); - - Next_Contour: - ; - } - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** HIGH-LEVEL INTERFACE *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_Error - ps2_hints_apply( PS_Hints ps_hints, - FT_Outline* outline, - PSH_Globals globals, - FT_Render_Mode hint_mode ) - { - PSH2_GlyphRec glyphrec; - PSH2_Glyph glyph = &glyphrec; - FT_Error error; -#ifdef DEBUG_HINTER - FT_Memory memory; -#endif - FT_Int dimension; - - FT_UNUSED( hint_mode ); - -#ifdef DEBUG_HINTER - memory = globals->memory; - - if ( ps2_debug_glyph ) - { - psh2_glyph_done( ps2_debug_glyph ); - FT_FREE( ps2_debug_glyph ); - } - - if ( FT_NEW( glyph ) ) - return error; - - ps2_debug_glyph = glyph; -#endif - - error = psh2_glyph_init( glyph, outline, ps_hints, globals ); - if ( error ) - goto Exit; - - for ( dimension = 0; dimension < 2; dimension++ ) - { - /* load outline coordinates into glyph */ - psh2_glyph_load_points( glyph, dimension ); - - /* compute aligned stem/hints positions */ - psh2_hint_table_align_hints( &glyph->hint_tables[dimension], - glyph->globals, - dimension ); - - /* find strong points, align them, then interpolate others */ - psh2_glyph_find_strong_points( glyph, dimension ); - psh2_glyph_interpolate_strong_points( glyph, dimension ); - psh2_glyph_interpolate_normal_points( glyph, dimension ); - psh2_glyph_interpolate_other_points( glyph, dimension ); - - /* save hinted coordinates back to outline */ - psh2_glyph_save_points( glyph, dimension ); - } - - Exit: -#ifndef DEBUG_HINTER - psh2_glyph_done( glyph ); -#endif - return error; - } - - -/* END */ diff --git a/src/libs/freetype2/pshinter/pshalgo2.h b/src/libs/freetype2/pshinter/pshalgo2.h deleted file mode 100644 index 12b5a67cbd..0000000000 --- a/src/libs/freetype2/pshinter/pshalgo2.h +++ /dev/null @@ -1,203 +0,0 @@ -/***************************************************************************/ -/* */ -/* pshalgo2.h */ -/* */ -/* PostScript hinting algorithm 2 (specification). */ -/* */ -/* Copyright 2001 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. */ -/* */ -/***************************************************************************/ - - -#ifndef __PSHALGO2_H__ -#define __PSHALGO2_H__ - - -#include "pshrec.h" -#include "pshglob.h" -#include FT_TRIGONOMETRY_H - - -FT_BEGIN_HEADER - - - typedef struct PSH2_HintRec_* PSH2_Hint; - - typedef enum - { - PSH2_HINT_GHOST = PS_HINT_FLAG_GHOST, - PSH2_HINT_BOTTOM = PS_HINT_FLAG_BOTTOM, - PSH2_HINT_ACTIVE = 4, - PSH2_HINT_FITTED = 8 - - } PSH2_Hint_Flags; - - -#define psh2_hint_is_active( x ) ( ( (x)->flags & PSH2_HINT_ACTIVE ) != 0 ) -#define psh2_hint_is_ghost( x ) ( ( (x)->flags & PSH2_HINT_GHOST ) != 0 ) -#define psh2_hint_is_fitted( x ) ( ( (x)->flags & PSH2_HINT_FITTED ) != 0 ) - -#define psh2_hint_activate( x ) (x)->flags |= PSH2_HINT_ACTIVE -#define psh2_hint_deactivate( x ) (x)->flags &= ~PSH2_HINT_ACTIVE -#define psh2_hint_set_fitted( x ) (x)->flags |= PSH2_HINT_FITTED - - - typedef struct PSH2_HintRec_ - { - FT_Int org_pos; - FT_Int org_len; - FT_Pos cur_pos; - FT_Pos cur_len; - FT_UInt flags; - PSH2_Hint parent; - FT_Int order; - - } PSH2_HintRec; - - - /* this is an interpolation zone used for strong points; */ - /* weak points are interpolated according to their strong */ - /* neighbours */ - typedef struct PSH2_ZoneRec_ - { - FT_Fixed scale; - FT_Fixed delta; - FT_Pos min; - FT_Pos max; - - } PSH2_ZoneRec, *PSH2_Zone; - - - typedef struct PSH2_Hint_TableRec_ - { - FT_UInt max_hints; - FT_UInt num_hints; - PSH2_Hint hints; - PSH2_Hint* sort; - PSH2_Hint* sort_global; - FT_UInt num_zones; - PSH2_Zone zones; - PSH2_Zone zone; - PS_Mask_Table hint_masks; - PS_Mask_Table counter_masks; - - } PSH2_Hint_TableRec, *PSH2_Hint_Table; - - - typedef struct PSH2_PointRec_* PSH2_Point; - typedef struct PSH2_ContourRec_* PSH2_Contour; - - enum - { - PSH2_DIR_NONE = 4, - PSH2_DIR_UP = 1, - PSH2_DIR_DOWN = -1, - PSH2_DIR_LEFT = -2, - PSH2_DIR_RIGHT = 2 - }; - - enum - { - PSH2_POINT_OFF = 1, /* point is off the curve */ - PSH2_POINT_STRONG = 2, /* point is strong */ - PSH2_POINT_SMOOTH = 4, /* point is smooth */ - PSH2_POINT_FITTED = 8 /* point is already fitted */ - }; - - - typedef struct PSH2_PointRec_ - { - PSH2_Point prev; - PSH2_Point next; - PSH2_Contour contour; - FT_UInt flags; - FT_Char dir_in; - FT_Char dir_out; - FT_Angle angle_in; - FT_Angle angle_out; - PSH2_Hint hint; - FT_Pos org_u; - FT_Pos cur_u; -#ifdef DEBUG_HINTER - FT_Pos org_x; - FT_Pos cur_x; - FT_Pos org_y; - FT_Pos cur_y; - FT_UInt flags_x; - FT_UInt flags_y; -#endif - - } PSH2_PointRec; - - -#define psh2_point_is_strong( p ) ( (p)->flags & PSH2_POINT_STRONG ) -#define psh2_point_is_fitted( p ) ( (p)->flags & PSH2_POINT_FITTED ) -#define psh2_point_is_smooth( p ) ( (p)->flags & PSH2_POINT_SMOOTH ) - -#define psh2_point_set_strong( p ) (p)->flags |= PSH2_POINT_STRONG -#define psh2_point_set_fitted( p ) (p)->flags |= PSH2_POINT_FITTED -#define psh2_point_set_smooth( p ) (p)->flags |= PSH2_POINT_SMOOTH - - - typedef struct PSH2_ContourRec_ - { - PSH2_Point start; - FT_UInt count; - - } PSH2_ContourRec; - - - typedef struct PSH2_GlyphRec_ - { - FT_UInt num_points; - FT_UInt num_contours; - - PSH2_Point points; - PSH2_Contour contours; - - FT_Memory memory; - FT_Outline* outline; - PSH_Globals globals; - PSH2_Hint_TableRec hint_tables[2]; - - FT_Bool vertical; - FT_Int major_dir; - FT_Int minor_dir; - - } PSH2_GlyphRec, *PSH2_Glyph; - - -#ifdef DEBUG_HINTER - extern PSH2_Hint_Table ps2_debug_hint_table; - - typedef void - (*PSH2_HintFunc)( PSH2_Hint hint, - FT_Bool vertical ); - - extern PSH2_HintFunc ps2_debug_hint_func; - - extern PSH2_Glyph ps2_debug_glyph; -#endif - - - extern FT_Error - ps2_hints_apply( PS_Hints ps_hints, - FT_Outline* outline, - PSH_Globals globals, - FT_Render_Mode hint_mode ); - - -FT_END_HEADER - - -#endif /* __PSHALGO2_H__ */ - - -/* END */ diff --git a/src/libs/freetype2/pshinter/pshalgo3.h b/src/libs/freetype2/pshinter/pshalgo3.h deleted file mode 100644 index 70e35fe361..0000000000 --- a/src/libs/freetype2/pshinter/pshalgo3.h +++ /dev/null @@ -1,255 +0,0 @@ -/***************************************************************************/ -/* */ -/* pshalgo3.h */ -/* */ -/* PostScript hinting algorithm 3 (specification). */ -/* */ -/* Copyright 2001, 2002 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. */ -/* */ -/***************************************************************************/ - - -#ifndef __PSHALGO3_H__ -#define __PSHALGO3_H__ - - -#include "pshrec.h" -#include "pshglob.h" -#include FT_TRIGONOMETRY_H - - -FT_BEGIN_HEADER - - - /* handle to Hint structure */ - typedef struct PSH3_HintRec_* PSH3_Hint; - - /* hint bit-flags */ - typedef enum - { - PSH3_HINT_GHOST = PS_HINT_FLAG_GHOST, - PSH3_HINT_BOTTOM = PS_HINT_FLAG_BOTTOM, - PSH3_HINT_ACTIVE = 4, - PSH3_HINT_FITTED = 8 - - } PSH3_Hint_Flags; - - -#define psh3_hint_is_active( x ) ( ( (x)->flags & PSH3_HINT_ACTIVE ) != 0 ) -#define psh3_hint_is_ghost( x ) ( ( (x)->flags & PSH3_HINT_GHOST ) != 0 ) -#define psh3_hint_is_fitted( x ) ( ( (x)->flags & PSH3_HINT_FITTED ) != 0 ) - -#define psh3_hint_activate( x ) (x)->flags |= PSH3_HINT_ACTIVE -#define psh3_hint_deactivate( x ) (x)->flags &= ~PSH3_HINT_ACTIVE -#define psh3_hint_set_fitted( x ) (x)->flags |= PSH3_HINT_FITTED - - /* hint structure */ - typedef struct PSH3_HintRec_ - { - FT_Int org_pos; - FT_Int org_len; - FT_Pos cur_pos; - FT_Pos cur_len; - FT_UInt flags; - PSH3_Hint parent; - FT_Int order; - - } PSH3_HintRec; - - - /* this is an interpolation zone used for strong points; */ - /* weak points are interpolated according to their strong */ - /* neighbours */ - typedef struct PSH3_ZoneRec_ - { - FT_Fixed scale; - FT_Fixed delta; - FT_Pos min; - FT_Pos max; - - } PSH3_ZoneRec, *PSH3_Zone; - - - typedef struct PSH3_Hint_TableRec_ - { - FT_UInt max_hints; - FT_UInt num_hints; - PSH3_Hint hints; - PSH3_Hint* sort; - PSH3_Hint* sort_global; - FT_UInt num_zones; - PSH3_ZoneRec* zones; - PSH3_Zone zone; - PS_Mask_Table hint_masks; - PS_Mask_Table counter_masks; - - } PSH3_Hint_TableRec, *PSH3_Hint_Table; - - - typedef struct PSH3_PointRec_* PSH3_Point; - typedef struct PSH3_ContourRec_* PSH3_Contour; - - enum - { - PSH3_DIR_NONE = 4, - PSH3_DIR_UP = -1, - PSH3_DIR_DOWN = 1, - PSH3_DIR_LEFT = -2, - PSH3_DIR_RIGHT = 2 - }; - -#define PSH3_DIR_HORIZONTAL 2 -#define PSH3_DIR_VERTICAL 1 - -#define PSH3_DIR_COMPARE( d1, d2 ) ( (d1) == (d2) || (d1) == -(d2) ) -#define PSH3_DIR_IS_HORIZONTAL( d ) PSH3_DIR_COMPARE( d, PSH3_DIR_HORIZONTAL ) -#define PSH3_DIR_IS_VERTICAL( d ) PSH3_DIR_COMPARE( d, PSH3_DIR_VERTICAL ) - - - /* the following bit-flags are computed once by the glyph */ - /* analyzer, for both dimensions */ - enum - { - PSH3_POINT_OFF = 1, /* point is off the curve */ - PSH3_POINT_SMOOTH = 2, /* point is smooth */ - PSH3_POINT_INFLEX = 4 /* point is inflection */ - }; - -#define psh3_point_is_smooth( p ) ( (p)->flags & PSH3_POINT_SMOOTH ) -#define psh3_point_is_off( p ) ( (p)->flags & PSH3_POINT_OFF ) -#define psh3_point_is_inflex( p ) ( (p)->flags & PSH3_POINT_INFLEX ) - -#define psh3_point_set_smooth( p ) (p)->flags |= PSH3_POINT_SMOOTH -#define psh3_point_set_off( p ) (p)->flags |= PSH3_POINT_OFF -#define psh3_point_set_inflex( p ) (p)->flags |= PSH3_POINT_INFLEX - - /* the following bit-flags are re-computed for each dimension */ - enum - { - PSH3_POINT_STRONG = 16, /* point is strong */ - PSH3_POINT_FITTED = 32, /* point is already fitted */ - PSH3_POINT_EXTREMUM = 64, /* point is local extremum */ - PSH3_POINT_POSITIVE = 128, /* extremum has positive contour flow */ - PSH3_POINT_NEGATIVE = 256, /* extremum has negative contour flow */ - PSH3_POINT_EDGE_MIN = 512, /* point is aligned to left/bottom stem edge */ - PSH3_POINT_EDGE_MAX = 1024 /* point is aligned to top/right stem edge */ - }; - -#define psh3_point_is_strong( p ) ( (p)->flags2 & PSH3_POINT_STRONG ) -#define psh3_point_is_fitted( p ) ( (p)->flags2 & PSH3_POINT_FITTED ) -#define psh3_point_is_extremum( p ) ( (p)->flags2 & PSH3_POINT_EXTREMUM ) -#define psh3_point_is_positive( p ) ( (p)->flags2 & PSH3_POINT_POSITIVE ) -#define psh3_point_is_negative( p ) ( (p)->flags2 & PSH3_POINT_NEGATIVE ) -#define psh3_point_is_edge_min( p ) ( (p)->flags2 & PSH3_POINT_EDGE_MIN ) -#define psh3_point_is_edge_max( p ) ( (p)->flags2 & PSH3_POINT_EDGE_MAX ) - -#define psh3_point_set_strong( p ) (p)->flags2 |= PSH3_POINT_STRONG -#define psh3_point_set_fitted( p ) (p)->flags2 |= PSH3_POINT_FITTED -#define psh3_point_set_extremum( p ) (p)->flags2 |= PSH3_POINT_EXTREMUM -#define psh3_point_set_positive( p ) (p)->flags2 |= PSH3_POINT_POSITIVE -#define psh3_point_set_negative( p ) (p)->flags2 |= PSH3_POINT_NEGATIVE -#define psh3_point_set_edge_min( p ) (p)->flags2 |= PSH3_POINT_EDGE_MIN -#define psh3_point_set_edge_max( p ) (p)->flags2 |= PSH3_POINT_EDGE_MAX - - - typedef struct PSH3_PointRec_ - { - PSH3_Point prev; - PSH3_Point next; - PSH3_Contour contour; - FT_UInt flags; - FT_UInt flags2; - FT_Char dir_in; - FT_Char dir_out; - FT_Angle angle_in; - FT_Angle angle_out; - PSH3_Hint hint; - FT_Pos org_u; - FT_Pos org_v; - FT_Pos cur_u; -#ifdef DEBUG_HINTER - FT_Pos org_x; - FT_Pos cur_x; - FT_Pos org_y; - FT_Pos cur_y; - FT_UInt flags_x; - FT_UInt flags_y; -#endif - - } PSH3_PointRec; - - -#define PSH3_POINT_EQUAL_ORG( a, b ) ( (a)->org_u == (b)->org_u && \ - (a)->org_v == (b)->org_v ) - -#define PSH3_POINT_ANGLE( a, b ) FT_Atan2( (b)->org_u - (a)->org_u, \ - (b)->org_v - (a)->org_v ) - - typedef struct PSH3_ContourRec_ - { - PSH3_Point start; - FT_UInt count; - - } PSH3_ContourRec; - - - typedef struct PSH3_GlyphRec_ - { - FT_UInt num_points; - FT_UInt num_contours; - - PSH3_Point points; - PSH3_Contour contours; - - FT_Memory memory; - FT_Outline* outline; - PSH_Globals globals; - PSH3_Hint_TableRec hint_tables[2]; - - FT_Bool vertical; - FT_Int major_dir; - FT_Int minor_dir; - - FT_Bool do_horz_hints; - FT_Bool do_vert_hints; - FT_Bool do_horz_snapping; - FT_Bool do_vert_snapping; - FT_Bool do_stem_adjust; - - } PSH3_GlyphRec, *PSH3_Glyph; - - -#ifdef DEBUG_HINTER - extern PSH3_Hint_Table ps3_debug_hint_table; - - typedef void - (*PSH3_HintFunc)( PSH3_Hint hint, - FT_Bool vertical ); - - extern PSH3_HintFunc ps3_debug_hint_func; - - extern PSH3_Glyph ps3_debug_glyph; -#endif - - - extern FT_Error - ps3_hints_apply( PS_Hints ps_hints, - FT_Outline* outline, - PSH_Globals globals, - FT_Render_Mode hint_mode ); - - -FT_END_HEADER - - -#endif /* __PSHALGO3_H__ */ - - -/* END */ diff --git a/src/libs/freetype2/pshinter/pshglob.c b/src/libs/freetype2/pshinter/pshglob.c index c9d24808f1..21d45e92ff 100644 --- a/src/libs/freetype2/pshinter/pshglob.c +++ b/src/libs/freetype2/pshinter/pshglob.c @@ -5,7 +5,7 @@ /* PostScript hinter global hinting management (body). */ /* Inspired by the new auto-hinter module. */ /* */ -/* Copyright 2001, 2002 by */ +/* Copyright 2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used */ @@ -52,7 +52,7 @@ if ( count > 0 ) { width->cur = FT_MulFix( width->org, scale ); - width->fit = FT_RoundFix( width->cur ); + width->fit = FT_PIX_ROUND( width->cur ); width++; count--; @@ -72,12 +72,14 @@ w = stand->cur; width->cur = w; - width->fit = FT_RoundFix( w ); + width->fit = FT_PIX_ROUND( w ); } } } +#if 0 + /* org_width is is font units, result in device pixels, 26.6 format */ FT_LOCAL_DEF( FT_Pos ) psh_dimension_snap_width( PSH_Dimension dimension, @@ -122,6 +124,8 @@ return width; } +#endif /* 0 */ + /*************************************************************************/ /*************************************************************************/ @@ -373,7 +377,7 @@ /* parameter to the raw bluescale value. Here is why: */ /* */ /* We need to suppress overshoots for all pointsizes. */ - /* At 300dpi that satisfy: */ + /* At 300dpi that satisfies: */ /* */ /* pointsize < 240*bluescale + 0.49 */ /* */ @@ -392,7 +396,16 @@ /* */ /* "scale < bluescale" */ /* */ - blues->no_overshoots = FT_BOOL( scale < blues->blue_scale ); + /* Note that `blue_scale' is stored 1000 times its real */ + /* value, and that `scale' converts from font units to */ + /* fractional pixels. */ + /* */ + + /* 1000 / 64 = 125 / 8 */ + if ( scale >= 0x20C49BAL ) + blues->no_overshoots = FT_BOOL( scale < blues->blue_scale * 8 / 125 ); + else + blues->no_overshoots = FT_BOOL( scale * 125 < blues->blue_scale * 8 ); /* */ /* The blue threshold is the font units distance under */ @@ -408,7 +421,7 @@ while ( threshold > 0 && FT_MulFix( threshold, scale ) > 32 ) - threshold --; + threshold--; blues->blue_threshold = threshold; } @@ -444,7 +457,7 @@ zone->cur_delta = FT_MulFix( zone->org_delta, scale ); /* round scaled reference position */ - zone->cur_ref = ( zone->cur_ref + 32 ) & -64; + zone->cur_ref = FT_PIX_ROUND( zone->cur_ref ); #if 0 if ( zone->cur_ref > zone->cur_top ) @@ -526,7 +539,7 @@ no_shoots = blues->no_overshoots; - /* lookup stem top in top zones table */ + /* look up stem top in top zones table */ table = &blues->normal_top; count = table->count; zone = table->zones; @@ -561,7 +574,7 @@ if ( stem_bot >= zone->org_bottom - blues->blue_fuzz ) { - if ( no_shoots || delta < blues->blue_shift ) + if ( no_shoots || delta < blues->blue_threshold ) { alignment->align |= PSH_BLUE_ALIGN_BOT; alignment->align_bot = zone->cur_ref; @@ -640,7 +653,7 @@ read++; } - dim->stdw.count = write - dim->stdw.widths; + dim->stdw.count = priv->num_snap_widths + 1; } /* copy standard heights */ @@ -650,7 +663,7 @@ write->org = priv->standard_height[0]; - write++; + write++; read = priv->snap_heights; for ( count = priv->num_snap_heights; count > 0; count-- ) { @@ -659,7 +672,7 @@ read++; } - dim->stdw.count = write - dim->stdw.widths; + dim->stdw.count = priv->num_snap_heights + 1; } /* copy blue zones */ @@ -671,15 +684,9 @@ priv->family_blues, priv->num_family_other_blues, priv->family_other_blues, priv->blue_fuzz, 1 ); - globals->blues.blue_scale = priv->blue_scale - ? priv->blue_scale - : 0x28937L; /* 0.039625 * 0x400000L */ - - globals->blues.blue_shift = priv->blue_shift - ? priv->blue_shift - : 7; - - globals->blues.blue_fuzz = priv->blue_fuzz; + globals->blues.blue_scale = priv->blue_scale; + globals->blues.blue_shift = priv->blue_shift; + globals->blues.blue_fuzz = priv->blue_fuzz; globals->dimension[0].scale_mult = 0; globals->dimension[0].scale_delta = 0; @@ -696,7 +703,7 @@ } - static FT_Error + FT_LOCAL_DEF( FT_Error ) psh_globals_set_scale( PSH_Globals globals, FT_Fixed x_scale, FT_Fixed y_scale, @@ -740,4 +747,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/pshinter/pshglob.h b/src/libs/freetype2/pshinter/pshglob.h index 35bfafb202..c511626157 100644 --- a/src/libs/freetype2/pshinter/pshglob.h +++ b/src/libs/freetype2/pshinter/pshglob.h @@ -4,7 +4,7 @@ /* */ /* PostScript hinter global hinting management. */ /* */ -/* Copyright 2001, 2002 by */ +/* Copyright 2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -159,11 +159,20 @@ FT_BEGIN_HEADER psh_globals_funcs_init( PSH_Globals_FuncsRec* funcs ); +#if 0 /* snap a stem width to fitter coordinates. `org_width' is in font */ /* units. The result is in device pixels (26.6 format). */ FT_LOCAL( FT_Pos ) psh_dimension_snap_width( PSH_Dimension dimension, FT_Int org_width ); +#endif + + FT_LOCAL( FT_Error ) + psh_globals_set_scale( PSH_Globals globals, + FT_Fixed x_scale, + FT_Fixed y_scale, + FT_Fixed x_delta, + FT_Fixed y_delta ); /* snap a stem to one or two blue zones */ FT_LOCAL( void ) @@ -184,4 +193,4 @@ FT_END_HEADER #endif /* __PSHGLOB_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/pshinter/pshinter.c b/src/libs/freetype2/pshinter/pshinter.c index e118d01b6f..8e3f193093 100644 --- a/src/libs/freetype2/pshinter/pshinter.c +++ b/src/libs/freetype2/pshinter/pshinter.c @@ -4,7 +4,7 @@ /* */ /* FreeType PostScript Hinting module */ /* */ -/* Copyright 2001 by */ +/* Copyright 2001, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,10 +21,8 @@ #include <ft2build.h> #include "pshrec.c" #include "pshglob.c" -#include "pshalgo1.c" -#include "pshalgo2.c" -#include "pshalgo3.c" +#include "pshalgo.c" #include "pshmod.c" -/* END */ +/* END */ diff --git a/src/libs/freetype2/pshinter/pshmod.c b/src/libs/freetype2/pshinter/pshmod.c index 2c53dc726c..5b18684c75 100644 --- a/src/libs/freetype2/pshinter/pshmod.c +++ b/src/libs/freetype2/pshinter/pshmod.c @@ -117,4 +117,4 @@ }; -/* END */ +/* END */ diff --git a/src/libs/freetype2/pshinter/pshmod.h b/src/libs/freetype2/pshinter/pshmod.h index 9d44db28b4..1a91025b26 100644 --- a/src/libs/freetype2/pshinter/pshmod.h +++ b/src/libs/freetype2/pshinter/pshmod.h @@ -36,4 +36,4 @@ FT_END_HEADER #endif /* __PSHMOD_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/pshinter/pshnterr.h b/src/libs/freetype2/pshinter/pshnterr.h new file mode 100644 index 0000000000..3c0029fbf3 --- /dev/null +++ b/src/libs/freetype2/pshinter/pshnterr.h @@ -0,0 +1,40 @@ +/***************************************************************************/ +/* */ +/* pshnterr.h */ +/* */ +/* PS Hinter error codes (specification only). */ +/* */ +/* Copyright 2003 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the PSHinter error enumeration constants. */ + /* */ + /*************************************************************************/ + +#ifndef __PSHNTERR_H__ +#define __PSHNTERR_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX PSH_Err_ +#define FT_ERR_BASE FT_Mod_Err_PShinter + +#include FT_ERRORS_H + +#endif /* __PSHNTERR_H__ */ + + +/* END */ diff --git a/src/libs/freetype2/pshinter/pshrec.c b/src/libs/freetype2/pshinter/pshrec.c index 38996b40ca..648de18bc2 100644 --- a/src/libs/freetype2/pshinter/pshrec.c +++ b/src/libs/freetype2/pshinter/pshrec.c @@ -4,7 +4,7 @@ /* */ /* FreeType PostScript hints recorder (body). */ /* */ -/* Copyright 2001, 2002 by */ +/* Copyright 2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,6 +23,8 @@ #include "pshrec.h" #include "pshalgo.h" +#include "pshnterr.h" + #undef FT_COMPONENT #define FT_COMPONENT trace_pshrec @@ -66,7 +68,7 @@ if ( new_max > old_max ) { /* try to grow the table */ - new_max = ( new_max + 7 ) & -8; + new_max = FT_PAD_CEIL( new_max, 8 ); if ( !FT_RENEW_ARRAY( table->hints, old_max, new_max ) ) table->max_hints = new_max; } @@ -140,7 +142,7 @@ if ( new_max > old_max ) { - new_max = ( new_max + 7 ) & -8; + new_max = FT_PAD_CEIL( new_max, 8 ); if ( !FT_RENEW_ARRAY( mask->bytes, old_max, new_max ) ) mask->max_bits = new_max * 8; } @@ -237,7 +239,7 @@ if ( new_max > old_max ) { - new_max = ( new_max + 7 ) & -8; + new_max = FT_PAD_CEIL( new_max, 8 ); if ( !FT_RENEW_ARRAY( table->masks, old_max, new_max ) ) table->max_masks = new_max; } @@ -316,8 +318,7 @@ PS_Mask mask; - /* allocate new mask, and grow it to "bit_count" bits */ - error = ps_mask_table_alloc( table, memory, &mask ); + error = ps_mask_table_last( table, memory, &mask ); if ( error ) goto Exit; @@ -820,7 +821,7 @@ break; default: - hints->error = FT_Err_Invalid_Argument; + hints->error = PSH_Err_Invalid_Argument; hints->hint_type = hint_type; FT_ERROR(( "ps_hints_open: invalid charstring type!\n" )); @@ -861,8 +862,9 @@ FT_Memory memory = hints->memory; - error = ps_dimension_add_t1stem( dim, stems[0], stems[1], - memory, NULL ); + error = ps_dimension_add_t1stem( + dim, (FT_Int)stems[0], (FT_Int)stems[1], + memory, NULL ); if ( error ) { FT_ERROR(( "ps_hints_stem: could not add stem" @@ -917,8 +919,9 @@ /* add the three stems to our hints/masks table */ for ( count = 0; count < 3; count++, stems += 2 ) { - error = ps_dimension_add_t1stem( dim, stems[0], stems[1], - memory, &idx[count] ); + error = ps_dimension_add_t1stem( + dim, (FT_Int)stems[0], (FT_Int)stems[1], + memory, &idx[count] ); if ( error ) goto Fail; } @@ -932,7 +935,7 @@ else { FT_ERROR(( "ps_hints_t1stem3: called with invalid hint type!\n" )); - error = FT_Err_Invalid_Argument; + error = PSH_Err_Invalid_Argument; goto Fail; } } @@ -973,7 +976,7 @@ else { /* invalid hint type */ - error = FT_Err_Invalid_Argument; + error = PSH_Err_Invalid_Argument; goto Fail; } } @@ -1008,18 +1011,18 @@ FT_ERROR(( "ps_hints_t2mask: " "called with invalid bitcount %d (instead of %d)\n", bit_count, count1 + count2 )); - + /* simply ignore the operator */ return; } /* set-up new horizontal and vertical hint mask now */ - error = ps_dimension_set_mask_bits( &dim[0], bytes, 0, count1, + error = ps_dimension_set_mask_bits( &dim[0], bytes, count2, count1, end_point, memory ); if ( error ) goto Fail; - error = ps_dimension_set_mask_bits( &dim[1], bytes, count1, count2, + error = ps_dimension_set_mask_bits( &dim[1], bytes, 0, count2, end_point, memory ); if ( error ) goto Fail; @@ -1053,7 +1056,7 @@ FT_ERROR(( "ps_hints_t2counter: " "called with invalid bitcount %d (instead of %d)\n", bit_count, count1 + count2 )); - + /* simply ignore the operator */ return; } @@ -1139,7 +1142,7 @@ funcs->stem = (T1_Hints_SetStemFunc) t1_hints_stem; funcs->stem3 = (T1_Hints_SetStem3Func)ps_hints_t1stem3; funcs->reset = (T1_Hints_ResetFunc) ps_hints_t1reset; - funcs->apply = (T1_Hints_ApplyFunc) PS_HINTS_APPLY_FUNC; + funcs->apply = (T1_Hints_ApplyFunc) ps_hints_apply; } @@ -1164,7 +1167,8 @@ FT_Int count, FT_Fixed* coords ) { - FT_Pos stems[32], y, n, total = count; + FT_Pos stems[32], y, n; + FT_Int total = count; y = 0; @@ -1179,7 +1183,7 @@ for ( n = 0; n < count * 2; n++ ) { y += coords[n]; - stems[n] = ( y + 0x8000 ) >> 16; + stems[n] = ( y + 0x8000L ) >> 16; } /* compute lengths */ @@ -1204,8 +1208,8 @@ funcs->stems = (T2_Hints_StemsFunc) t2_hints_stems; funcs->hintmask= (T2_Hints_MaskFunc) ps_hints_t2mask; funcs->counter = (T2_Hints_CounterFunc)ps_hints_t2counter; - funcs->apply = (T2_Hints_ApplyFunc) PS_HINTS_APPLY_FUNC; + funcs->apply = (T2_Hints_ApplyFunc) ps_hints_apply; } -/* END */ +/* END */ diff --git a/src/libs/freetype2/pshinter/pshrec.h b/src/libs/freetype2/pshinter/pshrec.h index 45bf893f64..0159e9cd5d 100644 --- a/src/libs/freetype2/pshinter/pshrec.h +++ b/src/libs/freetype2/pshinter/pshrec.h @@ -4,7 +4,7 @@ /* */ /* Postscript (Type1/Type2) hints recorder (specification). */ /* */ -/* Copyright 2001, 2002 by */ +/* Copyright 2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -125,10 +125,6 @@ FT_BEGIN_HEADER } PS_DimensionRec, *PS_Dimension; - /* magic value used within PS_HintsRec */ -#define PS_HINTS_MAGIC 0x68696e74 /* "hint" */ - - /* glyph hints descriptor */ /* dimension 0 => X coordinates + vertical hints/stems */ /* dimension 1 => Y coordinates + horizontal hints/stems */ @@ -177,4 +173,4 @@ FT_END_HEADER #endif /* __PS_HINTER_RECORD_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/pshinter/rules.mk b/src/libs/freetype2/pshinter/rules.mk index 12be69cf51..57773394ac 100644 --- a/src/libs/freetype2/pshinter/rules.mk +++ b/src/libs/freetype2/pshinter/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2001 by +# Copyright 2001, 2003 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -15,28 +15,26 @@ # PSHINTER driver directory # -PSHINTER_DIR := $(SRC_)pshinter -PSHINTER_DIR_ := $(PSHINTER_DIR)$(SEP) +PSHINTER_DIR := $(SRC_DIR)/pshinter # compilation flags for the driver # -PSHINTER_COMPILE := $(FT_COMPILE) $I$(PSHINTER_DIR) +PSHINTER_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(PSHINTER_DIR)) # PSHINTER driver sources (i.e., C files) # -PSHINTER_DRV_SRC := $(PSHINTER_DIR_)pshrec.c \ - $(PSHINTER_DIR_)pshglob.c \ - $(PSHINTER_DIR_)pshmod.c \ - $(PSHINTER_DIR_)pshalgo1.c \ - $(PSHINTER_DIR_)pshalgo2.c \ - $(PSHINTER_DIR_)pshalgo3.c +PSHINTER_DRV_SRC := $(PSHINTER_DIR)/pshrec.c \ + $(PSHINTER_DIR)/pshglob.c \ + $(PSHINTER_DIR)/pshmod.c \ + $(PSHINTER_DIR)/pshalgo.c # PSHINTER driver headers # -PSHINTER_DRV_H := $(PSHINTER_DRV_SRC:%c=%h) +PSHINTER_DRV_H := $(PSHINTER_DRV_SRC:%c=%h) \ + $(PSHINTER_DIR)/pshnterr.h # PSHINTER driver object(s) @@ -44,25 +42,25 @@ PSHINTER_DRV_H := $(PSHINTER_DRV_SRC:%c=%h) # PSHINTER_DRV_OBJ_M is used during `multi' builds. # PSHINTER_DRV_OBJ_S is used during `single' builds. # -PSHINTER_DRV_OBJ_M := $(PSHINTER_DRV_SRC:$(PSHINTER_DIR_)%.c=$(OBJ_)%.$O) -PSHINTER_DRV_OBJ_S := $(OBJ_)pshinter.$O +PSHINTER_DRV_OBJ_M := $(PSHINTER_DRV_SRC:$(PSHINTER_DIR)/%.c=$(OBJ_DIR)/%.$O) +PSHINTER_DRV_OBJ_S := $(OBJ_DIR)/pshinter.$O # PSHINTER driver source file for single build # -PSHINTER_DRV_SRC_S := $(PSHINTER_DIR_)pshinter.c +PSHINTER_DRV_SRC_S := $(PSHINTER_DIR)/pshinter.c # PSHINTER driver - single object # $(PSHINTER_DRV_OBJ_S): $(PSHINTER_DRV_SRC_S) $(PSHINTER_DRV_SRC) \ $(FREETYPE_H) $(PSHINTER_DRV_H) - $(PSHINTER_COMPILE) $T$@ $(PSHINTER_DRV_SRC_S) + $(PSHINTER_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(PSHINTER_DRV_SRC_S)) # PSHINTER driver - multiple objects # -$(OBJ_)%.$O: $(PSHINTER_DIR_)%.c $(FREETYPE_H) $(PSHINTER_DRV_H) - $(PSHINTER_COMPILE) $T$@ $< +$(OBJ_DIR)/%.$O: $(PSHINTER_DIR)/%.c $(FREETYPE_H) $(PSHINTER_DRV_H) + $(PSHINTER_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) # update main driver object lists @@ -71,4 +69,4 @@ DRV_OBJS_S += $(PSHINTER_DRV_OBJ_S) DRV_OBJS_M += $(PSHINTER_DRV_OBJ_M) -# EOF +# EOF diff --git a/src/libs/freetype2/psnames/descrip.mms b/src/libs/freetype2/psnames/descrip.mms index 859450ac8f..6a66b9fa3e 100644 --- a/src/libs/freetype2/psnames/descrip.mms +++ b/src/libs/freetype2/psnames/descrip.mms @@ -20,4 +20,4 @@ OBJS=psnames.obj all : $(OBJS) library [--.lib]freetype.olb $(OBJS) -# EOF +# EOF diff --git a/src/libs/freetype2/psnames/module.mk b/src/libs/freetype2/psnames/module.mk index 0ed3572d4d..e1e59c46b6 100644 --- a/src/libs/freetype2/psnames/module.mk +++ b/src/libs/freetype2/psnames/module.mk @@ -19,4 +19,4 @@ add_psnames_module: $(OPEN_DRIVER)psnames_module_class$(CLOSE_DRIVER) $(ECHO_DRIVER)psnames $(ECHO_DRIVER_DESC)Postscript & Unicode Glyph name handling$(ECHO_DRIVER_DONE) -# EOF +# EOF diff --git a/src/libs/freetype2/psnames/psmodule.c b/src/libs/freetype2/psnames/psmodule.c index 433c379795..f6d6ae3285 100644 --- a/src/libs/freetype2/psnames/psmodule.c +++ b/src/libs/freetype2/psnames/psmodule.c @@ -4,7 +4,7 @@ /* */ /* PSNames module implementation (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ #include <ft2build.h> -#include FT_INTERNAL_POSTSCRIPT_NAMES_H #include FT_INTERNAL_OBJECTS_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H #include "psmodule.h" #include "pstables.h" @@ -44,7 +44,7 @@ char temp[64]; - /* if the name begins with `uni', then the glyph name may be a */ + /* If the name begins with `uni', then the glyph name may be a */ /* hard-coded unicode character code. */ if ( glyph_name[0] == 'u' && glyph_name[1] == 'n' && @@ -83,7 +83,44 @@ value = ( value << 4 ) + d; } - if ( count == 0 ) + + /* there must be exactly four hex digits */ + if ( ( *p == '\0' || *p == '.' ) && count == 0 ) + return value; + } + + /* If the name begins with `u', followed by four to six uppercase */ + /* hexadicimal digits, it is a hard-coded unicode character code. */ + if ( glyph_name[0] == 'u' ) + { + FT_Int count; + FT_ULong value = 0; + const char* p = glyph_name + 1; + + + for ( count = 6; count > 0; count--, p++ ) + { + char c = *p; + unsigned int d; + + + d = (unsigned char)c - '0'; + if ( d >= 10 ) + { + d = (unsigned char)c - 'A'; + if ( d >= 6 ) + d = 16; + else + d += 10; + } + + if ( d >= 16 ) + break; + + value = ( value << 4 ) + d; + } + + if ( ( *p == '\0' || *p == '.' ) && count <= 2 ) return value; } @@ -139,10 +176,10 @@ /* Builds a table that maps Unicode values to glyph indices */ static FT_Error - ps_build_unicode_table( FT_Memory memory, - FT_UInt num_glyphs, - const char** glyph_names, - PS_Unicodes* table ) + ps_unicodes_init( FT_Memory memory, + FT_UInt num_glyphs, + const char** glyph_names, + PS_Unicodes* table ) { FT_Error error; @@ -170,9 +207,9 @@ { uni_char = ps_unicode_value( gname ); - if ( uni_char != 0 && uni_char != 0xFFFF ) + if ( uni_char != 0 && uni_char != 0xFFFFL ) { - map->unicode = uni_char; + map->unicode = (FT_UInt)uni_char; map->glyph_index = n; map++; } @@ -205,8 +242,8 @@ static FT_UInt - ps_lookup_unicode( PS_Unicodes* table, - FT_ULong unicode ) + ps_unicodes_char_index( PS_Unicodes* table, + FT_ULong unicode ) { PS_UniMap *min, *max, *mid; @@ -231,13 +268,13 @@ max = mid - 1; } - return 0xFFFF; + return 0xFFFFU; } static FT_ULong - ps_next_unicode( PS_Unicodes* table, - FT_ULong unicode ) + ps_unicodes_char_next( PS_Unicodes* table, + FT_ULong unicode ) { PS_UniMap *min, *max, *mid; @@ -298,40 +335,52 @@ static - const PSNames_Interface psnames_interface = + const FT_Service_PsCMapsRec pscmaps_interface = { #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - (PS_Unicode_Value_Func) ps_unicode_value, - (PS_Build_Unicodes_Func) ps_build_unicode_table, - (PS_Lookup_Unicode_Func) ps_lookup_unicode, + (PS_Unicode_ValueFunc) ps_unicode_value, + (PS_Unicodes_InitFunc) ps_unicodes_init, + (PS_Unicodes_CharIndexFunc)ps_unicodes_char_index, + (PS_Unicodes_CharNextFunc) ps_unicodes_char_next, #else 0, 0, 0, + 0, #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ - (PS_Macintosh_Name_Func) ps_get_macintosh_name, - (PS_Adobe_Std_Strings_Func) ps_get_standard_strings, + (PS_Macintosh_Name_Func) ps_get_macintosh_name, + (PS_Adobe_Std_Strings_Func)ps_get_standard_strings, t1_standard_encoding, - t1_expert_encoding, - -#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - (PS_Next_Unicode_Func) ps_next_unicode -#else - 0 -#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ - + t1_expert_encoding }; + static const FT_ServiceDescRec pscmaps_services[] = + { + { FT_SERVICE_ID_POSTSCRIPT_CMAPS, &pscmaps_interface }, + { NULL, NULL } + }; + + + static FT_Pointer + psnames_get_service( FT_Module module, + const char* service_id ) + { + FT_UNUSED( module ); + + return ft_service_list_lookup( pscmaps_services, service_id ); + } + #endif /* !FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES */ + FT_CALLBACK_TABLE_DEF const FT_Module_Class psnames_module_class = { @@ -344,14 +393,16 @@ #ifdef FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES 0, -#else - (void*)&psnames_interface, /* module specific interface */ -#endif - (FT_Module_Constructor)0, (FT_Module_Destructor) 0, (FT_Module_Requester) 0 +#else + (void*)&pscmaps_interface, /* module specific interface */ + (FT_Module_Constructor)0, + (FT_Module_Destructor) 0, + (FT_Module_Requester) psnames_get_service +#endif }; -/* END */ +/* END */ diff --git a/src/libs/freetype2/psnames/psmodule.h b/src/libs/freetype2/psnames/psmodule.h index 527cdba5a6..232fdfb9a9 100644 --- a/src/libs/freetype2/psnames/psmodule.h +++ b/src/libs/freetype2/psnames/psmodule.h @@ -35,4 +35,4 @@ FT_END_HEADER #endif /* __PSMODULE_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/psnames/psnamerr.h b/src/libs/freetype2/psnames/psnamerr.h index 8c1d0a6e8d..ae1541d960 100644 --- a/src/libs/freetype2/psnames/psnamerr.h +++ b/src/libs/freetype2/psnames/psnamerr.h @@ -38,4 +38,4 @@ #endif /* __PSNAMERR_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/psnames/psnames.c b/src/libs/freetype2/psnames/psnames.c index 456078f0bc..d6ed998bfb 100644 --- a/src/libs/freetype2/psnames/psnames.c +++ b/src/libs/freetype2/psnames/psnames.c @@ -22,4 +22,4 @@ #include "psmodule.c" -/* END */ +/* END */ diff --git a/src/libs/freetype2/psnames/pstables.h b/src/libs/freetype2/psnames/pstables.h index a38dbe2034..7c07393757 100644 --- a/src/libs/freetype2/psnames/pstables.h +++ b/src/libs/freetype2/psnames/pstables.h @@ -1,10 +1,10 @@ /***************************************************************************/ /* */ -/* pstables.h */ +/* pstables.h.new */ /* */ /* PostScript glyph names (specification only). */ /* */ -/* Copyright 2000-2001 by */ +/* Copyright 2000-2001, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,8 +23,6 @@ { ".null", "nonmarkingreturn", - "nonbreakingspace", - "apple", ".notdef", "space", "exclam", @@ -420,95 +418,404 @@ #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST "AEacute", + "AEmacron", "Abreve", + "Abreveacute", + "Abrevecyrillic", + "Abrevedotbelow", + "Abrevegrave", + "Abrevehookabove", + "Abrevetilde", + "Acaron", + "Acircle", + "Acircumflexacute", + "Acircumflexdotbelow", + "Acircumflexgrave", + "Acircumflexhookabove", + "Acircumflextilde", "Acute", + "Acyrillic", + "Adblgrave", + "Adieresiscyrillic", + "Adieresismacron", + "Adotbelow", + "Adotmacron", + "Ahookabove", + "Aiecyrillic", + "Ainvertedbreve", "Alpha", "Alphatonos", "Amacron", + "Amonospace", "Aogonek", "Aringacute", + "Aringbelow", + "Aybarmenian", + "Bcircle", + "Bdotaccent", + "Bdotbelow", + "Becyrillic", + "Benarmenian", "Beta", + "Bhook", + "Blinebelow", + "Bmonospace", + "Btopbar", + "Caarmenian", "Cacute", "Caron", "Ccaron", + "Ccedillaacute", + "Ccircle", "Ccircumflex", + "Cdot", "Cdotaccent", + "Chaarmenian", + "Cheabkhasiancyrillic", + "Checyrillic", + "Chedescenderabkhasiancyrillic", + "Chedescendercyrillic", + "Chedieresiscyrillic", + "Cheharmenian", + "Chekhakassiancyrillic", + "Cheverticalstrokecyrillic", "Chi", + "Chook", + "Cmonospace", + "Coarmenian", + "DZ", + "DZcaron", + "Daarmenian", + "Dafrican", "Dcaron", + "Dcedilla", + "Dcircle", + "Dcircumflexbelow", "Dcroat", + "Ddotaccent", + "Ddotbelow", + "Decyrillic", + "Deicoptic", "Delta", - "Delta", + "Deltagreek", + "Dhook", "Dieresis", "DieresisAcute", "DieresisGrave", + "Digammagreek", + "Djecyrillic", + "Dlinebelow", + "Dmonospace", + "Dslash", + "Dtopbar", + "Dz", + "Dzcaron", + "Dzeabkhasiancyrillic", + "Dzecyrillic", + "Dzhecyrillic", "Ebreve", "Ecaron", + "Ecedillabreve", + "Echarmenian", + "Ecircle", + "Ecircumflexacute", + "Ecircumflexbelow", + "Ecircumflexdotbelow", + "Ecircumflexgrave", + "Ecircumflexhookabove", + "Ecircumflextilde", + "Ecyrillic", + "Edblgrave", + "Edot", "Edotaccent", + "Edotbelow", + "Efcyrillic", + "Eharmenian", + "Ehookabove", + "Eightroman", + "Einvertedbreve", + "Eiotifiedcyrillic", + "Elcyrillic", + "Elevenroman", "Emacron", + "Emacronacute", + "Emacrongrave", + "Emcyrillic", + "Emonospace", + "Encyrillic", + "Endescendercyrillic", "Eng", + "Enghecyrillic", + "Enhookcyrillic", "Eogonek", + "Eopen", "Epsilon", "Epsilontonos", + "Ercyrillic", + "Ereversed", + "Ereversedcyrillic", + "Escyrillic", + "Esdescendercyrillic", + "Esh", "Eta", + "Etarmenian", "Etatonos", + "Etilde", + "Etildebelow", "Euro", + "Ezh", + "Ezhcaron", + "Ezhreversed", + "Fcircle", + "Fdotaccent", + "Feharmenian", + "Feicoptic", + "Fhook", + "Fitacyrillic", + "Fiveroman", + "Fmonospace", + "Fourroman", + "GBsquare", + "Gacute", "Gamma", + "Gammaafrican", + "Gangiacoptic", "Gbreve", "Gcaron", + "Gcedilla", + "Gcircle", "Gcircumflex", "Gcommaaccent", + "Gdot", "Gdotaccent", + "Gecyrillic", + "Ghadarmenian", + "Ghemiddlehookcyrillic", + "Ghestrokecyrillic", + "Gheupturncyrillic", + "Ghook", + "Gimarmenian", + "Gjecyrillic", + "Gmacron", + "Gmonospace", "Grave", + "Gsmallhook", + "Gstroke", "H18533", "H18543", "H18551", "H22073", + "HPsquare", + "Haabkhasiancyrillic", + "Hadescendercyrillic", + "Hardsigncyrillic", "Hbar", + "Hbrevebelow", + "Hcedilla", + "Hcircle", "Hcircumflex", + "Hdieresis", + "Hdotaccent", + "Hdotbelow", + "Hmonospace", + "Hoarmenian", + "Horicoptic", "Hungarumlaut", + "Hzsquare", + "IAcyrillic", "IJ", + "IUcyrillic", "Ibreve", + "Icaron", + "Icircle", + "Icyrillic", + "Idblgrave", + "Idieresisacute", + "Idieresiscyrillic", + "Idot", "Idotaccent", + "Idotbelow", + "Iebrevecyrillic", + "Iecyrillic", "Ifraktur", + "Ihookabove", + "Iicyrillic", + "Iinvertedbreve", + "Iishortcyrillic", "Imacron", + "Imacroncyrillic", + "Imonospace", + "Iniarmenian", + "Iocyrillic", "Iogonek", "Iota", + "Iotaafrican", "Iotadieresis", "Iotatonos", + "Istroke", "Itilde", + "Itildebelow", + "Izhitsacyrillic", + "Izhitsadblgravecyrillic", + "Jaarmenian", + "Jcircle", "Jcircumflex", + "Jecyrillic", + "Jheharmenian", + "Jmonospace", + "KBsquare", + "KKsquare", + "Kabashkircyrillic", + "Kacute", + "Kacyrillic", + "Kadescendercyrillic", + "Kahookcyrillic", "Kappa", + "Kastrokecyrillic", + "Kaverticalstrokecyrillic", + "Kcaron", + "Kcedilla", + "Kcircle", "Kcommaaccent", + "Kdotbelow", + "Keharmenian", + "Kenarmenian", + "Khacyrillic", + "Kheicoptic", + "Khook", + "Kjecyrillic", + "Klinebelow", + "Kmonospace", + "Koppacyrillic", + "Koppagreek", + "Ksicyrillic", + "LJ", "LL", "Lacute", "Lambda", "Lcaron", + "Lcedilla", + "Lcircle", + "Lcircumflexbelow", "Lcommaaccent", "Ldot", + "Ldotaccent", + "Ldotbelow", + "Ldotbelowmacron", + "Liwnarmenian", + "Lj", + "Ljecyrillic", + "Llinebelow", + "Lmonospace", + "MBsquare", "Macron", + "Macute", + "Mcircle", + "Mdotaccent", + "Mdotbelow", + "Menarmenian", + "Mmonospace", + "Mturned", "Mu", + "NJ", "Nacute", "Ncaron", + "Ncedilla", + "Ncircle", + "Ncircumflexbelow", "Ncommaaccent", + "Ndotaccent", + "Ndotbelow", + "Nhookleft", + "Nineroman", + "Nj", + "Njecyrillic", + "Nlinebelow", + "Nmonospace", + "Nowarmenian", "Nu", + "Obarredcyrillic", + "Obarreddieresiscyrillic", "Obreve", + "Ocaron", + "Ocenteredtilde", + "Ocircle", + "Ocircumflexacute", + "Ocircumflexdotbelow", + "Ocircumflexgrave", + "Ocircumflexhookabove", + "Ocircumflextilde", + "Ocyrillic", + "Odblacute", + "Odblgrave", + "Odieresiscyrillic", + "Odotbelow", + "Oharmenian", + "Ohm", + "Ohookabove", "Ohorn", + "Ohornacute", + "Ohorndotbelow", + "Ohorngrave", + "Ohornhookabove", + "Ohorntilde", "Ohungarumlaut", + "Oi", + "Oinvertedbreve", "Omacron", + "Omacronacute", + "Omacrongrave", "Omega", - "Omega", + "Omegacyrillic", + "Omegagreek", + "Omegaroundcyrillic", + "Omegatitlocyrillic", "Omegatonos", "Omicron", "Omicrontonos", + "Omonospace", + "Oneroman", + "Oogonek", + "Oogonekmacron", + "Oopen", "Oslashacute", + "Ostrokeacute", + "Otcyrillic", + "Otildeacute", + "Otildedieresis", + "Pacute", + "Pcircle", + "Pdotaccent", + "Pecyrillic", + "Peharmenian", + "Pemiddlehookcyrillic", "Phi", + "Phook", "Pi", + "Piwrarmenian", + "Pmonospace", "Psi", + "Psicyrillic", + "Qcircle", + "Qmonospace", + "Raarmenian", "Racute", "Rcaron", + "Rcedilla", + "Rcircle", "Rcommaaccent", + "Rdblgrave", + "Rdotaccent", + "Rdotbelow", + "Rdotbelowmacron", + "Reharmenian", "Rfraktur", "Rho", + "Rinvertedbreve", + "Rlinebelow", + "Rmonospace", + "Rsmallinverted", + "Rsmallinvertedsuperior", "SF010000", "SF020000", "SF030000", @@ -550,42 +857,211 @@ "SF530000", "SF540000", "Sacute", + "Sacutedotaccent", + "Sampigreek", + "Scarondotaccent", "Scedilla", - "Scedilla", + "Schwa", + "Schwacyrillic", + "Schwadieresiscyrillic", + "Scircle", "Scircumflex", "Scommaaccent", + "Sdotaccent", + "Sdotbelow", + "Sdotbelowdotaccent", + "Seharmenian", + "Sevenroman", + "Shaarmenian", + "Shacyrillic", + "Shchacyrillic", + "Sheicoptic", + "Shhacyrillic", + "Shimacoptic", "Sigma", + "Sixroman", + "Smonospace", + "Softsigncyrillic", + "Stigmagreek", "Tau", "Tbar", "Tcaron", + "Tcedilla", + "Tcircle", + "Tcircumflexbelow", "Tcommaaccent", - "Tcommaaccent", + "Tdotaccent", + "Tdotbelow", + "Tecyrillic", + "Tedescendercyrillic", + "Tenroman", + "Tetsecyrillic", "Theta", + "Thook", + "Threeroman", + "Tiwnarmenian", + "Tlinebelow", + "Tmonospace", + "Toarmenian", + "Tonefive", + "Tonesix", + "Tonetwo", + "Tretroflexhook", + "Tsecyrillic", + "Tshecyrillic", + "Twelveroman", + "Tworoman", "Ubreve", + "Ucaron", + "Ucircle", + "Ucircumflexbelow", + "Ucyrillic", + "Udblacute", + "Udblgrave", + "Udieresisacute", + "Udieresisbelow", + "Udieresiscaron", + "Udieresiscyrillic", + "Udieresisgrave", + "Udieresismacron", + "Udotbelow", + "Uhookabove", "Uhorn", + "Uhornacute", + "Uhorndotbelow", + "Uhorngrave", + "Uhornhookabove", + "Uhorntilde", "Uhungarumlaut", + "Uhungarumlautcyrillic", + "Uinvertedbreve", + "Ukcyrillic", "Umacron", + "Umacroncyrillic", + "Umacrondieresis", + "Umonospace", "Uogonek", "Upsilon", "Upsilon1", + "Upsilonacutehooksymbolgreek", + "Upsilonafrican", "Upsilondieresis", + "Upsilondieresishooksymbolgreek", + "Upsilonhooksymbol", "Upsilontonos", "Uring", + "Ushortcyrillic", + "Ustraightcyrillic", + "Ustraightstrokecyrillic", "Utilde", + "Utildeacute", + "Utildebelow", + "Vcircle", + "Vdotbelow", + "Vecyrillic", + "Vewarmenian", + "Vhook", + "Vmonospace", + "Voarmenian", + "Vtilde", "Wacute", + "Wcircle", "Wcircumflex", "Wdieresis", + "Wdotaccent", + "Wdotbelow", "Wgrave", + "Wmonospace", + "Xcircle", + "Xdieresis", + "Xdotaccent", + "Xeharmenian", "Xi", + "Xmonospace", + "Yatcyrillic", + "Ycircle", "Ycircumflex", + "Ydotaccent", + "Ydotbelow", + "Yericyrillic", + "Yerudieresiscyrillic", "Ygrave", + "Yhook", + "Yhookabove", + "Yiarmenian", + "Yicyrillic", + "Yiwnarmenian", + "Ymonospace", + "Ytilde", + "Yusbigcyrillic", + "Yusbigiotifiedcyrillic", + "Yuslittlecyrillic", + "Yuslittleiotifiedcyrillic", + "Zaarmenian", "Zacute", + "Zcircle", + "Zcircumflex", + "Zdot", "Zdotaccent", + "Zdotbelow", + "Zecyrillic", + "Zedescendercyrillic", + "Zedieresiscyrillic", "Zeta", + "Zhearmenian", + "Zhebrevecyrillic", + "Zhecyrillic", + "Zhedescendercyrillic", + "Zhedieresiscyrillic", + "Zlinebelow", + "Zmonospace", + "Zstroke", + "aabengali", + "aadeva", + "aagujarati", + "aagurmukhi", + "aamatragurmukhi", + "aarusquare", + "aavowelsignbengali", + "aavowelsigndeva", + "aavowelsigngujarati", + "abbreviationmarkarmenian", + "abbreviationsigndeva", + "abengali", + "abopomofo", "abreve", + "abreveacute", + "abrevecyrillic", + "abrevedotbelow", + "abrevegrave", + "abrevehookabove", + "abrevetilde", + "acaron", + "acircle", + "acircumflexacute", + "acircumflexdotbelow", + "acircumflexgrave", + "acircumflexhookabove", + "acircumflextilde", + "acutebelowcmb", + "acutecmb", "acutecomb", + "acutedeva", + "acutelowmod", + "acutetonecmb", + "acyrillic", + "adblgrave", + "addakgurmukhi", + "adeva", + "adieresiscyrillic", + "adieresismacron", + "adotbelow", + "adotmacron", "aeacute", + "aekorean", + "aemacron", "afii00208", + "afii08941", "afii10017", "afii10018", "afii10019", @@ -830,262 +1306,3020 @@ "afii61664", "afii63167", "afii64937", + "agujarati", + "agurmukhi", + "ahiragana", + "ahookabove", + "aibengali", + "aibopomofo", + "aideva", + "aiecyrillic", + "aigujarati", + "aigurmukhi", + "aimatragurmukhi", + "ainarabic", + "ainfinalarabic", + "aininitialarabic", + "ainmedialarabic", + "ainvertedbreve", + "aivowelsignbengali", + "aivowelsigndeva", + "aivowelsigngujarati", + "akatakana", + "akatakanahalfwidth", + "akorean", + "alef", + "alefarabic", + "alefdageshhebrew", + "aleffinalarabic", + "alefhamzaabovearabic", + "alefhamzaabovefinalarabic", + "alefhamzabelowarabic", + "alefhamzabelowfinalarabic", + "alefhebrew", + "aleflamedhebrew", + "alefmaddaabovearabic", + "alefmaddaabovefinalarabic", + "alefmaksuraarabic", + "alefmaksurafinalarabic", + "alefmaksurainitialarabic", + "alefmaksuramedialarabic", + "alefpatahhebrew", + "alefqamatshebrew", "aleph", + "allequal", "alpha", "alphatonos", "amacron", + "amonospace", + "ampersandmonospace", + "amsquare", + "anbopomofo", + "angbopomofo", + "angkhankhuthai", "angle", + "anglebracketleft", + "anglebracketleftvertical", + "anglebracketright", + "anglebracketrightvertical", "angleleft", "angleright", + "angstrom", "anoteleia", + "anudattadeva", + "anusvarabengali", + "anusvaradeva", + "anusvaragujarati", "aogonek", + "apaatosquare", + "aparen", + "apostrophearmenian", + "apostrophemod", + "apple", + "approaches", "approxequal", + "approxequalorimage", + "approximatelyequal", + "araeaekorean", + "araeakorean", + "arc", + "arighthalfring", "aringacute", + "aringbelow", "arrowboth", + "arrowdashdown", + "arrowdashleft", + "arrowdashright", + "arrowdashup", "arrowdblboth", "arrowdbldown", "arrowdblleft", "arrowdblright", "arrowdblup", "arrowdown", + "arrowdownleft", + "arrowdownright", + "arrowdownwhite", + "arrowheaddownmod", + "arrowheadleftmod", + "arrowheadrightmod", + "arrowheadupmod", "arrowhorizex", "arrowleft", + "arrowleftdbl", + "arrowleftdblstroke", + "arrowleftoverright", + "arrowleftwhite", "arrowright", + "arrowrightdblstroke", + "arrowrightheavy", + "arrowrightoverleft", + "arrowrightwhite", + "arrowtableft", + "arrowtabright", "arrowup", "arrowupdn", "arrowupdnbse", + "arrowupdownbase", + "arrowupleft", + "arrowupleftofdown", + "arrowupright", + "arrowupwhite", "arrowvertex", + "asciicircummonospace", + "asciitildemonospace", + "ascript", + "ascriptturned", + "asmallhiragana", + "asmallkatakana", + "asmallkatakanahalfwidth", + "asteriskaltonearabic", + "asteriskarabic", "asteriskmath", + "asteriskmonospace", + "asterisksmall", + "asterism", + "asymptoticallyequal", + "atmonospace", + "atsmall", + "aturned", + "aubengali", + "aubopomofo", + "audeva", + "augujarati", + "augurmukhi", + "aulengthmarkbengali", + "aumatragurmukhi", + "auvowelsignbengali", + "auvowelsigndeva", + "auvowelsigngujarati", + "avagrahadeva", + "aybarmenian", + "ayin", + "ayinaltonehebrew", + "ayinhebrew", + "babengali", + "backslashmonospace", + "badeva", + "bagujarati", + "bagurmukhi", + "bahiragana", + "bahtthai", + "bakatakana", + "barmonospace", + "bbopomofo", + "bcircle", + "bdotaccent", + "bdotbelow", + "beamedsixteenthnotes", + "because", + "becyrillic", + "beharabic", + "behfinalarabic", + "behinitialarabic", + "behiragana", + "behmedialarabic", + "behmeeminitialarabic", + "behmeemisolatedarabic", + "behnoonfinalarabic", + "bekatakana", + "benarmenian", + "bet", "beta", + "betasymbolgreek", + "betdagesh", + "betdageshhebrew", + "bethebrew", + "betrafehebrew", + "bhabengali", + "bhadeva", + "bhagujarati", + "bhagurmukhi", + "bhook", + "bihiragana", + "bikatakana", + "bilabialclick", + "bindigurmukhi", + "birusquare", + "blackcircle", + "blackdiamond", + "blackdownpointingtriangle", + "blackleftpointingpointer", + "blackleftpointingtriangle", + "blacklenticularbracketleft", + "blacklenticularbracketleftvertical", + "blacklenticularbracketright", + "blacklenticularbracketrightvertical", + "blacklowerlefttriangle", + "blacklowerrighttriangle", + "blackrectangle", + "blackrightpointingpointer", + "blackrightpointingtriangle", + "blacksmallsquare", + "blacksmilingface", + "blacksquare", + "blackstar", + "blackupperlefttriangle", + "blackupperrighttriangle", + "blackuppointingsmalltriangle", + "blackuppointingtriangle", + "blank", + "blinebelow", "block", + "bmonospace", + "bobaimaithai", + "bohiragana", + "bokatakana", + "bparen", + "bqsquare", "braceex", "braceleftbt", "braceleftmid", + "braceleftmonospace", + "braceleftsmall", "bracelefttp", + "braceleftvertical", "bracerightbt", "bracerightmid", + "bracerightmonospace", + "bracerightsmall", "bracerighttp", + "bracerightvertical", "bracketleftbt", "bracketleftex", + "bracketleftmonospace", "bracketlefttp", "bracketrightbt", "bracketrightex", + "bracketrightmonospace", "bracketrighttp", + "brevebelowcmb", + "brevecmb", + "breveinvertedbelowcmb", + "breveinvertedcmb", + "breveinverteddoublecmb", + "bridgebelowcmb", + "bridgeinvertedbelowcmb", + "bstroke", + "btopbar", + "buhiragana", + "bukatakana", + "bulletinverse", + "bulletoperator", + "bullseye", + "caarmenian", + "cabengali", "cacute", + "cadeva", + "cagujarati", + "cagurmukhi", + "calsquare", + "candrabindubengali", + "candrabinducmb", + "candrabindudeva", + "candrabindugujarati", + "capslock", + "careof", + "caronbelowcmb", + "caroncmb", "carriagereturn", + "cbopomofo", "ccaron", + "ccedillaacute", + "ccircle", "ccircumflex", + "ccurl", + "cdot", "cdotaccent", + "cdsquare", + "cedillacmb", + "centigrade", + "centmonospace", + "chaarmenian", + "chabengali", + "chadeva", + "chagujarati", + "chagurmukhi", + "chbopomofo", + "cheabkhasiancyrillic", + "checkmark", + "checyrillic", + "chedescenderabkhasiancyrillic", + "chedescendercyrillic", + "chedieresiscyrillic", + "cheharmenian", + "chekhakassiancyrillic", + "cheverticalstrokecyrillic", "chi", + "chieuchacirclekorean", + "chieuchaparenkorean", + "chieuchcirclekorean", + "chieuchkorean", + "chieuchparenkorean", + "chochangthai", + "chochanthai", + "chochingthai", + "chochoethai", + "chook", + "cieucacirclekorean", + "cieucaparenkorean", + "cieuccirclekorean", + "cieuckorean", + "cieucparenkorean", + "cieucuparenkorean", "circle", "circlemultiply", + "circleot", "circleplus", + "circlepostalmark", + "circlewithlefthalfblack", + "circlewithrighthalfblack", + "circumflexbelowcmb", + "circumflexcmb", + "clear", + "clickalveolar", + "clickdental", + "clicklateral", + "clickretroflex", "club", + "clubsuitblack", + "clubsuitwhite", + "cmcubedsquare", + "cmonospace", + "cmsquaredsquare", + "coarmenian", + "colonmonospace", + "colonsign", + "colonsmall", + "colontriangularhalfmod", + "colontriangularmod", + "commaabovecmb", + "commaaboverightcmb", "commaaccent", + "commaarabic", + "commaarmenian", + "commamonospace", + "commareversedabovecmb", + "commareversedmod", + "commasmall", + "commaturnedabovecmb", + "commaturnedmod", + "compass", "congruent", + "contourintegral", + "control", + "controlACK", + "controlBEL", + "controlBS", + "controlCAN", + "controlCR", + "controlDC1", + "controlDC2", + "controlDC3", + "controlDC4", + "controlDEL", + "controlDLE", + "controlEM", + "controlENQ", + "controlEOT", + "controlESC", + "controlETB", + "controlETX", + "controlFF", + "controlFS", + "controlGS", + "controlHT", + "controlLF", + "controlNAK", + "controlRS", + "controlSI", + "controlSO", + "controlSOT", + "controlSTX", + "controlSUB", + "controlSYN", + "controlUS", + "controlVT", "copyrightsans", "copyrightserif", + "cornerbracketleft", + "cornerbracketlefthalfwidth", + "cornerbracketleftvertical", + "cornerbracketright", + "cornerbracketrighthalfwidth", + "cornerbracketrightvertical", + "corporationsquare", + "cosquare", + "coverkgsquare", + "cparen", + "cruzeiro", + "cstretched", + "curlyand", + "curlyor", "cyrBreve", "cyrFlex", "cyrbreve", "cyrflex", + "daarmenian", + "dabengali", + "dadarabic", + "dadeva", + "dadfinalarabic", + "dadinitialarabic", + "dadmedialarabic", + "dagesh", + "dageshhebrew", + "dagujarati", + "dagurmukhi", + "dahiragana", + "dakatakana", + "dalarabic", + "dalet", + "daletdagesh", + "daletdageshhebrew", + "dalethatafpatah", + "dalethatafpatahhebrew", + "dalethatafsegol", + "dalethatafsegolhebrew", + "dalethebrew", + "dalethiriq", + "dalethiriqhebrew", + "daletholam", + "daletholamhebrew", + "daletpatah", + "daletpatahhebrew", + "daletqamats", + "daletqamatshebrew", + "daletqubuts", + "daletqubutshebrew", + "daletsegol", + "daletsegolhebrew", + "daletsheva", + "daletshevahebrew", + "dalettsere", + "dalettserehebrew", + "dalfinalarabic", + "dammaarabic", + "dammalowarabic", + "dammatanaltonearabic", + "dammatanarabic", + "danda", + "dargahebrew", + "dargalefthebrew", + "dasiapneumatacyrilliccmb", "dblGrave", + "dblanglebracketleft", + "dblanglebracketleftvertical", + "dblanglebracketright", + "dblanglebracketrightvertical", + "dblarchinvertedbelowcmb", + "dblarrowleft", + "dblarrowright", + "dbldanda", "dblgrave", + "dblgravecmb", + "dblintegral", + "dbllowline", + "dbllowlinecmb", + "dbloverlinecmb", + "dblprimemod", + "dblverticalbar", + "dblverticallineabovecmb", + "dbopomofo", + "dbsquare", "dcaron", + "dcedilla", + "dcircle", + "dcircumflexbelow", "dcroat", + "ddabengali", + "ddadeva", + "ddagujarati", + "ddagurmukhi", + "ddalarabic", + "ddalfinalarabic", + "dddhadeva", + "ddhabengali", + "ddhadeva", + "ddhagujarati", + "ddhagurmukhi", + "ddotaccent", + "ddotbelow", + "decimalseparatorarabic", + "decimalseparatorpersian", + "decyrillic", + "dehihebrew", + "dehiragana", + "deicoptic", + "dekatakana", + "deleteleft", + "deleteright", "delta", + "deltaturned", + "denominatorminusonenumeratorbengali", + "dezh", + "dhabengali", + "dhadeva", + "dhagujarati", + "dhagurmukhi", + "dhook", + "dialytikatonos", + "dialytikatonoscmb", "diamond", + "diamondsuitwhite", "dieresisacute", + "dieresisbelowcmb", + "dieresiscmb", "dieresisgrave", "dieresistonos", + "dihiragana", + "dikatakana", + "dittomark", + "divides", + "divisionslash", + "djecyrillic", "dkshade", + "dlinebelow", + "dlsquare", + "dmacron", + "dmonospace", "dnblock", + "dochadathai", + "dodekthai", + "dohiragana", + "dokatakana", + "dollarmonospace", + "dollarsmall", "dong", + "dorusquare", + "dotaccentcmb", + "dotbelowcmb", "dotbelowcomb", + "dotkatakana", "dotlessj", + "dotlessjstrokehook", "dotmath", + "dottedcircle", + "doubleyodpatah", + "doubleyodpatahhebrew", + "downtackbelowcmb", + "downtackmod", + "dparen", + "dtail", + "dtopbar", + "duhiragana", + "dukatakana", + "dz", + "dzaltone", + "dzcaron", + "dzcurl", + "dzeabkhasiancyrillic", + "dzecyrillic", + "dzhecyrillic", + "earth", + "ebengali", + "ebopomofo", "ebreve", + "ecandradeva", + "ecandragujarati", + "ecandravowelsigndeva", + "ecandravowelsigngujarati", "ecaron", + "ecedillabreve", + "echarmenian", + "echyiwnarmenian", + "ecircle", + "ecircumflexacute", + "ecircumflexbelow", + "ecircumflexdotbelow", + "ecircumflexgrave", + "ecircumflexhookabove", + "ecircumflextilde", + "ecyrillic", + "edblgrave", + "edeva", + "edot", "edotaccent", + "edotbelow", + "eegurmukhi", + "eematragurmukhi", + "efcyrillic", + "egujarati", + "eharmenian", + "ehbopomofo", + "ehiragana", + "ehookabove", + "eibopomofo", + "eightarabic", + "eightbengali", + "eightcircle", + "eightcircleinversesansserif", + "eightdeva", + "eighteencircle", + "eighteenparen", + "eighteenperiod", + "eightgujarati", + "eightgurmukhi", + "eighthackarabic", + "eighthangzhou", + "eighthnotebeamed", + "eightideographicparen", + "eightmonospace", + "eightparen", + "eightperiod", + "eightpersian", + "eightroman", + "eightthai", + "einvertedbreve", + "eiotifiedcyrillic", + "ekatakana", + "ekatakanahalfwidth", + "ekonkargurmukhi", + "ekorean", + "elcyrillic", "element", + "elevencircle", + "elevenparen", + "elevenperiod", + "elevenroman", + "ellipsisvertical", "emacron", + "emacronacute", + "emacrongrave", + "emcyrillic", + "emdashvertical", + "emonospace", + "emphasismarkarmenian", "emptyset", + "enbopomofo", + "encyrillic", + "endashvertical", + "endescendercyrillic", "eng", + "engbopomofo", + "enghecyrillic", + "enhookcyrillic", + "enspace", "eogonek", + "eokorean", + "eopen", + "eopenclosed", + "eopenreversed", + "eopenreversedclosed", + "eopenreversedhook", + "eparen", "epsilon", "epsilontonos", + "equalmonospace", + "equalsmall", + "equalsuperior", "equivalence", + "erbopomofo", + "ercyrillic", + "ereversed", + "ereversedcyrillic", + "escyrillic", + "esdescendercyrillic", + "esh", + "eshcurl", + "eshortdeva", + "eshortvowelsigndeva", + "eshreversedloop", + "eshsquatreversed", + "esmallhiragana", + "esmallkatakana", + "esmallkatakanahalfwidth", "estimated", "eta", + "etarmenian", "etatonos", + "etilde", + "etildebelow", + "etnahtafoukhhebrew", + "etnahtafoukhlefthebrew", + "etnahtahebrew", + "etnahtalefthebrew", + "eturned", + "eukorean", + "euro", + "evowelsignbengali", + "evowelsigndeva", + "evowelsigngujarati", + "exclamarmenian", "exclamdbl", + "exclammonospace", "existential", + "ezh", + "ezhcaron", + "ezhcurl", + "ezhreversed", + "ezhtail", + "fadeva", + "fagurmukhi", + "fahrenheit", + "fathaarabic", + "fathalowarabic", + "fathatanarabic", + "fbopomofo", + "fcircle", + "fdotaccent", + "feharabic", + "feharmenian", + "fehfinalarabic", + "fehinitialarabic", + "fehmedialarabic", + "feicoptic", "female", + "fifteencircle", + "fifteenparen", + "fifteenperiod", "filledbox", "filledrect", + "finalkaf", + "finalkafdagesh", + "finalkafdageshhebrew", + "finalkafhebrew", + "finalkafqamats", + "finalkafqamatshebrew", + "finalkafsheva", + "finalkafshevahebrew", + "finalmem", + "finalmemhebrew", + "finalnun", + "finalnunhebrew", + "finalpe", + "finalpehebrew", + "finaltsadi", + "finaltsadihebrew", + "firsttonechinese", + "fisheye", + "fitacyrillic", + "fivearabic", + "fivebengali", + "fivecircle", + "fivecircleinversesansserif", + "fivedeva", + "fivegujarati", + "fivegurmukhi", + "fivehackarabic", + "fivehangzhou", + "fiveideographicparen", + "fivemonospace", + "fiveparen", + "fiveperiod", + "fivepersian", + "fiveroman", + "fivethai", + "fmonospace", + "fmsquare", + "fofanthai", + "fofathai", + "fongmanthai", + "forall", + "fourarabic", + "fourbengali", + "fourcircle", + "fourcircleinversesansserif", + "fourdeva", + "fourgujarati", + "fourgurmukhi", + "fourhackarabic", + "fourhangzhou", + "fourideographicparen", + "fourmonospace", + "fournumeratorbengali", + "fourparen", + "fourperiod", + "fourpersian", + "fourroman", + "fourteencircle", + "fourteenparen", + "fourteenperiod", + "fourthai", + "fourthtonechinese", + "fparen", "franc", + "gabengali", + "gacute", + "gadeva", + "gafarabic", + "gaffinalarabic", + "gafinitialarabic", + "gafmedialarabic", + "gagujarati", + "gagurmukhi", + "gahiragana", + "gakatakana", "gamma", + "gammalatinsmall", + "gammasuperior", + "gangiacoptic", + "gbopomofo", "gbreve", "gcaron", + "gcedilla", + "gcircle", "gcircumflex", "gcommaaccent", + "gdot", "gdotaccent", + "gecyrillic", + "gehiragana", + "gekatakana", + "geometricallyequal", + "gereshaccenthebrew", + "gereshhebrew", + "gereshmuqdamhebrew", + "gershayimaccenthebrew", + "gershayimhebrew", + "getamark", + "ghabengali", + "ghadarmenian", + "ghadeva", + "ghagujarati", + "ghagurmukhi", + "ghainarabic", + "ghainfinalarabic", + "ghaininitialarabic", + "ghainmedialarabic", + "ghemiddlehookcyrillic", + "ghestrokecyrillic", + "gheupturncyrillic", + "ghhadeva", + "ghhagurmukhi", + "ghook", + "ghzsquare", + "gihiragana", + "gikatakana", + "gimarmenian", + "gimel", + "gimeldagesh", + "gimeldageshhebrew", + "gimelhebrew", + "gjecyrillic", + "glottalinvertedstroke", + "glottalstop", + "glottalstopinverted", + "glottalstopmod", + "glottalstopreversed", + "glottalstopreversedmod", + "glottalstopreversedsuperior", + "glottalstopstroke", + "glottalstopstrokereversed", + "gmacron", + "gmonospace", + "gohiragana", + "gokatakana", + "gparen", + "gpasquare", "gradient", + "gravebelowcmb", + "gravecmb", "gravecomb", + "gravedeva", + "gravelowmod", + "gravemonospace", + "gravetonecmb", "greaterequal", + "greaterequalorless", + "greatermonospace", + "greaterorequivalent", + "greaterorless", + "greateroverequal", + "greatersmall", + "gscript", + "gstroke", + "guhiragana", + "gukatakana", + "guramusquare", + "gysquare", + "haabkhasiancyrillic", + "haaltonearabic", + "habengali", + "hadescendercyrillic", + "hadeva", + "hagujarati", + "hagurmukhi", + "haharabic", + "hahfinalarabic", + "hahinitialarabic", + "hahiragana", + "hahmedialarabic", + "haitusquare", + "hakatakana", + "hakatakanahalfwidth", + "halantgurmukhi", + "hamzaarabic", + "hamzadammaarabic", + "hamzadammatanarabic", + "hamzafathaarabic", + "hamzafathatanarabic", + "hamzalowarabic", + "hamzalowkasraarabic", + "hamzalowkasratanarabic", + "hamzasukunarabic", + "hangulfiller", + "hardsigncyrillic", + "harpoonleftbarbup", + "harpoonrightbarbup", + "hasquare", + "hatafpatah", + "hatafpatah16", + "hatafpatah23", + "hatafpatah2f", + "hatafpatahhebrew", + "hatafpatahnarrowhebrew", + "hatafpatahquarterhebrew", + "hatafpatahwidehebrew", + "hatafqamats", + "hatafqamats1b", + "hatafqamats28", + "hatafqamats34", + "hatafqamatshebrew", + "hatafqamatsnarrowhebrew", + "hatafqamatsquarterhebrew", + "hatafqamatswidehebrew", + "hatafsegol", + "hatafsegol17", + "hatafsegol24", + "hatafsegol30", + "hatafsegolhebrew", + "hatafsegolnarrowhebrew", + "hatafsegolquarterhebrew", + "hatafsegolwidehebrew", "hbar", + "hbopomofo", + "hbrevebelow", + "hcedilla", + "hcircle", "hcircumflex", + "hdieresis", + "hdotaccent", + "hdotbelow", + "he", "heart", + "heartsuitblack", + "heartsuitwhite", + "hedagesh", + "hedageshhebrew", + "hehaltonearabic", + "heharabic", + "hehebrew", + "hehfinalaltonearabic", + "hehfinalalttwoarabic", + "hehfinalarabic", + "hehhamzaabovefinalarabic", + "hehhamzaaboveisolatedarabic", + "hehinitialaltonearabic", + "hehinitialarabic", + "hehiragana", + "hehmedialaltonearabic", + "hehmedialarabic", + "heiseierasquare", + "hekatakana", + "hekatakanahalfwidth", + "hekutaarusquare", + "henghook", + "herutusquare", + "het", + "hethebrew", + "hhook", + "hhooksuperior", + "hieuhacirclekorean", + "hieuhaparenkorean", + "hieuhcirclekorean", + "hieuhkorean", + "hieuhparenkorean", + "hihiragana", + "hikatakana", + "hikatakanahalfwidth", + "hiriq", + "hiriq14", + "hiriq21", + "hiriq2d", + "hiriqhebrew", + "hiriqnarrowhebrew", + "hiriqquarterhebrew", + "hiriqwidehebrew", + "hlinebelow", + "hmonospace", + "hoarmenian", + "hohipthai", + "hohiragana", + "hokatakana", + "hokatakanahalfwidth", + "holam", + "holam19", + "holam26", + "holam32", + "holamhebrew", + "holamnarrowhebrew", + "holamquarterhebrew", + "holamwidehebrew", + "honokhukthai", "hookabovecomb", + "hookcmb", + "hookpalatalizedbelowcmb", + "hookretroflexbelowcmb", + "hoonsquare", + "horicoptic", + "horizontalbar", + "horncmb", + "hotsprings", "house", + "hparen", + "hsuperior", + "hturned", + "huhiragana", + "huiitosquare", + "hukatakana", + "hukatakanahalfwidth", + "hungarumlautcmb", + "hv", + "hyphenmonospace", + "hyphensmall", + "hyphentwo", + "iacyrillic", + "ibengali", + "ibopomofo", "ibreve", + "icaron", + "icircle", + "icyrillic", + "idblgrave", + "ideographearthcircle", + "ideographfirecircle", + "ideographicallianceparen", + "ideographiccallparen", + "ideographiccentrecircle", + "ideographicclose", + "ideographiccomma", + "ideographiccommaleft", + "ideographiccongratulationparen", + "ideographiccorrectcircle", + "ideographicearthparen", + "ideographicenterpriseparen", + "ideographicexcellentcircle", + "ideographicfestivalparen", + "ideographicfinancialcircle", + "ideographicfinancialparen", + "ideographicfireparen", + "ideographichaveparen", + "ideographichighcircle", + "ideographiciterationmark", + "ideographiclaborcircle", + "ideographiclaborparen", + "ideographicleftcircle", + "ideographiclowcircle", + "ideographicmedicinecircle", + "ideographicmetalparen", + "ideographicmoonparen", + "ideographicnameparen", + "ideographicperiod", + "ideographicprintcircle", + "ideographicreachparen", + "ideographicrepresentparen", + "ideographicresourceparen", + "ideographicrightcircle", + "ideographicsecretcircle", + "ideographicselfparen", + "ideographicsocietyparen", + "ideographicspace", + "ideographicspecialparen", + "ideographicstockparen", + "ideographicstudyparen", + "ideographicsunparen", + "ideographicsuperviseparen", + "ideographicwaterparen", + "ideographicwoodparen", + "ideographiczero", + "ideographmetalcircle", + "ideographmooncircle", + "ideographnamecircle", + "ideographsuncircle", + "ideographwatercircle", + "ideographwoodcircle", + "ideva", + "idieresisacute", + "idieresiscyrillic", + "idotbelow", + "iebrevecyrillic", + "iecyrillic", + "ieungacirclekorean", + "ieungaparenkorean", + "ieungcirclekorean", + "ieungkorean", + "ieungparenkorean", + "igujarati", + "igurmukhi", + "ihiragana", + "ihookabove", + "iibengali", + "iicyrillic", + "iideva", + "iigujarati", + "iigurmukhi", + "iimatragurmukhi", + "iinvertedbreve", + "iishortcyrillic", + "iivowelsignbengali", + "iivowelsigndeva", + "iivowelsigngujarati", "ij", + "ikatakana", + "ikatakanahalfwidth", + "ikorean", + "ilde", + "iluyhebrew", "imacron", + "imacroncyrillic", + "imageorapproximatelyequal", + "imatragurmukhi", + "imonospace", + "increment", "infinity", + "iniarmenian", "integral", + "integralbottom", "integralbt", "integralex", + "integraltop", "integraltp", "intersection", + "intisquare", "invbullet", "invcircle", "invsmileface", + "iocyrillic", "iogonek", "iota", "iotadieresis", "iotadieresistonos", + "iotalatin", "iotatonos", + "iparen", + "irigurmukhi", + "ismallhiragana", + "ismallkatakana", + "ismallkatakanahalfwidth", + "issharbengali", + "istroke", + "iterationhiragana", + "iterationkatakana", "itilde", + "itildebelow", + "iubopomofo", + "iucyrillic", + "ivowelsignbengali", + "ivowelsigndeva", + "ivowelsigngujarati", + "izhitsacyrillic", + "izhitsadblgravecyrillic", + "jaarmenian", + "jabengali", + "jadeva", + "jagujarati", + "jagurmukhi", + "jbopomofo", + "jcaron", + "jcircle", "jcircumflex", + "jcrossedtail", + "jdotlessstroke", + "jecyrillic", + "jeemarabic", + "jeemfinalarabic", + "jeeminitialarabic", + "jeemmedialarabic", + "jeharabic", + "jehfinalarabic", + "jhabengali", + "jhadeva", + "jhagujarati", + "jhagurmukhi", + "jheharmenian", + "jis", + "jmonospace", + "jparen", + "jsuperior", + "kabashkircyrillic", + "kabengali", + "kacute", + "kacyrillic", + "kadescendercyrillic", + "kadeva", + "kaf", + "kafarabic", + "kafdagesh", + "kafdageshhebrew", + "kaffinalarabic", + "kafhebrew", + "kafinitialarabic", + "kafmedialarabic", + "kafrafehebrew", + "kagujarati", + "kagurmukhi", + "kahiragana", + "kahookcyrillic", + "kakatakana", + "kakatakanahalfwidth", "kappa", + "kappasymbolgreek", + "kapyeounmieumkorean", + "kapyeounphieuphkorean", + "kapyeounpieupkorean", + "kapyeounssangpieupkorean", + "karoriisquare", + "kashidaautoarabic", + "kashidaautonosidebearingarabic", + "kasmallkatakana", + "kasquare", + "kasraarabic", + "kasratanarabic", + "kastrokecyrillic", + "katahiraprolongmarkhalfwidth", + "kaverticalstrokecyrillic", + "kbopomofo", + "kcalsquare", + "kcaron", + "kcedilla", + "kcircle", "kcommaaccent", + "kdotbelow", + "keharmenian", + "kehiragana", + "kekatakana", + "kekatakanahalfwidth", + "kenarmenian", + "kesmallkatakana", "kgreenlandic", + "khabengali", + "khacyrillic", + "khadeva", + "khagujarati", + "khagurmukhi", + "khaharabic", + "khahfinalarabic", + "khahinitialarabic", + "khahmedialarabic", + "kheicoptic", + "khhadeva", + "khhagurmukhi", + "khieukhacirclekorean", + "khieukhaparenkorean", + "khieukhcirclekorean", + "khieukhkorean", + "khieukhparenkorean", + "khokhaithai", + "khokhonthai", + "khokhuatthai", + "khokhwaithai", + "khomutthai", + "khook", + "khorakhangthai", + "khzsquare", + "kihiragana", + "kikatakana", + "kikatakanahalfwidth", + "kiroguramusquare", + "kiromeetorusquare", + "kirosquare", + "kiyeokacirclekorean", + "kiyeokaparenkorean", + "kiyeokcirclekorean", + "kiyeokkorean", + "kiyeokparenkorean", + "kiyeoksioskorean", + "kjecyrillic", + "klinebelow", + "klsquare", + "kmcubedsquare", + "kmonospace", + "kmsquaredsquare", + "kohiragana", + "kohmsquare", + "kokaithai", + "kokatakana", + "kokatakanahalfwidth", + "kooposquare", + "koppacyrillic", + "koreanstandardsymbol", + "koroniscmb", + "kparen", + "kpasquare", + "ksicyrillic", + "ktsquare", + "kturned", + "kuhiragana", + "kukatakana", + "kukatakanahalfwidth", + "kvsquare", + "kwsquare", + "labengali", "lacute", + "ladeva", + "lagujarati", + "lagurmukhi", + "lakkhangyaothai", + "lamaleffinalarabic", + "lamalefhamzaabovefinalarabic", + "lamalefhamzaaboveisolatedarabic", + "lamalefhamzabelowfinalarabic", + "lamalefhamzabelowisolatedarabic", + "lamalefisolatedarabic", + "lamalefmaddaabovefinalarabic", + "lamalefmaddaaboveisolatedarabic", + "lamarabic", "lambda", + "lambdastroke", + "lamed", + "lameddagesh", + "lameddageshhebrew", + "lamedhebrew", + "lamedholam", + "lamedholamdagesh", + "lamedholamdageshhebrew", + "lamedholamhebrew", + "lamfinalarabic", + "lamhahinitialarabic", + "laminitialarabic", + "lamjeeminitialarabic", + "lamkhahinitialarabic", + "lamlamhehisolatedarabic", + "lammedialarabic", + "lammeemhahinitialarabic", + "lammeeminitialarabic", + "lammeemjeeminitialarabic", + "lammeemkhahinitialarabic", + "largecircle", + "lbar", + "lbelt", + "lbopomofo", "lcaron", + "lcedilla", + "lcircle", + "lcircumflexbelow", "lcommaaccent", "ldot", + "ldotaccent", + "ldotbelow", + "ldotbelowmacron", + "leftangleabovecmb", + "lefttackbelowcmb", "lessequal", + "lessequalorgreater", + "lessmonospace", + "lessorequivalent", + "lessorgreater", + "lessoverequal", + "lesssmall", + "lezh", "lfblock", + "lhookretroflex", "lira", + "liwnarmenian", + "lj", + "ljecyrillic", "ll", + "lladeva", + "llagujarati", + "llinebelow", + "llladeva", + "llvocalicbengali", + "llvocalicdeva", + "llvocalicvowelsignbengali", + "llvocalicvowelsigndeva", + "lmiddletilde", + "lmonospace", + "lmsquare", + "lochulathai", "logicaland", + "logicalnotreversed", "logicalor", + "lolingthai", "longs", + "lowlinecenterline", + "lowlinecmb", + "lowlinedashed", "lozenge", + "lparen", + "lsquare", "ltshade", + "luthai", + "lvocalicbengali", + "lvocalicdeva", + "lvocalicvowelsignbengali", + "lvocalicvowelsigndeva", + "lxsquare", + "mabengali", + "macronbelowcmb", + "macroncmb", + "macronlowmod", + "macronmonospace", + "macute", + "madeva", + "magujarati", + "magurmukhi", + "mahapakhhebrew", + "mahapakhlefthebrew", + "mahiragana", + "maichattawalowleftthai", + "maichattawalowrightthai", + "maichattawathai", + "maichattawaupperleftthai", + "maieklowleftthai", + "maieklowrightthai", + "maiekthai", + "maiekupperleftthai", + "maihanakatleftthai", + "maihanakatthai", + "maitaikhuleftthai", + "maitaikhuthai", + "maitholowleftthai", + "maitholowrightthai", + "maithothai", + "maithoupperleftthai", + "maitrilowleftthai", + "maitrilowrightthai", + "maitrithai", + "maitriupperleftthai", + "maiyamokthai", + "makatakana", + "makatakanahalfwidth", "male", + "mansyonsquare", + "maqafhebrew", + "mars", + "masoracirclehebrew", + "masquare", + "mbopomofo", + "mbsquare", + "mcircle", + "mcubedsquare", + "mdotaccent", + "mdotbelow", + "meemarabic", + "meemfinalarabic", + "meeminitialarabic", + "meemmedialarabic", + "meemmeeminitialarabic", + "meemmeemisolatedarabic", + "meetorusquare", + "mehiragana", + "meizierasquare", + "mekatakana", + "mekatakanahalfwidth", + "mem", + "memdagesh", + "memdageshhebrew", + "memhebrew", + "menarmenian", + "merkhahebrew", + "merkhakefulahebrew", + "merkhakefulalefthebrew", + "merkhalefthebrew", + "mhook", + "mhzsquare", + "middledotkatakanahalfwidth", + "middot", + "mieumacirclekorean", + "mieumaparenkorean", + "mieumcirclekorean", + "mieumkorean", + "mieumpansioskorean", + "mieumparenkorean", + "mieumpieupkorean", + "mieumsioskorean", + "mihiragana", + "mikatakana", + "mikatakanahalfwidth", + "minusbelowcmb", + "minuscircle", + "minusmod", + "minusplus", "minute", + "miribaarusquare", + "mirisquare", + "mlonglegturned", + "mlsquare", + "mmcubedsquare", + "mmonospace", + "mmsquaredsquare", + "mohiragana", + "mohmsquare", + "mokatakana", + "mokatakanahalfwidth", + "molsquare", + "momathai", + "moverssquare", + "moverssquaredsquare", + "mparen", + "mpasquare", + "mssquare", + "mturned", + "mu1", + "muasquare", + "muchgreater", + "muchless", + "mufsquare", + "mugreek", + "mugsquare", + "muhiragana", + "mukatakana", + "mukatakanahalfwidth", + "mulsquare", + "mumsquare", + "munahhebrew", + "munahlefthebrew", "musicalnote", "musicalnotedbl", + "musicflatsign", + "musicsharpsign", + "mussquare", + "muvsquare", + "muwsquare", + "mvmegasquare", + "mvsquare", + "mwmegasquare", + "mwsquare", + "nabengali", + "nabla", "nacute", + "nadeva", + "nagujarati", + "nagurmukhi", + "nahiragana", + "nakatakana", + "nakatakanahalfwidth", "napostrophe", + "nasquare", + "nbopomofo", + "nbspace", "ncaron", + "ncedilla", + "ncircle", + "ncircumflexbelow", "ncommaaccent", + "ndotaccent", + "ndotbelow", + "nehiragana", + "nekatakana", + "nekatakanahalfwidth", + "newsheqelsign", + "nfsquare", + "ngabengali", + "ngadeva", + "ngagujarati", + "ngagurmukhi", + "ngonguthai", + "nhiragana", + "nhookleft", + "nhookretroflex", + "nieunacirclekorean", + "nieunaparenkorean", + "nieuncieuckorean", + "nieuncirclekorean", + "nieunhieuhkorean", + "nieunkorean", + "nieunpansioskorean", + "nieunparenkorean", + "nieunsioskorean", + "nieuntikeutkorean", + "nihiragana", + "nikatakana", + "nikatakanahalfwidth", + "nikhahitleftthai", + "nikhahitthai", + "ninearabic", + "ninebengali", + "ninecircle", + "ninecircleinversesansserif", + "ninedeva", + "ninegujarati", + "ninegurmukhi", + "ninehackarabic", + "ninehangzhou", + "nineideographicparen", + "ninemonospace", + "nineparen", + "nineperiod", + "ninepersian", + "nineroman", + "nineteencircle", + "nineteenparen", + "nineteenperiod", + "ninethai", + "nj", + "njecyrillic", + "nkatakana", + "nkatakanahalfwidth", + "nlegrightlong", + "nlinebelow", + "nmonospace", + "nmsquare", + "nnabengali", + "nnadeva", + "nnagujarati", + "nnagurmukhi", + "nnnadeva", + "nohiragana", + "nokatakana", + "nokatakanahalfwidth", + "nonbreakingspace", + "nonenthai", + "nonuthai", + "noonarabic", + "noonfinalarabic", + "noonghunnaarabic", + "noonghunnafinalarabic", + "noonhehinitialarabic", + "nooninitialarabic", + "noonjeeminitialarabic", + "noonjeemisolatedarabic", + "noonmedialarabic", + "noonmeeminitialarabic", + "noonmeemisolatedarabic", + "noonnoonfinalarabic", + "notcontains", "notelement", + "notelementof", "notequal", + "notgreater", + "notgreaternorequal", + "notgreaternorless", + "notidentical", + "notless", + "notlessnorequal", + "notparallel", + "notprecedes", "notsubset", + "notsucceeds", + "notsuperset", + "nowarmenian", + "nparen", + "nssquare", "nu", + "nuhiragana", + "nukatakana", + "nukatakanahalfwidth", + "nuktabengali", + "nuktadeva", + "nuktagujarati", + "nuktagurmukhi", + "numbersignmonospace", + "numbersignsmall", + "numeralsigngreek", + "numeralsignlowergreek", + "numero", + "nun", + "nundagesh", + "nundageshhebrew", + "nunhebrew", + "nvsquare", + "nwsquare", + "nyabengali", + "nyadeva", + "nyagujarati", + "nyagurmukhi", + "oangthai", + "obarred", + "obarredcyrillic", + "obarreddieresiscyrillic", + "obengali", + "obopomofo", "obreve", + "ocandradeva", + "ocandragujarati", + "ocandravowelsigndeva", + "ocandravowelsigngujarati", + "ocaron", + "ocircle", + "ocircumflexacute", + "ocircumflexdotbelow", + "ocircumflexgrave", + "ocircumflexhookabove", + "ocircumflextilde", + "ocyrillic", + "odblacute", + "odblgrave", + "odeva", + "odieresiscyrillic", + "odotbelow", + "oekorean", + "ogonekcmb", + "ogujarati", + "oharmenian", + "ohiragana", + "ohookabove", "ohorn", + "ohornacute", + "ohorndotbelow", + "ohorngrave", + "ohornhookabove", + "ohorntilde", "ohungarumlaut", + "oi", + "oinvertedbreve", + "okatakana", + "okatakanahalfwidth", + "okorean", + "olehebrew", "omacron", + "omacronacute", + "omacrongrave", + "omdeva", "omega", "omega1", + "omegacyrillic", + "omegalatinclosed", + "omegaroundcyrillic", + "omegatitlocyrillic", "omegatonos", + "omgujarati", "omicron", "omicrontonos", + "omonospace", + "onearabic", + "onebengali", + "onecircle", + "onecircleinversesansserif", + "onedeva", + "onegujarati", + "onegurmukhi", + "onehackarabic", + "onehangzhou", + "oneideographicparen", + "onemonospace", + "onenumeratorbengali", + "oneparen", + "oneperiod", + "onepersian", + "oneroman", + "onethai", + "oogonek", + "oogonekmacron", + "oogurmukhi", + "oomatragurmukhi", + "oopen", + "oparen", "openbullet", + "option", "orthogonal", + "oshortdeva", + "oshortvowelsigndeva", "oslashacute", + "osmallhiragana", + "osmallkatakana", + "osmallkatakanahalfwidth", + "ostrokeacute", + "otcyrillic", + "otildeacute", + "otildedieresis", + "oubopomofo", + "overline", + "overlinecenterline", + "overlinecmb", + "overlinedashed", + "overlinedblwavy", + "overlinewavy", + "overscore", + "ovowelsignbengali", + "ovowelsigndeva", + "ovowelsigngujarati", + "paampssquare", + "paasentosquare", + "pabengali", + "pacute", + "padeva", + "pagedown", + "pageup", + "pagujarati", + "pagurmukhi", + "pahiragana", + "paiyannoithai", + "pakatakana", + "palatalizationcyrilliccmb", + "palochkacyrillic", + "pansioskorean", + "parallel", + "parenleftaltonearabic", "parenleftbt", "parenleftex", + "parenleftmonospace", + "parenleftsmall", "parenlefttp", + "parenleftvertical", + "parenrightaltonearabic", "parenrightbt", "parenrightex", + "parenrightmonospace", + "parenrightsmall", "parenrighttp", + "parenrightvertical", "partialdiff", + "paseqhebrew", + "pashtahebrew", + "pasquare", + "patah", + "patah11", + "patah1d", + "patah2a", + "patahhebrew", + "patahnarrowhebrew", + "patahquarterhebrew", + "patahwidehebrew", + "pazerhebrew", + "pbopomofo", + "pcircle", + "pdotaccent", + "pe", + "pecyrillic", + "pedagesh", + "pedageshhebrew", + "peezisquare", + "pefinaldageshhebrew", + "peharabic", + "peharmenian", + "pehebrew", + "pehfinalarabic", + "pehinitialarabic", + "pehiragana", + "pehmedialarabic", + "pekatakana", + "pemiddlehookcyrillic", + "perafehebrew", + "percentarabic", + "percentmonospace", + "percentsmall", + "periodarmenian", + "periodhalfwidth", + "periodmonospace", + "periodsmall", + "perispomenigreekcmb", "perpendicular", "peseta", + "pfsquare", + "phabengali", + "phadeva", + "phagujarati", + "phagurmukhi", "phi", "phi1", + "phieuphacirclekorean", + "phieuphaparenkorean", + "phieuphcirclekorean", + "phieuphkorean", + "phieuphparenkorean", + "philatin", + "phinthuthai", + "phisymbolgreek", + "phook", + "phophanthai", + "phophungthai", + "phosamphaothai", "pi", + "pieupacirclekorean", + "pieupaparenkorean", + "pieupcieuckorean", + "pieupcirclekorean", + "pieupkiyeokkorean", + "pieupkorean", + "pieupparenkorean", + "pieupsioskiyeokkorean", + "pieupsioskorean", + "pieupsiostikeutkorean", + "pieupthieuthkorean", + "pieuptikeutkorean", + "pihiragana", + "pikatakana", + "pisymbolgreek", + "piwrarmenian", + "plusbelowcmb", + "pluscircle", + "plusmod", + "plusmonospace", + "plussmall", + "plussuperior", + "pmonospace", + "pmsquare", + "pohiragana", + "pointingindexdownwhite", + "pointingindexleftwhite", + "pointingindexrightwhite", + "pointingindexupwhite", + "pokatakana", + "poplathai", + "postalmark", + "postalmarkface", + "pparen", + "precedes", "prescription", + "primemod", + "primereversed", "product", + "projective", + "prolongedkana", + "propellor", "propersubset", "propersuperset", + "proportion", "proportional", "psi", + "psicyrillic", + "psilipneumatacyrilliccmb", + "pssquare", + "puhiragana", + "pukatakana", + "pvsquare", + "pwsquare", + "qadeva", + "qadmahebrew", + "qafarabic", + "qaffinalarabic", + "qafinitialarabic", + "qafmedialarabic", + "qamats", + "qamats10", + "qamats1a", + "qamats1c", + "qamats27", + "qamats29", + "qamats33", + "qamatsde", + "qamatshebrew", + "qamatsnarrowhebrew", + "qamatsqatanhebrew", + "qamatsqatannarrowhebrew", + "qamatsqatanquarterhebrew", + "qamatsqatanwidehebrew", + "qamatsquarterhebrew", + "qamatswidehebrew", + "qarneyparahebrew", + "qbopomofo", + "qcircle", + "qhook", + "qmonospace", + "qof", + "qofdagesh", + "qofdageshhebrew", + "qofhatafpatah", + "qofhatafpatahhebrew", + "qofhatafsegol", + "qofhatafsegolhebrew", + "qofhebrew", + "qofhiriq", + "qofhiriqhebrew", + "qofholam", + "qofholamhebrew", + "qofpatah", + "qofpatahhebrew", + "qofqamats", + "qofqamatshebrew", + "qofqubuts", + "qofqubutshebrew", + "qofsegol", + "qofsegolhebrew", + "qofsheva", + "qofshevahebrew", + "qoftsere", + "qoftserehebrew", + "qparen", + "quarternote", + "qubuts", + "qubuts18", + "qubuts25", + "qubuts31", + "qubutshebrew", + "qubutsnarrowhebrew", + "qubutsquarterhebrew", + "qubutswidehebrew", + "questionarabic", + "questionarmenian", + "questiongreek", + "questionmonospace", + "quotedblmonospace", + "quotedblprime", + "quotedblprimereversed", + "quoteleftreversed", "quotereversed", + "quoterightn", + "quotesinglemonospace", + "raarmenian", + "rabengali", "racute", + "radeva", "radical", "radicalex", + "radoverssquare", + "radoverssquaredsquare", + "radsquare", + "rafe", + "rafehebrew", + "ragujarati", + "ragurmukhi", + "rahiragana", + "rakatakana", + "rakatakanahalfwidth", + "ralowerdiagonalbengali", + "ramiddlediagonalbengali", + "ramshorn", + "ratio", + "rbopomofo", "rcaron", + "rcedilla", + "rcircle", "rcommaaccent", + "rdblgrave", + "rdotaccent", + "rdotbelow", + "rdotbelowmacron", + "referencemark", "reflexsubset", "reflexsuperset", "registersans", "registerserif", + "reharabic", + "reharmenian", + "rehfinalarabic", + "rehiragana", + "rehyehaleflamarabic", + "rekatakana", + "rekatakanahalfwidth", + "resh", + "reshdageshhebrew", + "reshhatafpatah", + "reshhatafpatahhebrew", + "reshhatafsegol", + "reshhatafsegolhebrew", + "reshhebrew", + "reshhiriq", + "reshhiriqhebrew", + "reshholam", + "reshholamhebrew", + "reshpatah", + "reshpatahhebrew", + "reshqamats", + "reshqamatshebrew", + "reshqubuts", + "reshqubutshebrew", + "reshsegol", + "reshsegolhebrew", + "reshsheva", + "reshshevahebrew", + "reshtsere", + "reshtserehebrew", + "reversedtilde", + "reviahebrew", + "reviamugrashhebrew", "revlogicalnot", + "rfishhook", + "rfishhookreversed", + "rhabengali", + "rhadeva", "rho", + "rhook", + "rhookturned", + "rhookturnedsuperior", + "rhosymbolgreek", + "rhotichookmod", + "rieulacirclekorean", + "rieulaparenkorean", + "rieulcirclekorean", + "rieulhieuhkorean", + "rieulkiyeokkorean", + "rieulkiyeoksioskorean", + "rieulkorean", + "rieulmieumkorean", + "rieulpansioskorean", + "rieulparenkorean", + "rieulphieuphkorean", + "rieulpieupkorean", + "rieulpieupsioskorean", + "rieulsioskorean", + "rieulthieuthkorean", + "rieultikeutkorean", + "rieulyeorinhieuhkorean", + "rightangle", + "righttackbelowcmb", + "righttriangle", + "rihiragana", + "rikatakana", + "rikatakanahalfwidth", + "ringbelowcmb", + "ringcmb", + "ringhalfleft", + "ringhalfleftarmenian", + "ringhalfleftbelowcmb", + "ringhalfleftcentered", + "ringhalfright", + "ringhalfrightbelowcmb", + "ringhalfrightcentered", + "rinvertedbreve", + "rittorusquare", + "rlinebelow", + "rlongleg", + "rlonglegturned", + "rmonospace", + "rohiragana", + "rokatakana", + "rokatakanahalfwidth", + "roruathai", + "rparen", + "rrabengali", + "rradeva", + "rragurmukhi", + "rreharabic", + "rrehfinalarabic", + "rrvocalicbengali", + "rrvocalicdeva", + "rrvocalicgujarati", + "rrvocalicvowelsignbengali", + "rrvocalicvowelsigndeva", + "rrvocalicvowelsigngujarati", "rtblock", + "rturned", + "rturnedsuperior", + "ruhiragana", + "rukatakana", + "rukatakanahalfwidth", + "rupeemarkbengali", + "rupeesignbengali", + "ruthai", + "rvocalicbengali", + "rvocalicdeva", + "rvocalicgujarati", + "rvocalicvowelsignbengali", + "rvocalicvowelsigndeva", + "rvocalicvowelsigngujarati", + "sabengali", "sacute", + "sacutedotaccent", + "sadarabic", + "sadeva", + "sadfinalarabic", + "sadinitialarabic", + "sadmedialarabic", + "sagujarati", + "sagurmukhi", + "sahiragana", + "sakatakana", + "sakatakanahalfwidth", + "sallallahoualayhewasallamarabic", + "samekh", + "samekhdagesh", + "samekhdageshhebrew", + "samekhhebrew", + "saraaathai", + "saraaethai", + "saraaimaimalaithai", + "saraaimaimuanthai", + "saraamthai", + "saraathai", + "saraethai", + "saraiileftthai", + "saraiithai", + "saraileftthai", + "saraithai", + "saraothai", + "saraueeleftthai", + "saraueethai", + "saraueleftthai", + "sarauethai", + "sarauthai", + "sarauuthai", + "sbopomofo", + "scarondotaccent", "scedilla", - "scedilla", + "schwa", + "schwacyrillic", + "schwadieresiscyrillic", + "schwahook", + "scircle", "scircumflex", "scommaaccent", + "sdotaccent", + "sdotbelow", + "sdotbelowdotaccent", + "seagullbelowcmb", "second", + "secondtonechinese", + "seenarabic", + "seenfinalarabic", + "seeninitialarabic", + "seenmedialarabic", + "segol", + "segol13", + "segol1f", + "segol2c", + "segolhebrew", + "segolnarrowhebrew", + "segolquarterhebrew", + "segoltahebrew", + "segolwidehebrew", + "seharmenian", + "sehiragana", + "sekatakana", + "sekatakanahalfwidth", + "semicolonarabic", + "semicolonmonospace", + "semicolonsmall", + "semivoicedmarkkana", + "semivoicedmarkkanahalfwidth", + "sentisquare", + "sentosquare", + "sevenarabic", + "sevenbengali", + "sevencircle", + "sevencircleinversesansserif", + "sevendeva", + "sevengujarati", + "sevengurmukhi", + "sevenhackarabic", + "sevenhangzhou", + "sevenideographicparen", + "sevenmonospace", + "sevenparen", + "sevenperiod", + "sevenpersian", + "sevenroman", + "seventeencircle", + "seventeenparen", + "seventeenperiod", + "seventhai", + "sfthyphen", + "shaarmenian", + "shabengali", + "shacyrillic", + "shaddaarabic", + "shaddadammaarabic", + "shaddadammatanarabic", + "shaddafathaarabic", + "shaddafathatanarabic", + "shaddakasraarabic", + "shaddakasratanarabic", "shade", + "shadedark", + "shadelight", + "shademedium", + "shadeva", + "shagujarati", + "shagurmukhi", + "shalshelethebrew", + "shbopomofo", + "shchacyrillic", + "sheenarabic", + "sheenfinalarabic", + "sheeninitialarabic", + "sheenmedialarabic", + "sheicoptic", + "sheqel", + "sheqelhebrew", + "sheva", + "sheva115", + "sheva15", + "sheva22", + "sheva2e", + "shevahebrew", + "shevanarrowhebrew", + "shevaquarterhebrew", + "shevawidehebrew", + "shhacyrillic", + "shimacoptic", + "shin", + "shindagesh", + "shindageshhebrew", + "shindageshshindot", + "shindageshshindothebrew", + "shindageshsindot", + "shindageshsindothebrew", + "shindothebrew", + "shinhebrew", + "shinshindot", + "shinshindothebrew", + "shinsindot", + "shinsindothebrew", + "shook", "sigma", "sigma1", + "sigmafinal", + "sigmalunatesymbolgreek", + "sihiragana", + "sikatakana", + "sikatakanahalfwidth", + "siluqhebrew", + "siluqlefthebrew", "similar", + "sindothebrew", + "siosacirclekorean", + "siosaparenkorean", + "sioscieuckorean", + "sioscirclekorean", + "sioskiyeokkorean", + "sioskorean", + "siosnieunkorean", + "siosparenkorean", + "siospieupkorean", + "siostikeutkorean", + "sixarabic", + "sixbengali", + "sixcircle", + "sixcircleinversesansserif", + "sixdeva", + "sixgujarati", + "sixgurmukhi", + "sixhackarabic", + "sixhangzhou", + "sixideographicparen", + "sixmonospace", + "sixparen", + "sixperiod", + "sixpersian", + "sixroman", + "sixteencircle", + "sixteencurrencydenominatorbengali", + "sixteenparen", + "sixteenperiod", + "sixthai", + "slashmonospace", + "slong", + "slongdotaccent", "smileface", + "smonospace", + "sofpasuqhebrew", + "softhyphen", + "softsigncyrillic", + "sohiragana", + "sokatakana", + "sokatakanahalfwidth", + "soliduslongoverlaycmb", + "solidusshortoverlaycmb", + "sorusithai", + "sosalathai", + "sosothai", + "sosuathai", + "spacehackarabic", "spade", + "spadesuitblack", + "spadesuitwhite", + "sparen", + "squarebelowcmb", + "squarecc", + "squarecm", + "squarediagonalcrosshatchfill", + "squarehorizontalfill", + "squarekg", + "squarekm", + "squarekmcapital", + "squareln", + "squarelog", + "squaremg", + "squaremil", + "squaremm", + "squaremsquared", + "squareorthogonalcrosshatchfill", + "squareupperlefttolowerrightfill", + "squareupperrighttolowerleftfill", + "squareverticalfill", + "squarewhitewithsmallblack", + "srsquare", + "ssabengali", + "ssadeva", + "ssagujarati", + "ssangcieuckorean", + "ssanghieuhkorean", + "ssangieungkorean", + "ssangkiyeokkorean", + "ssangnieunkorean", + "ssangpieupkorean", + "ssangsioskorean", + "ssangtikeutkorean", + "sterlingmonospace", + "strokelongoverlaycmb", + "strokeshortoverlaycmb", + "subset", + "subsetnotequal", + "subsetorequal", + "succeeds", "suchthat", + "suhiragana", + "sukatakana", + "sukatakanahalfwidth", + "sukunarabic", "summation", "sun", + "superset", + "supersetnotequal", + "supersetorequal", + "svsquare", + "syouwaerasquare", + "tabengali", + "tackdown", + "tackleft", + "tadeva", + "tagujarati", + "tagurmukhi", + "taharabic", + "tahfinalarabic", + "tahinitialarabic", + "tahiragana", + "tahmedialarabic", + "taisyouerasquare", + "takatakana", + "takatakanahalfwidth", + "tatweelarabic", "tau", + "tav", + "tavdages", + "tavdagesh", + "tavdageshhebrew", + "tavhebrew", "tbar", + "tbopomofo", "tcaron", + "tccurl", + "tcedilla", + "tcheharabic", + "tchehfinalarabic", + "tchehinitialarabic", + "tchehmedialarabic", + "tchehmeeminitialarabic", + "tcircle", + "tcircumflexbelow", "tcommaaccent", - "tcommaaccent", + "tdieresis", + "tdotaccent", + "tdotbelow", + "tecyrillic", + "tedescendercyrillic", + "teharabic", + "tehfinalarabic", + "tehhahinitialarabic", + "tehhahisolatedarabic", + "tehinitialarabic", + "tehiragana", + "tehjeeminitialarabic", + "tehjeemisolatedarabic", + "tehmarbutaarabic", + "tehmarbutafinalarabic", + "tehmedialarabic", + "tehmeeminitialarabic", + "tehmeemisolatedarabic", + "tehnoonfinalarabic", + "tekatakana", + "tekatakanahalfwidth", + "telephone", + "telephoneblack", + "telishagedolahebrew", + "telishaqetanahebrew", + "tencircle", + "tenideographicparen", + "tenparen", + "tenperiod", + "tenroman", + "tesh", + "tet", + "tetdagesh", + "tetdageshhebrew", + "tethebrew", + "tetsecyrillic", + "tevirhebrew", + "tevirlefthebrew", + "thabengali", + "thadeva", + "thagujarati", + "thagurmukhi", + "thalarabic", + "thalfinalarabic", + "thanthakhatlowleftthai", + "thanthakhatlowrightthai", + "thanthakhatthai", + "thanthakhatupperleftthai", + "theharabic", + "thehfinalarabic", + "thehinitialarabic", + "thehmedialarabic", + "thereexists", "therefore", "theta", "theta1", + "thetasymbolgreek", + "thieuthacirclekorean", + "thieuthaparenkorean", + "thieuthcirclekorean", + "thieuthkorean", + "thieuthparenkorean", + "thirteencircle", + "thirteenparen", + "thirteenperiod", + "thonangmonthothai", + "thook", + "thophuthaothai", + "thothahanthai", + "thothanthai", + "thothongthai", + "thothungthai", + "thousandcyrillic", + "thousandsseparatorarabic", + "thousandsseparatorpersian", + "threearabic", + "threebengali", + "threecircle", + "threecircleinversesansserif", + "threedeva", + "threegujarati", + "threegurmukhi", + "threehackarabic", + "threehangzhou", + "threeideographicparen", + "threemonospace", + "threenumeratorbengali", + "threeparen", + "threeperiod", + "threepersian", + "threeroman", + "threethai", + "thzsquare", + "tihiragana", + "tikatakana", + "tikatakanahalfwidth", + "tikeutacirclekorean", + "tikeutaparenkorean", + "tikeutcirclekorean", + "tikeutkorean", + "tikeutparenkorean", + "tildebelowcmb", + "tildecmb", "tildecomb", + "tildedoublecmb", + "tildeoperator", + "tildeoverlaycmb", + "tildeverticalcmb", + "timescircle", + "tipehahebrew", + "tipehalefthebrew", + "tippigurmukhi", + "titlocyrilliccmb", + "tiwnarmenian", + "tlinebelow", + "tmonospace", + "toarmenian", + "tohiragana", + "tokatakana", + "tokatakanahalfwidth", + "tonebarextrahighmod", + "tonebarextralowmod", + "tonebarhighmod", + "tonebarlowmod", + "tonebarmidmod", + "tonefive", + "tonesix", + "tonetwo", "tonos", + "tonsquare", + "topatakthai", + "tortoiseshellbracketleft", + "tortoiseshellbracketleftsmall", + "tortoiseshellbracketleftvertical", + "tortoiseshellbracketright", + "tortoiseshellbracketrightsmall", + "tortoiseshellbracketrightvertical", + "totaothai", + "tpalatalhook", + "tparen", "trademarksans", "trademarkserif", + "tretroflexhook", "triagdn", "triaglf", "triagrt", "triagup", + "ts", + "tsadi", + "tsadidagesh", + "tsadidageshhebrew", + "tsadihebrew", + "tsecyrillic", + "tsere", + "tsere12", + "tsere1e", + "tsere2b", + "tserehebrew", + "tserenarrowhebrew", + "tserequarterhebrew", + "tserewidehebrew", + "tshecyrillic", + "ttabengali", + "ttadeva", + "ttagujarati", + "ttagurmukhi", + "tteharabic", + "ttehfinalarabic", + "ttehinitialarabic", + "ttehmedialarabic", + "tthabengali", + "tthadeva", + "tthagujarati", + "tthagurmukhi", + "tturned", + "tuhiragana", + "tukatakana", + "tukatakanahalfwidth", + "tusmallhiragana", + "tusmallkatakana", + "tusmallkatakanahalfwidth", + "twelvecircle", + "twelveparen", + "twelveperiod", + "twelveroman", + "twentycircle", + "twentyhangzhou", + "twentyparen", + "twentyperiod", + "twoarabic", + "twobengali", + "twocircle", + "twocircleinversesansserif", + "twodeva", + "twodotleader", + "twodotleadervertical", + "twogujarati", + "twogurmukhi", + "twohackarabic", + "twohangzhou", + "twoideographicparen", + "twomonospace", + "twonumeratorbengali", + "twoparen", + "twoperiod", + "twopersian", + "tworoman", + "twostroke", + "twothai", + "ubar", + "ubengali", + "ubopomofo", "ubreve", + "ucaron", + "ucircle", + "ucircumflexbelow", + "ucyrillic", + "udattadeva", + "udblacute", + "udblgrave", + "udeva", + "udieresisacute", + "udieresisbelow", + "udieresiscaron", + "udieresiscyrillic", + "udieresisgrave", + "udieresismacron", + "udotbelow", + "ugujarati", + "ugurmukhi", + "uhiragana", + "uhookabove", "uhorn", + "uhornacute", + "uhorndotbelow", + "uhorngrave", + "uhornhookabove", + "uhorntilde", "uhungarumlaut", + "uhungarumlautcyrillic", + "uinvertedbreve", + "ukatakana", + "ukatakanahalfwidth", + "ukcyrillic", + "ukorean", "umacron", + "umacroncyrillic", + "umacrondieresis", + "umatragurmukhi", + "umonospace", "underscoredbl", + "underscoremonospace", + "underscorevertical", + "underscorewavy", "union", "universal", "uogonek", + "uparen", "upblock", + "upperdothebrew", "upsilon", "upsilondieresis", "upsilondieresistonos", + "upsilonlatin", "upsilontonos", + "uptackbelowcmb", + "uptackmod", + "uragurmukhi", "uring", + "ushortcyrillic", + "usmallhiragana", + "usmallkatakana", + "usmallkatakanahalfwidth", + "ustraightcyrillic", + "ustraightstrokecyrillic", "utilde", + "utildeacute", + "utildebelow", + "uubengali", + "uudeva", + "uugujarati", + "uugurmukhi", + "uumatragurmukhi", + "uuvowelsignbengali", + "uuvowelsigndeva", + "uuvowelsigngujarati", + "uvowelsignbengali", + "uvowelsigndeva", + "uvowelsigngujarati", + "vadeva", + "vagujarati", + "vagurmukhi", + "vakatakana", + "vav", + "vavdagesh", + "vavdagesh65", + "vavdageshhebrew", + "vavhebrew", + "vavholam", + "vavholamhebrew", + "vavvavhebrew", + "vavyodhebrew", + "vcircle", + "vdotbelow", + "vecyrillic", + "veharabic", + "vehfinalarabic", + "vehinitialarabic", + "vehmedialarabic", + "vekatakana", + "venus", + "verticalbar", + "verticallineabovecmb", + "verticallinebelowcmb", + "verticallinelowmod", + "verticallinemod", + "vewarmenian", + "vhook", + "vikatakana", + "viramabengali", + "viramadeva", + "viramagujarati", + "visargabengali", + "visargadeva", + "visargagujarati", + "vmonospace", + "voarmenian", + "voicediterationhiragana", + "voicediterationkatakana", + "voicedmarkkana", + "voicedmarkkanahalfwidth", + "vokatakana", + "vparen", + "vtilde", + "vturned", + "vuhiragana", + "vukatakana", "wacute", + "waekorean", + "wahiragana", + "wakatakana", + "wakatakanahalfwidth", + "wakorean", + "wasmallhiragana", + "wasmallkatakana", + "wattosquare", + "wavedash", + "wavyunderscorevertical", + "wawarabic", + "wawfinalarabic", + "wawhamzaabovearabic", + "wawhamzaabovefinalarabic", + "wbsquare", + "wcircle", "wcircumflex", "wdieresis", + "wdotaccent", + "wdotbelow", + "wehiragana", "weierstrass", + "wekatakana", + "wekorean", + "weokorean", "wgrave", + "whitebullet", + "whitecircle", + "whitecircleinverse", + "whitecornerbracketleft", + "whitecornerbracketleftvertical", + "whitecornerbracketright", + "whitecornerbracketrightvertical", + "whitediamond", + "whitediamondcontainingblacksmalldiamond", + "whitedownpointingsmalltriangle", + "whitedownpointingtriangle", + "whiteleftpointingsmalltriangle", + "whiteleftpointingtriangle", + "whitelenticularbracketleft", + "whitelenticularbracketright", + "whiterightpointingsmalltriangle", + "whiterightpointingtriangle", + "whitesmallsquare", + "whitesmilingface", + "whitesquare", + "whitestar", + "whitetelephone", + "whitetortoiseshellbracketleft", + "whitetortoiseshellbracketright", + "whiteuppointingsmalltriangle", + "whiteuppointingtriangle", + "wihiragana", + "wikatakana", + "wikorean", + "wmonospace", + "wohiragana", + "wokatakana", + "wokatakanahalfwidth", + "won", + "wonmonospace", + "wowaenthai", + "wparen", + "wring", + "wsuperior", + "wturned", + "wynn", + "xabovecmb", + "xbopomofo", + "xcircle", + "xdieresis", + "xdotaccent", + "xeharmenian", "xi", + "xmonospace", + "xparen", + "xsuperior", + "yaadosquare", + "yabengali", + "yadeva", + "yaekorean", + "yagujarati", + "yagurmukhi", + "yahiragana", + "yakatakana", + "yakatakanahalfwidth", + "yakorean", + "yamakkanthai", + "yasmallhiragana", + "yasmallkatakana", + "yasmallkatakanahalfwidth", + "yatcyrillic", + "ycircle", "ycircumflex", + "ydotaccent", + "ydotbelow", + "yeharabic", + "yehbarreearabic", + "yehbarreefinalarabic", + "yehfinalarabic", + "yehhamzaabovearabic", + "yehhamzaabovefinalarabic", + "yehhamzaaboveinitialarabic", + "yehhamzaabovemedialarabic", + "yehinitialarabic", + "yehmedialarabic", + "yehmeeminitialarabic", + "yehmeemisolatedarabic", + "yehnoonfinalarabic", + "yehthreedotsbelowarabic", + "yekorean", + "yenmonospace", + "yeokorean", + "yeorinhieuhkorean", + "yerahbenyomohebrew", + "yerahbenyomolefthebrew", + "yericyrillic", + "yerudieresiscyrillic", + "yesieungkorean", + "yesieungpansioskorean", + "yesieungsioskorean", + "yetivhebrew", "ygrave", + "yhook", + "yhookabove", + "yiarmenian", + "yicyrillic", + "yikorean", + "yinyang", + "yiwnarmenian", + "ymonospace", + "yod", + "yoddagesh", + "yoddageshhebrew", + "yodhebrew", + "yodyodhebrew", + "yodyodpatahhebrew", + "yohiragana", + "yoikorean", + "yokatakana", + "yokatakanahalfwidth", + "yokorean", + "yosmallhiragana", + "yosmallkatakana", + "yosmallkatakanahalfwidth", + "yotgreek", + "yoyaekorean", + "yoyakorean", + "yoyakthai", + "yoyingthai", + "yparen", + "ypogegrammeni", + "ypogegrammenigreekcmb", + "yr", + "yring", + "ysuperior", + "ytilde", + "yturned", + "yuhiragana", + "yuikorean", + "yukatakana", + "yukatakanahalfwidth", + "yukorean", + "yusbigcyrillic", + "yusbigiotifiedcyrillic", + "yuslittlecyrillic", + "yuslittleiotifiedcyrillic", + "yusmallhiragana", + "yusmallkatakana", + "yusmallkatakanahalfwidth", + "yuyekorean", + "yuyeokorean", + "yyabengali", + "yyadeva", + "zaarmenian", "zacute", + "zadeva", + "zagurmukhi", + "zaharabic", + "zahfinalarabic", + "zahinitialarabic", + "zahiragana", + "zahmedialarabic", + "zainarabic", + "zainfinalarabic", + "zakatakana", + "zaqefgadolhebrew", + "zaqefqatanhebrew", + "zarqahebrew", + "zayin", + "zayindagesh", + "zayindageshhebrew", + "zayinhebrew", + "zbopomofo", + "zcircle", + "zcircumflex", + "zcurl", + "zdot", "zdotaccent", + "zdotbelow", + "zecyrillic", + "zedescendercyrillic", + "zedieresiscyrillic", + "zehiragana", + "zekatakana", + "zeroarabic", + "zerobengali", + "zerodeva", + "zerogujarati", + "zerogurmukhi", + "zerohackarabic", + "zeromonospace", + "zeropersian", + "zerothai", + "zerowidthjoiner", + "zerowidthnonjoiner", + "zerowidthspace", "zeta", + "zhbopomofo", + "zhearmenian", + "zhebrevecyrillic", + "zhecyrillic", + "zhedescendercyrillic", + "zhedieresiscyrillic", + "zihiragana", + "zikatakana", + "zinorhebrew", + "zlinebelow", + "zmonospace", + "zohiragana", + "zokatakana", + "zparen", + "zretroflexhook", + "zstroke", + "zuhiragana", + "zukatakana", #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ @@ -1093,13 +4327,13 @@ }; - static const char* const * const sid_standard_names = ps_glyph_names + 4; + static const char* const * const sid_standard_names = ps_glyph_names + 2; #define NUM_SID_GLYPHS 391 #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST -#define NUM_ADOBE_GLYPHS 1058 +#define NUM_ADOBE_GLYPHS 4294 #else #define NUM_ADOBE_GLYPHS 391 #endif @@ -1107,17 +4341,19 @@ static const unsigned short mac_standard_names[259] = { - 4, + 2, 0, 1, + 3, + 4, 5, 6, 7, 8, 9, - 10, + 106, 11, - 108, + 12, 13, 14, 15, @@ -1172,9 +4408,9 @@ 64, 65, 66, - 67, + 126, 68, - 128, + 69, 70, 71, 72, @@ -1203,554 +4439,552 @@ 95, 96, 97, - 98, - 99, + 175, 177, 179, - 181, - 182, - 190, - 193, - 199, + 180, + 188, + 191, + 197, + 202, + 205, + 203, 204, 207, - 205, 206, - 209, 208, + 209, + 212, 210, 211, - 214, - 212, 213, - 215, - 218, 216, + 214, + 215, 217, + 218, + 221, 219, 220, - 223, - 221, 222, 224, - 226, - 229, 227, - 228, - 116, - 165, - 101, - 102, - 106, - 120, - 119, - 153, - 169, - 174, - 157, - 129, - 135, - 959, - 142, - 145, - 917, - 160, - 941, - 908, - 104, - 156, - 980, - 1018, - 987, - 985, - 918, - 143, - 147, - 471, - 148, - 151, - 127, - 100, - 155, - 994, - 105, - 815, - 412, - 110, - 124, - 125, - 2, - 178, - 180, - 195, - 146, - 152, - 115, - 141, - 109, - 123, - 69, - 12, + 225, + 226, + 114, 163, - 948, - 231, - 202, + 99, + 100, + 104, + 118, + 117, + 151, + 167, + 172, + 155, + 127, + 133, + 2919, + 140, + 143, + 2413, + 158, + 2642, + 2156, + 102, + 154, + 3092, + 3681, + 3192, + 3153, + 2415, + 141, + 145, + 741, + 146, + 149, + 125, + 98, + 153, + 3284, 103, + 1353, + 472, + 108, + 122, + 123, + 2901, + 176, + 178, + 193, + 144, + 150, + 113, + 139, 107, + 121, + 67, + 10, + 161, + 2677, + 229, + 200, + 101, + 105, + 109, + 110, 111, 112, - 113, - 114, - 117, - 118, - 121, - 122, - 126, - 176, + 115, + 116, + 119, + 120, + 124, + 174, + 181, + 173, + 182, 183, - 175, 184, 185, 186, 187, - 188, 189, - 191, + 190, + 1351, 192, - 3, - 194, - 197, + 195, + 196, 198, - 200, - 149, + 147, + 128, + 129, 130, 131, 132, - 133, 134, + 135, 136, 137, 138, - 139, - 140, - 144, - 150, - 196, - 225, - 203, - 232, - 164, - 158, - 171, + 142, + 148, + 194, + 223, 201, 230, - 161, - 166, - 170, - 172, - 154, - 168, - 173, - 159, 162, - 167, - 899, - 429, - 901, - 444, - 526, - 1006, - 404, - 847, - 406, - 849, - 868, + 156, + 169, + 199, + 228, + 159, + 164, + 168, + 170, + 152, + 166, + 171, + 157, + 160, + 165, + 2074, + 556, + 2091, + 609, + 836, + 3465, + 438, + 1545, + 440, + 1560, + 1767, 0 }; - static const unsigned short ps_names_to_unicode[1059] = + static const unsigned short ps_names_to_unicode[4295] = { 0, - 0x0020, - 0x0021, - 0x0022, - 0x0023, - 0x0024, - 0x0025, - 0x0026, - 0x2019, - 0x0028, - 0x0029, - 0x002A, - 0x002B, - 0x002C, - 0x002D, - 0x002E, - 0x002F, - 0x0030, - 0x0031, - 0x0032, - 0x0033, - 0x0034, - 0x0035, - 0x0036, - 0x0037, - 0x0038, - 0x0039, - 0x003A, - 0x003B, - 0x003C, - 0x003D, - 0x003E, - 0x003F, - 0x0040, - 0x0041, - 0x0042, - 0x0043, - 0x0044, - 0x0045, - 0x0046, - 0x0047, - 0x0048, - 0x0049, - 0x004A, - 0x004B, - 0x004C, - 0x004D, - 0x004E, - 0x004F, - 0x0050, - 0x0051, - 0x0052, - 0x0053, - 0x0054, - 0x0055, - 0x0056, - 0x0057, - 0x0058, - 0x0059, - 0x005A, - 0x005B, - 0x005C, - 0x005D, - 0x005E, - 0x005F, - 0x2018, - 0x0061, - 0x0062, - 0x0063, - 0x0064, - 0x0065, - 0x0066, - 0x0067, - 0x0068, - 0x0069, - 0x006A, - 0x006B, - 0x006C, - 0x006D, - 0x006E, - 0x006F, - 0x0070, - 0x0071, - 0x0072, - 0x0073, - 0x0074, - 0x0075, - 0x0076, - 0x0077, - 0x0078, - 0x0079, - 0x007A, - 0x007B, - 0x007C, - 0x007D, - 0x007E, - 0x00A1, - 0x00A2, - 0x00A3, - 0x2044, - 0x00A5, - 0x0192, - 0x00A7, - 0x00A4, - 0x0027, - 0x201C, - 0x00AB, - 0x2039, - 0x203A, - 0xFB01, - 0xFB02, - 0x2013, - 0x2020, - 0x2021, - 0x00B7, - 0x00B6, - 0x2022, - 0x201A, - 0x201E, - 0x201D, - 0x00BB, - 0x2026, - 0x2030, - 0x00BF, - 0x0060, - 0x00B4, - 0x02C6, - 0x02DC, - 0x00AF, - 0x02D8, - 0x02D9, - 0x00A8, - 0x02DA, - 0x00B8, - 0x02DD, - 0x02DB, - 0x02C7, - 0x2014, - 0x00C6, - 0x00AA, - 0x0141, - 0x00D8, - 0x0152, - 0x00BA, - 0x00E6, - 0x0131, - 0x0142, - 0x00F8, - 0x0153, - 0x00DF, - 0x00B9, - 0x00AC, - 0x00B5, - 0x2122, - 0x00D0, - 0x00BD, - 0x00B1, - 0x00DE, - 0x00BC, - 0x00F7, - 0x00A6, - 0x00B0, - 0x00FE, - 0x00BE, - 0x00B2, - 0x00AE, - 0x2212, - 0x00F0, - 0x00D7, - 0x00B3, - 0x00A9, - 0x00C1, - 0x00C2, - 0x00C4, - 0x00C0, - 0x00C5, - 0x00C3, - 0x00C7, - 0x00C9, - 0x00CA, - 0x00CB, - 0x00C8, - 0x00CD, - 0x00CE, - 0x00CF, - 0x00CC, - 0x00D1, - 0x00D3, - 0x00D4, - 0x00D6, - 0x00D2, - 0x00D5, - 0x0160, - 0x00DA, - 0x00DB, - 0x00DC, - 0x00D9, - 0x00DD, - 0x0178, - 0x017D, - 0x00E1, - 0x00E2, - 0x00E4, - 0x00E0, - 0x00E5, - 0x00E3, - 0x00E7, - 0x00E9, - 0x00EA, - 0x00EB, - 0x00E8, - 0x00ED, - 0x00EE, - 0x00EF, - 0x00EC, - 0x00F1, - 0x00F3, - 0x00F4, - 0x00F6, - 0x00F2, - 0x00F5, - 0x0161, - 0x00FA, - 0x00FB, - 0x00FC, - 0x00F9, - 0x00FD, - 0x00FF, - 0x017E, - 0xF721, - 0xF6F8, - 0xF724, - 0xF6E4, - 0xF726, - 0xF7B4, - 0x207D, - 0x207E, - 0x2025, - 0x2024, - 0xF730, - 0xF731, - 0xF732, - 0xF733, - 0xF734, - 0xF735, - 0xF736, - 0xF737, - 0xF738, - 0xF739, - 0xF6E2, - 0xF6DE, - 0xF6E8, - 0xF73F, - 0xF6E9, - 0xF6EA, - 0xF6E0, - 0xF6EB, - 0xF6EC, - 0xF6ED, - 0xF6EE, - 0xF6EF, - 0x207F, - 0xF6F0, - 0xF6F1, - 0xF6F2, - 0xF6F3, - 0xFB00, - 0xFB03, - 0xFB04, - 0x208D, - 0x208E, - 0xF6F6, - 0xF6E6, - 0xF760, - 0xF761, - 0xF762, - 0xF763, - 0xF764, - 0xF765, - 0xF766, - 0xF767, - 0xF768, - 0xF769, - 0xF76A, - 0xF76B, - 0xF76C, - 0xF76D, - 0xF76E, - 0xF76F, - 0xF770, - 0xF771, - 0xF772, - 0xF773, - 0xF774, - 0xF775, - 0xF776, - 0xF777, - 0xF778, - 0xF779, - 0xF77A, - 0x20A1, - 0xF6DC, - 0xF6DD, - 0xF6FE, - 0xF7A1, - 0xF7A2, - 0xF6F9, - 0xF6FD, - 0xF6FF, - 0xF7A8, - 0xF6F4, - 0xF6F5, - 0xF6F7, - 0xF7AF, - 0x2012, - 0xF6E5, - 0xF6FB, - 0xF6FC, - 0xF7B8, - 0xF7BF, - 0x215B, - 0x215C, - 0x215D, - 0x215E, - 0x2153, - 0x2154, - 0x2070, - 0x2074, - 0x2075, - 0x2076, - 0x2077, - 0x2078, - 0x2079, - 0x2080, - 0x2081, - 0x2082, - 0x2083, - 0x2084, - 0x2085, - 0x2086, - 0x2087, - 0x2088, - 0x2089, - 0xF6DF, - 0xF6E3, - 0xF6E7, - 0xF6E1, - 0xF7E0, - 0xF7E1, - 0xF7E2, - 0xF7E3, - 0xF7E4, - 0xF7E5, - 0xF7E6, - 0xF7E7, - 0xF7E8, - 0xF7E9, - 0xF7EA, - 0xF7EB, - 0xF7EC, - 0xF7ED, - 0xF7EE, - 0xF7EF, - 0xF7F0, - 0xF7F1, - 0xF7F2, - 0xF7F3, - 0xF7F4, - 0xF7F5, - 0xF7F6, - 0xF6FA, - 0xF7F8, - 0xF7F9, - 0xF7FA, - 0xF7FB, - 0xF7FC, - 0xF7FD, - 0xF7FE, - 0xF7FF, + 0x0020U, + 0x0021U, + 0x0022U, + 0x0023U, + 0x0024U, + 0x0025U, + 0x0026U, + 0x2019U, + 0x0028U, + 0x0029U, + 0x002AU, + 0x002BU, + 0x002CU, + 0x002DU, + 0x002EU, + 0x002FU, + 0x0030U, + 0x0031U, + 0x0032U, + 0x0033U, + 0x0034U, + 0x0035U, + 0x0036U, + 0x0037U, + 0x0038U, + 0x0039U, + 0x003AU, + 0x003BU, + 0x003CU, + 0x003DU, + 0x003EU, + 0x003FU, + 0x0040U, + 0x0041U, + 0x0042U, + 0x0043U, + 0x0044U, + 0x0045U, + 0x0046U, + 0x0047U, + 0x0048U, + 0x0049U, + 0x004AU, + 0x004BU, + 0x004CU, + 0x004DU, + 0x004EU, + 0x004FU, + 0x0050U, + 0x0051U, + 0x0052U, + 0x0053U, + 0x0054U, + 0x0055U, + 0x0056U, + 0x0057U, + 0x0058U, + 0x0059U, + 0x005AU, + 0x005BU, + 0x005CU, + 0x005DU, + 0x005EU, + 0x005FU, + 0x2018U, + 0x0061U, + 0x0062U, + 0x0063U, + 0x0064U, + 0x0065U, + 0x0066U, + 0x0067U, + 0x0068U, + 0x0069U, + 0x006AU, + 0x006BU, + 0x006CU, + 0x006DU, + 0x006EU, + 0x006FU, + 0x0070U, + 0x0071U, + 0x0072U, + 0x0073U, + 0x0074U, + 0x0075U, + 0x0076U, + 0x0077U, + 0x0078U, + 0x0079U, + 0x007AU, + 0x007BU, + 0x007CU, + 0x007DU, + 0x007EU, + 0x00A1U, + 0x00A2U, + 0x00A3U, + 0x2044U, + 0x00A5U, + 0x0192U, + 0x00A7U, + 0x00A4U, + 0x0027U, + 0x201CU, + 0x00ABU, + 0x2039U, + 0x203AU, + 0xFB01U, + 0xFB02U, + 0x2013U, + 0x2020U, + 0x2021U, + 0x00B7U, + 0x00B6U, + 0x2022U, + 0x201AU, + 0x201EU, + 0x201DU, + 0x00BBU, + 0x2026U, + 0x2030U, + 0x00BFU, + 0x0060U, + 0x00B4U, + 0x02C6U, + 0x02DCU, + 0x00AFU, + 0x02D8U, + 0x02D9U, + 0x00A8U, + 0x02DAU, + 0x00B8U, + 0x02DDU, + 0x02DBU, + 0x02C7U, + 0x2014U, + 0x00C6U, + 0x00AAU, + 0x0141U, + 0x00D8U, + 0x0152U, + 0x00BAU, + 0x00E6U, + 0x0131U, + 0x0142U, + 0x00F8U, + 0x0153U, + 0x00DFU, + 0x00B9U, + 0x00ACU, + 0x00B5U, + 0x2122U, + 0x00D0U, + 0x00BDU, + 0x00B1U, + 0x00DEU, + 0x00BCU, + 0x00F7U, + 0x00A6U, + 0x00B0U, + 0x00FEU, + 0x00BEU, + 0x00B2U, + 0x00AEU, + 0x2212U, + 0x00F0U, + 0x00D7U, + 0x00B3U, + 0x00A9U, + 0x00C1U, + 0x00C2U, + 0x00C4U, + 0x00C0U, + 0x00C5U, + 0x00C3U, + 0x00C7U, + 0x00C9U, + 0x00CAU, + 0x00CBU, + 0x00C8U, + 0x00CDU, + 0x00CEU, + 0x00CFU, + 0x00CCU, + 0x00D1U, + 0x00D3U, + 0x00D4U, + 0x00D6U, + 0x00D2U, + 0x00D5U, + 0x0160U, + 0x00DAU, + 0x00DBU, + 0x00DCU, + 0x00D9U, + 0x00DDU, + 0x0178U, + 0x017DU, + 0x00E1U, + 0x00E2U, + 0x00E4U, + 0x00E0U, + 0x00E5U, + 0x00E3U, + 0x00E7U, + 0x00E9U, + 0x00EAU, + 0x00EBU, + 0x00E8U, + 0x00EDU, + 0x00EEU, + 0x00EFU, + 0x00ECU, + 0x00F1U, + 0x00F3U, + 0x00F4U, + 0x00F6U, + 0x00F2U, + 0x00F5U, + 0x0161U, + 0x00FAU, + 0x00FBU, + 0x00FCU, + 0x00F9U, + 0x00FDU, + 0x00FFU, + 0x017EU, + 0xF721U, + 0xF6F8U, + 0xF724U, + 0xF6E4U, + 0xF726U, + 0xF7B4U, + 0x207DU, + 0x207EU, + 0x2025U, + 0x2024U, + 0xF730U, + 0xF731U, + 0xF732U, + 0xF733U, + 0xF734U, + 0xF735U, + 0xF736U, + 0xF737U, + 0xF738U, + 0xF739U, + 0xF6E2U, + 0xF6DEU, + 0xF6E8U, + 0xF73FU, + 0xF6E9U, + 0xF6EAU, + 0xF6E0U, + 0xF6EBU, + 0xF6ECU, + 0xF6EDU, + 0xF6EEU, + 0xF6EFU, + 0x207FU, + 0xF6F0U, + 0xF6F1U, + 0xF6F2U, + 0xF6F3U, + 0xFB00U, + 0xFB03U, + 0xFB04U, + 0x208DU, + 0x208EU, + 0xF6F6U, + 0xF6E6U, + 0xF760U, + 0xF761U, + 0xF762U, + 0xF763U, + 0xF764U, + 0xF765U, + 0xF766U, + 0xF767U, + 0xF768U, + 0xF769U, + 0xF76AU, + 0xF76BU, + 0xF76CU, + 0xF76DU, + 0xF76EU, + 0xF76FU, + 0xF770U, + 0xF771U, + 0xF772U, + 0xF773U, + 0xF774U, + 0xF775U, + 0xF776U, + 0xF777U, + 0xF778U, + 0xF779U, + 0xF77AU, + 0x20A1U, + 0xF6DCU, + 0xF6DDU, + 0xF6FEU, + 0xF7A1U, + 0xF7A2U, + 0xF6F9U, + 0xF6FDU, + 0xF6FFU, + 0xF7A8U, + 0xF6F4U, + 0xF6F5U, + 0xF6F7U, + 0xF7AFU, + 0x2012U, + 0xF6E5U, + 0xF6FBU, + 0xF6FCU, + 0xF7B8U, + 0xF7BFU, + 0x215BU, + 0x215CU, + 0x215DU, + 0x215EU, + 0x2153U, + 0x2154U, + 0x2070U, + 0x2074U, + 0x2075U, + 0x2076U, + 0x2077U, + 0x2078U, + 0x2079U, + 0x2080U, + 0x2081U, + 0x2082U, + 0x2083U, + 0x2084U, + 0x2085U, + 0x2086U, + 0x2087U, + 0x2088U, + 0x2089U, + 0xF6DFU, + 0xF6E3U, + 0xF6E7U, + 0xF6E1U, + 0xF7E0U, + 0xF7E1U, + 0xF7E2U, + 0xF7E3U, + 0xF7E4U, + 0xF7E5U, + 0xF7E6U, + 0xF7E7U, + 0xF7E8U, + 0xF7E9U, + 0xF7EAU, + 0xF7EBU, + 0xF7ECU, + 0xF7EDU, + 0xF7EEU, + 0xF7EFU, + 0xF7F0U, + 0xF7F1U, + 0xF7F2U, + 0xF7F3U, + 0xF7F4U, + 0xF7F5U, + 0xF7F6U, + 0xF6FAU, + 0xF7F8U, + 0xF7F9U, + 0xF7FAU, + 0xF7FBU, + 0xF7FCU, + 0xF7FDU, + 0xF7FEU, + 0xF7FFU, 0, 0, 0, @@ -1766,673 +5000,3909 @@ #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - 0x01FC, - 0x0102, - 0xF6C9, - 0x0391, - 0x0386, - 0x0100, - 0x0104, - 0x01FA, - 0x0392, - 0x0106, - 0xF6CA, - 0x010C, - 0x0108, - 0x010A, - 0x03A7, - 0x010E, - 0x0110, - 0x2206, - 0x2206, - 0xF6CB, - 0xF6CC, - 0xF6CD, - 0x0114, - 0x011A, - 0x0116, - 0x0112, - 0x014A, - 0x0118, - 0x0395, - 0x0388, - 0x0397, - 0x0389, - 0x20AC, - 0x0393, - 0x011E, - 0x01E6, - 0x011C, - 0x0122, - 0x0120, - 0xF6CE, - 0x25CF, - 0x25AA, - 0x25AB, - 0x25A1, - 0x0126, - 0x0124, - 0xF6CF, - 0x0132, - 0x012C, - 0x0130, - 0x2111, - 0x012A, - 0x012E, - 0x0399, - 0x03AA, - 0x038A, - 0x0128, - 0x0134, - 0x039A, - 0x0136, - 0xF6BF, - 0x0139, - 0x039B, - 0x013D, - 0x013B, - 0x013F, - 0xF6D0, - 0x039C, - 0x0143, - 0x0147, - 0x0145, - 0x039D, - 0x014E, - 0x01A0, - 0x0150, - 0x014C, - 0x2126, - 0x2126, - 0x038F, - 0x039F, - 0x038C, - 0x01FE, - 0x03A6, - 0x03A0, - 0x03A8, - 0x0154, - 0x0158, - 0x0156, - 0x211C, - 0x03A1, - 0x250C, - 0x2514, - 0x2510, - 0x2518, - 0x253C, - 0x252C, - 0x2534, - 0x251C, - 0x2524, - 0x2500, - 0x2502, - 0x2561, - 0x2562, - 0x2556, - 0x2555, - 0x2563, - 0x2551, - 0x2557, - 0x255D, - 0x255C, - 0x255B, - 0x255E, - 0x255F, - 0x255A, - 0x2554, - 0x2569, - 0x2566, - 0x2560, - 0x2550, - 0x256C, - 0x2567, - 0x2568, - 0x2564, - 0x2565, - 0x2559, - 0x2558, - 0x2552, - 0x2553, - 0x256B, - 0x256A, - 0x015A, - 0x015E, - 0x015E, - 0x015C, - 0x0218, - 0x03A3, - 0x03A4, - 0x0166, - 0x0164, - 0x0162, - 0x0162, - 0x0398, - 0x016C, - 0x01AF, - 0x0170, - 0x016A, - 0x0172, - 0x03A5, - 0x03D2, - 0x03AB, - 0x038E, - 0x016E, - 0x0168, - 0x1E82, - 0x0174, - 0x1E84, - 0x1E80, - 0x039E, - 0x0176, - 0x1EF2, - 0x0179, - 0x017B, - 0x0396, - 0x0103, - 0x0301, - 0x01FD, - 0x2015, - 0x0410, - 0x0411, - 0x0412, - 0x0413, - 0x0414, - 0x0415, - 0x0401, - 0x0416, - 0x0417, - 0x0418, - 0x0419, - 0x041A, - 0x041B, - 0x041C, - 0x041D, - 0x041E, - 0x041F, - 0x0420, - 0x0421, - 0x0422, - 0x0423, - 0x0424, - 0x0425, - 0x0426, - 0x0427, - 0x0428, - 0x0429, - 0x042A, - 0x042B, - 0x042C, - 0x042D, - 0x042E, - 0x042F, - 0x0490, - 0x0402, - 0x0403, - 0x0404, - 0x0405, - 0x0406, - 0x0407, - 0x0408, - 0x0409, - 0x040A, - 0x040B, - 0x040C, - 0x040E, - 0xF6C4, - 0xF6C5, - 0x0430, - 0x0431, - 0x0432, - 0x0433, - 0x0434, - 0x0435, - 0x0451, - 0x0436, - 0x0437, - 0x0438, - 0x0439, - 0x043A, - 0x043B, - 0x043C, - 0x043D, - 0x043E, - 0x043F, - 0x0440, - 0x0441, - 0x0442, - 0x0443, - 0x0444, - 0x0445, - 0x0446, - 0x0447, - 0x0448, - 0x0449, - 0x044A, - 0x044B, - 0x044C, - 0x044D, - 0x044E, - 0x044F, - 0x0491, - 0x0452, - 0x0453, - 0x0454, - 0x0455, - 0x0456, - 0x0457, - 0x0458, - 0x0459, - 0x045A, - 0x045B, - 0x045C, - 0x045E, - 0x040F, - 0x0462, - 0x0472, - 0x0474, - 0xF6C6, - 0x045F, - 0x0463, - 0x0473, - 0x0475, - 0xF6C7, - 0xF6C8, - 0x04D9, - 0x200E, - 0x200F, - 0x200D, - 0x066A, - 0x060C, - 0x0660, - 0x0661, - 0x0662, - 0x0663, - 0x0664, - 0x0665, - 0x0666, - 0x0667, - 0x0668, - 0x0669, - 0x061B, - 0x061F, - 0x0621, - 0x0622, - 0x0623, - 0x0624, - 0x0625, - 0x0626, - 0x0627, - 0x0628, - 0x0629, - 0x062A, - 0x062B, - 0x062C, - 0x062D, - 0x062E, - 0x062F, - 0x0630, - 0x0631, - 0x0632, - 0x0633, - 0x0634, - 0x0635, - 0x0636, - 0x0637, - 0x0638, - 0x0639, - 0x063A, - 0x0640, - 0x0641, - 0x0642, - 0x0643, - 0x0644, - 0x0645, - 0x0646, - 0x0648, - 0x0649, - 0x064A, - 0x064B, - 0x064C, - 0x064D, - 0x064E, - 0x064F, - 0x0650, - 0x0651, - 0x0652, - 0x0647, - 0x06A4, - 0x067E, - 0x0686, - 0x0698, - 0x06AF, - 0x0679, - 0x0688, - 0x0691, - 0x06BA, - 0x06D2, - 0x06D5, - 0x20AA, - 0x05BE, - 0x05C3, - 0x05D0, - 0x05D1, - 0x05D2, - 0x05D3, - 0x05D4, - 0x05D5, - 0x05D6, - 0x05D7, - 0x05D8, - 0x05D9, - 0x05DA, - 0x05DB, - 0x05DC, - 0x05DD, - 0x05DE, - 0x05DF, - 0x05E0, - 0x05E1, - 0x05E2, - 0x05E3, - 0x05E4, - 0x05E5, - 0x05E6, - 0x05E7, - 0x05E8, - 0x05E9, - 0x05EA, - 0xFB2A, - 0xFB2B, - 0xFB4B, - 0xFB1F, - 0x05F0, - 0x05F1, - 0x05F2, - 0xFB35, - 0x05B4, - 0x05B5, - 0x05B6, - 0x05BB, - 0x05B8, - 0x05B7, - 0x05B0, - 0x05B2, - 0x05B1, - 0x05B3, - 0x05C2, - 0x05C1, - 0x05B9, - 0x05BC, - 0x05BD, - 0x05BF, - 0x05C0, - 0x02BC, - 0x2105, - 0x2113, - 0x2116, - 0x202C, - 0x202D, - 0x202E, - 0x200C, - 0x066D, - 0x02BD, - 0x2135, - 0x03B1, - 0x03AC, - 0x0101, - 0x2220, - 0x2329, - 0x232A, - 0x0387, - 0x0105, - 0x2248, - 0x01FB, - 0x2194, - 0x21D4, - 0x21D3, - 0x21D0, - 0x21D2, - 0x21D1, - 0x2193, - 0xF8E7, - 0x2190, - 0x2192, - 0x2191, - 0x2195, - 0x21A8, - 0xF8E6, - 0x2217, - 0x03B2, - 0x2588, - 0xF8F4, - 0xF8F3, - 0xF8F2, - 0xF8F1, - 0xF8FE, - 0xF8FD, - 0xF8FC, - 0xF8F0, - 0xF8EF, - 0xF8EE, - 0xF8FB, - 0xF8FA, - 0xF8F9, - 0x0107, - 0x21B5, - 0x010D, - 0x0109, - 0x010B, - 0x03C7, - 0x25CB, - 0x2297, - 0x2295, - 0x2663, - 0xF6C3, - 0x2245, - 0xF8E9, - 0xF6D9, - 0xF6D1, - 0xF6D2, - 0xF6D4, - 0xF6D5, - 0xF6D3, - 0xF6D6, - 0x010F, - 0x0111, - 0x03B4, - 0x2666, - 0xF6D7, - 0xF6D8, - 0x0385, - 0x2593, - 0x2584, - 0x20AB, - 0x0323, - 0xF6BE, - 0x22C5, - 0x0115, - 0x011B, - 0x0117, - 0x2208, - 0x0113, - 0x2205, - 0x014B, - 0x0119, - 0x03B5, - 0x03AD, - 0x2261, - 0x212E, - 0x03B7, - 0x03AE, - 0x203C, - 0x2203, - 0x2640, - 0x25A0, - 0x25AC, - 0x20A3, - 0x03B3, - 0x011F, - 0x01E7, - 0x011D, - 0x0123, - 0x0121, - 0x2207, - 0x0300, - 0x2265, - 0x0127, - 0x0125, - 0x2665, - 0x0309, - 0x2302, - 0x012D, - 0x0133, - 0x012B, - 0x221E, - 0x222B, - 0x2321, - 0xF8F5, - 0x2320, - 0x2229, - 0x25D8, - 0x25D9, - 0x263B, - 0x012F, - 0x03B9, - 0x03CA, - 0x0390, - 0x03AF, - 0x0129, - 0x0135, - 0x03BA, - 0x0137, - 0x0138, - 0x013A, - 0x03BB, - 0x013E, - 0x013C, - 0x0140, - 0x2264, - 0x258C, - 0x20A4, - 0xF6C0, - 0x2227, - 0x2228, - 0x017F, - 0x25CA, - 0x2591, - 0x2642, - 0x2032, - 0x266A, - 0x266B, - 0x0144, - 0x0149, - 0x0148, - 0x0146, - 0x2209, - 0x2260, - 0x2284, - 0x03BD, - 0x014F, - 0x01A1, - 0x0151, - 0x014D, - 0x03C9, - 0x03D6, - 0x03CE, - 0x03BF, - 0x03CC, - 0x25E6, - 0x221F, - 0x01FF, - 0xF8ED, - 0xF8EC, - 0xF8EB, - 0xF8F8, - 0xF8F7, - 0xF8F6, - 0x2202, - 0x22A5, - 0x20A7, - 0x03C6, - 0x03D5, - 0x03C0, - 0x211E, - 0x220F, - 0x2282, - 0x2283, - 0x221D, - 0x03C8, - 0x201B, - 0x0155, - 0x221A, - 0xF8E5, - 0x0159, - 0x0157, - 0x2286, - 0x2287, - 0xF8E8, - 0xF6DA, - 0x2310, - 0x03C1, - 0x2590, - 0x015B, - 0x015F, - 0x015F, - 0x015D, - 0x0219, - 0x2033, - 0x2592, - 0x03C3, - 0x03C2, - 0x223C, - 0x263A, - 0x2660, - 0x220B, - 0x2211, - 0x263C, - 0x03C4, - 0x0167, - 0x0165, - 0x0163, - 0x0163, - 0x2234, - 0x03B8, - 0x03D1, - 0x0303, - 0x0384, - 0xF8EA, - 0xF6DB, - 0x25BC, - 0x25C4, - 0x25BA, - 0x25B2, - 0x016D, - 0x01B0, - 0x0171, - 0x016B, - 0x2017, - 0x222A, - 0x2200, - 0x0173, - 0x2580, - 0x03C5, - 0x03CB, - 0x03B0, - 0x03CD, - 0x016F, - 0x0169, - 0x1E83, - 0x0175, - 0x1E85, - 0x2118, - 0x1E81, - 0x03BE, - 0x0177, - 0x1EF3, - 0x017A, - 0x017C, - 0x03B6, + 0x01FCU, + 0x01E2U, + 0x0102U, + 0x1EAEU, + 0x04D0U, + 0x1EB6U, + 0x1EB0U, + 0x1EB2U, + 0x1EB4U, + 0x01CDU, + 0x24B6U, + 0x1EA4U, + 0x1EACU, + 0x1EA6U, + 0x1EA8U, + 0x1EAAU, + 0xF6C9U, + 0x0410U, + 0x0200U, + 0x04D2U, + 0x01DEU, + 0x1EA0U, + 0x01E0U, + 0x1EA2U, + 0x04D4U, + 0x0202U, + 0x0391U, + 0x0386U, + 0x0100U, + 0xFF21U, + 0x0104U, + 0x01FAU, + 0x1E00U, + 0x0531U, + 0x24B7U, + 0x1E02U, + 0x1E04U, + 0x0411U, + 0x0532U, + 0x0392U, + 0x0181U, + 0x1E06U, + 0xFF22U, + 0x0182U, + 0x053EU, + 0x0106U, + 0xF6CAU, + 0x010CU, + 0x1E08U, + 0x24B8U, + 0x0108U, + 0x010AU, + 0x010AU, + 0x0549U, + 0x04BCU, + 0x0427U, + 0x04BEU, + 0x04B6U, + 0x04F4U, + 0x0543U, + 0x04CBU, + 0x04B8U, + 0x03A7U, + 0x0187U, + 0xFF23U, + 0x0551U, + 0x01F1U, + 0x01C4U, + 0x0534U, + 0x0189U, + 0x010EU, + 0x1E10U, + 0x24B9U, + 0x1E12U, + 0x0110U, + 0x1E0AU, + 0x1E0CU, + 0x0414U, + 0x03EEU, + 0x2206U, + 0x0394U, + 0x018AU, + 0xF6CBU, + 0xF6CCU, + 0xF6CDU, + 0x03DCU, + 0x0402U, + 0x1E0EU, + 0xFF24U, + 0x0110U, + 0x018BU, + 0x01F2U, + 0x01C5U, + 0x04E0U, + 0x0405U, + 0x040FU, + 0x0114U, + 0x011AU, + 0x1E1CU, + 0x0535U, + 0x24BAU, + 0x1EBEU, + 0x1E18U, + 0x1EC6U, + 0x1EC0U, + 0x1EC2U, + 0x1EC4U, + 0x0404U, + 0x0204U, + 0x0116U, + 0x0116U, + 0x1EB8U, + 0x0424U, + 0x0537U, + 0x1EBAU, + 0x2167U, + 0x0206U, + 0x0464U, + 0x041BU, + 0x216AU, + 0x0112U, + 0x1E16U, + 0x1E14U, + 0x041CU, + 0xFF25U, + 0x041DU, + 0x04A2U, + 0x014AU, + 0x04A4U, + 0x04C7U, + 0x0118U, + 0x0190U, + 0x0395U, + 0x0388U, + 0x0420U, + 0x018EU, + 0x042DU, + 0x0421U, + 0x04AAU, + 0x01A9U, + 0x0397U, + 0x0538U, + 0x0389U, + 0x1EBCU, + 0x1E1AU, + 0x20ACU, + 0x01B7U, + 0x01EEU, + 0x01B8U, + 0x24BBU, + 0x1E1EU, + 0x0556U, + 0x03E4U, + 0x0191U, + 0x0472U, + 0x2164U, + 0xFF26U, + 0x2163U, + 0x3387U, + 0x01F4U, + 0x0393U, + 0x0194U, + 0x03EAU, + 0x011EU, + 0x01E6U, + 0x0122U, + 0x24BCU, + 0x011CU, + 0x0122U, + 0x0120U, + 0x0120U, + 0x0413U, + 0x0542U, + 0x0494U, + 0x0492U, + 0x0490U, + 0x0193U, + 0x0533U, + 0x0403U, + 0x1E20U, + 0xFF27U, + 0xF6CEU, + 0x029BU, + 0x01E4U, + 0x25CFU, + 0x25AAU, + 0x25ABU, + 0x25A1U, + 0x33CBU, + 0x04A8U, + 0x04B2U, + 0x042AU, + 0x0126U, + 0x1E2AU, + 0x1E28U, + 0x24BDU, + 0x0124U, + 0x1E26U, + 0x1E22U, + 0x1E24U, + 0xFF28U, + 0x0540U, + 0x03E8U, + 0xF6CFU, + 0x3390U, + 0x042FU, + 0x0132U, + 0x042EU, + 0x012CU, + 0x01CFU, + 0x24BEU, + 0x0406U, + 0x0208U, + 0x1E2EU, + 0x04E4U, + 0x0130U, + 0x0130U, + 0x1ECAU, + 0x04D6U, + 0x0415U, + 0x2111U, + 0x1EC8U, + 0x0418U, + 0x020AU, + 0x0419U, + 0x012AU, + 0x04E2U, + 0xFF29U, + 0x053BU, + 0x0401U, + 0x012EU, + 0x0399U, + 0x0196U, + 0x03AAU, + 0x038AU, + 0x0197U, + 0x0128U, + 0x1E2CU, + 0x0474U, + 0x0476U, + 0x0541U, + 0x24BFU, + 0x0134U, + 0x0408U, + 0x054BU, + 0xFF2AU, + 0x3385U, + 0x33CDU, + 0x04A0U, + 0x1E30U, + 0x041AU, + 0x049AU, + 0x04C3U, + 0x039AU, + 0x049EU, + 0x049CU, + 0x01E8U, + 0x0136U, + 0x24C0U, + 0x0136U, + 0x1E32U, + 0x0554U, + 0x053FU, + 0x0425U, + 0x03E6U, + 0x0198U, + 0x040CU, + 0x1E34U, + 0xFF2BU, + 0x0480U, + 0x03DEU, + 0x046EU, + 0x01C7U, + 0xF6BFU, + 0x0139U, + 0x039BU, + 0x013DU, + 0x013BU, + 0x24C1U, + 0x1E3CU, + 0x013BU, + 0x013FU, + 0x013FU, + 0x1E36U, + 0x1E38U, + 0x053CU, + 0x01C8U, + 0x0409U, + 0x1E3AU, + 0xFF2CU, + 0x3386U, + 0xF6D0U, + 0x1E3EU, + 0x24C2U, + 0x1E40U, + 0x1E42U, + 0x0544U, + 0xFF2DU, + 0x019CU, + 0x039CU, + 0x01CAU, + 0x0143U, + 0x0147U, + 0x0145U, + 0x24C3U, + 0x1E4AU, + 0x0145U, + 0x1E44U, + 0x1E46U, + 0x019DU, + 0x2168U, + 0x01CBU, + 0x040AU, + 0x1E48U, + 0xFF2EU, + 0x0546U, + 0x039DU, + 0x04E8U, + 0x04EAU, + 0x014EU, + 0x01D1U, + 0x019FU, + 0x24C4U, + 0x1ED0U, + 0x1ED8U, + 0x1ED2U, + 0x1ED4U, + 0x1ED6U, + 0x041EU, + 0x0150U, + 0x020CU, + 0x04E6U, + 0x1ECCU, + 0x0555U, + 0x2126U, + 0x1ECEU, + 0x01A0U, + 0x1EDAU, + 0x1EE2U, + 0x1EDCU, + 0x1EDEU, + 0x1EE0U, + 0x0150U, + 0x01A2U, + 0x020EU, + 0x014CU, + 0x1E52U, + 0x1E50U, + 0x2126U, + 0x0460U, + 0x03A9U, + 0x047AU, + 0x047CU, + 0x038FU, + 0x039FU, + 0x038CU, + 0xFF2FU, + 0x2160U, + 0x01EAU, + 0x01ECU, + 0x0186U, + 0x01FEU, + 0x01FEU, + 0x047EU, + 0x1E4CU, + 0x1E4EU, + 0x1E54U, + 0x24C5U, + 0x1E56U, + 0x041FU, + 0x054AU, + 0x04A6U, + 0x03A6U, + 0x01A4U, + 0x03A0U, + 0x0553U, + 0xFF30U, + 0x03A8U, + 0x0470U, + 0x24C6U, + 0xFF31U, + 0x054CU, + 0x0154U, + 0x0158U, + 0x0156U, + 0x24C7U, + 0x0156U, + 0x0210U, + 0x1E58U, + 0x1E5AU, + 0x1E5CU, + 0x0550U, + 0x211CU, + 0x03A1U, + 0x0212U, + 0x1E5EU, + 0xFF32U, + 0x0281U, + 0x02B6U, + 0x250CU, + 0x2514U, + 0x2510U, + 0x2518U, + 0x253CU, + 0x252CU, + 0x2534U, + 0x251CU, + 0x2524U, + 0x2500U, + 0x2502U, + 0x2561U, + 0x2562U, + 0x2556U, + 0x2555U, + 0x2563U, + 0x2551U, + 0x2557U, + 0x255DU, + 0x255CU, + 0x255BU, + 0x255EU, + 0x255FU, + 0x255AU, + 0x2554U, + 0x2569U, + 0x2566U, + 0x2560U, + 0x2550U, + 0x256CU, + 0x2567U, + 0x2568U, + 0x2564U, + 0x2565U, + 0x2559U, + 0x2558U, + 0x2552U, + 0x2553U, + 0x256BU, + 0x256AU, + 0x015AU, + 0x1E64U, + 0x03E0U, + 0x1E66U, + 0x015EU, + 0x018FU, + 0x04D8U, + 0x04DAU, + 0x24C8U, + 0x015CU, + 0x0218U, + 0x1E60U, + 0x1E62U, + 0x1E68U, + 0x054DU, + 0x2166U, + 0x0547U, + 0x0428U, + 0x0429U, + 0x03E2U, + 0x04BAU, + 0x03ECU, + 0x03A3U, + 0x2165U, + 0xFF33U, + 0x042CU, + 0x03DAU, + 0x03A4U, + 0x0166U, + 0x0164U, + 0x0162U, + 0x24C9U, + 0x1E70U, + 0x0162U, + 0x1E6AU, + 0x1E6CU, + 0x0422U, + 0x04ACU, + 0x2169U, + 0x04B4U, + 0x0398U, + 0x01ACU, + 0x2162U, + 0x054FU, + 0x1E6EU, + 0xFF34U, + 0x0539U, + 0x01BCU, + 0x0184U, + 0x01A7U, + 0x01AEU, + 0x0426U, + 0x040BU, + 0x216BU, + 0x2161U, + 0x016CU, + 0x01D3U, + 0x24CAU, + 0x1E76U, + 0x0423U, + 0x0170U, + 0x0214U, + 0x01D7U, + 0x1E72U, + 0x01D9U, + 0x04F0U, + 0x01DBU, + 0x01D5U, + 0x1EE4U, + 0x1EE6U, + 0x01AFU, + 0x1EE8U, + 0x1EF0U, + 0x1EEAU, + 0x1EECU, + 0x1EEEU, + 0x0170U, + 0x04F2U, + 0x0216U, + 0x0478U, + 0x016AU, + 0x04EEU, + 0x1E7AU, + 0xFF35U, + 0x0172U, + 0x03A5U, + 0x03D2U, + 0x03D3U, + 0x01B1U, + 0x03ABU, + 0x03D4U, + 0x03D2U, + 0x038EU, + 0x016EU, + 0x040EU, + 0x04AEU, + 0x04B0U, + 0x0168U, + 0x1E78U, + 0x1E74U, + 0x24CBU, + 0x1E7EU, + 0x0412U, + 0x054EU, + 0x01B2U, + 0xFF36U, + 0x0548U, + 0x1E7CU, + 0x1E82U, + 0x24CCU, + 0x0174U, + 0x1E84U, + 0x1E86U, + 0x1E88U, + 0x1E80U, + 0xFF37U, + 0x24CDU, + 0x1E8CU, + 0x1E8AU, + 0x053DU, + 0x039EU, + 0xFF38U, + 0x0462U, + 0x24CEU, + 0x0176U, + 0x1E8EU, + 0x1EF4U, + 0x042BU, + 0x04F8U, + 0x1EF2U, + 0x01B3U, + 0x1EF6U, + 0x0545U, + 0x0407U, + 0x0552U, + 0xFF39U, + 0x1EF8U, + 0x046AU, + 0x046CU, + 0x0466U, + 0x0468U, + 0x0536U, + 0x0179U, + 0x24CFU, + 0x1E90U, + 0x017BU, + 0x017BU, + 0x1E92U, + 0x0417U, + 0x0498U, + 0x04DEU, + 0x0396U, + 0x053AU, + 0x04C1U, + 0x0416U, + 0x0496U, + 0x04DCU, + 0x1E94U, + 0xFF3AU, + 0x01B5U, + 0x0986U, + 0x0906U, + 0x0A86U, + 0x0A06U, + 0x0A3EU, + 0x3303U, + 0x09BEU, + 0x093EU, + 0x0ABEU, + 0x055FU, + 0x0970U, + 0x0985U, + 0x311AU, + 0x0103U, + 0x1EAFU, + 0x04D1U, + 0x1EB7U, + 0x1EB1U, + 0x1EB3U, + 0x1EB5U, + 0x01CEU, + 0x24D0U, + 0x1EA5U, + 0x1EADU, + 0x1EA7U, + 0x1EA9U, + 0x1EABU, + 0x0317U, + 0x0301U, + 0x0301U, + 0x0954U, + 0x02CFU, + 0x0341U, + 0x0430U, + 0x0201U, + 0x0A71U, + 0x0905U, + 0x04D3U, + 0x01DFU, + 0x1EA1U, + 0x01E1U, + 0x01FDU, + 0x3150U, + 0x01E3U, + 0x2015U, + 0x20A4U, + 0x0410U, + 0x0411U, + 0x0412U, + 0x0413U, + 0x0414U, + 0x0415U, + 0x0401U, + 0x0416U, + 0x0417U, + 0x0418U, + 0x0419U, + 0x041AU, + 0x041BU, + 0x041CU, + 0x041DU, + 0x041EU, + 0x041FU, + 0x0420U, + 0x0421U, + 0x0422U, + 0x0423U, + 0x0424U, + 0x0425U, + 0x0426U, + 0x0427U, + 0x0428U, + 0x0429U, + 0x042AU, + 0x042BU, + 0x042CU, + 0x042DU, + 0x042EU, + 0x042FU, + 0x0490U, + 0x0402U, + 0x0403U, + 0x0404U, + 0x0405U, + 0x0406U, + 0x0407U, + 0x0408U, + 0x0409U, + 0x040AU, + 0x040BU, + 0x040CU, + 0x040EU, + 0xF6C4U, + 0xF6C5U, + 0x0430U, + 0x0431U, + 0x0432U, + 0x0433U, + 0x0434U, + 0x0435U, + 0x0451U, + 0x0436U, + 0x0437U, + 0x0438U, + 0x0439U, + 0x043AU, + 0x043BU, + 0x043CU, + 0x043DU, + 0x043EU, + 0x043FU, + 0x0440U, + 0x0441U, + 0x0442U, + 0x0443U, + 0x0444U, + 0x0445U, + 0x0446U, + 0x0447U, + 0x0448U, + 0x0449U, + 0x044AU, + 0x044BU, + 0x044CU, + 0x044DU, + 0x044EU, + 0x044FU, + 0x0491U, + 0x0452U, + 0x0453U, + 0x0454U, + 0x0455U, + 0x0456U, + 0x0457U, + 0x0458U, + 0x0459U, + 0x045AU, + 0x045BU, + 0x045CU, + 0x045EU, + 0x040FU, + 0x0462U, + 0x0472U, + 0x0474U, + 0xF6C6U, + 0x045FU, + 0x0463U, + 0x0473U, + 0x0475U, + 0xF6C7U, + 0xF6C8U, + 0x04D9U, + 0x200EU, + 0x200FU, + 0x200DU, + 0x066AU, + 0x060CU, + 0x0660U, + 0x0661U, + 0x0662U, + 0x0663U, + 0x0664U, + 0x0665U, + 0x0666U, + 0x0667U, + 0x0668U, + 0x0669U, + 0x061BU, + 0x061FU, + 0x0621U, + 0x0622U, + 0x0623U, + 0x0624U, + 0x0625U, + 0x0626U, + 0x0627U, + 0x0628U, + 0x0629U, + 0x062AU, + 0x062BU, + 0x062CU, + 0x062DU, + 0x062EU, + 0x062FU, + 0x0630U, + 0x0631U, + 0x0632U, + 0x0633U, + 0x0634U, + 0x0635U, + 0x0636U, + 0x0637U, + 0x0638U, + 0x0639U, + 0x063AU, + 0x0640U, + 0x0641U, + 0x0642U, + 0x0643U, + 0x0644U, + 0x0645U, + 0x0646U, + 0x0648U, + 0x0649U, + 0x064AU, + 0x064BU, + 0x064CU, + 0x064DU, + 0x064EU, + 0x064FU, + 0x0650U, + 0x0651U, + 0x0652U, + 0x0647U, + 0x06A4U, + 0x067EU, + 0x0686U, + 0x0698U, + 0x06AFU, + 0x0679U, + 0x0688U, + 0x0691U, + 0x06BAU, + 0x06D2U, + 0x06D5U, + 0x20AAU, + 0x05BEU, + 0x05C3U, + 0x05D0U, + 0x05D1U, + 0x05D2U, + 0x05D3U, + 0x05D4U, + 0x05D5U, + 0x05D6U, + 0x05D7U, + 0x05D8U, + 0x05D9U, + 0x05DAU, + 0x05DBU, + 0x05DCU, + 0x05DDU, + 0x05DEU, + 0x05DFU, + 0x05E0U, + 0x05E1U, + 0x05E2U, + 0x05E3U, + 0x05E4U, + 0x05E5U, + 0x05E6U, + 0x05E7U, + 0x05E8U, + 0x05E9U, + 0x05EAU, + 0xFB2AU, + 0xFB2BU, + 0xFB4BU, + 0xFB1FU, + 0x05F0U, + 0x05F1U, + 0x05F2U, + 0xFB35U, + 0x05B4U, + 0x05B5U, + 0x05B6U, + 0x05BBU, + 0x05B8U, + 0x05B7U, + 0x05B0U, + 0x05B2U, + 0x05B1U, + 0x05B3U, + 0x05C2U, + 0x05C1U, + 0x05B9U, + 0x05BCU, + 0x05BDU, + 0x05BFU, + 0x05C0U, + 0x02BCU, + 0x2105U, + 0x2113U, + 0x2116U, + 0x202CU, + 0x202DU, + 0x202EU, + 0x200CU, + 0x066DU, + 0x02BDU, + 0x0A85U, + 0x0A05U, + 0x3042U, + 0x1EA3U, + 0x0990U, + 0x311EU, + 0x0910U, + 0x04D5U, + 0x0A90U, + 0x0A10U, + 0x0A48U, + 0x0639U, + 0xFECAU, + 0xFECBU, + 0xFECCU, + 0x0203U, + 0x09C8U, + 0x0948U, + 0x0AC8U, + 0x30A2U, + 0xFF71U, + 0x314FU, + 0x05D0U, + 0x0627U, + 0xFB30U, + 0xFE8EU, + 0x0623U, + 0xFE84U, + 0x0625U, + 0xFE88U, + 0x05D0U, + 0xFB4FU, + 0x0622U, + 0xFE82U, + 0x0649U, + 0xFEF0U, + 0xFEF3U, + 0xFEF4U, + 0xFB2EU, + 0xFB2FU, + 0x2135U, + 0x224CU, + 0x03B1U, + 0x03ACU, + 0x0101U, + 0xFF41U, + 0xFF06U, + 0x33C2U, + 0x3122U, + 0x3124U, + 0x0E5AU, + 0x2220U, + 0x3008U, + 0xFE3FU, + 0x3009U, + 0xFE40U, + 0x2329U, + 0x232AU, + 0x212BU, + 0x0387U, + 0x0952U, + 0x0982U, + 0x0902U, + 0x0A82U, + 0x0105U, + 0x3300U, + 0x249CU, + 0x055AU, + 0x02BCU, + 0xF8FFU, + 0x2250U, + 0x2248U, + 0x2252U, + 0x2245U, + 0x318EU, + 0x318DU, + 0x2312U, + 0x1E9AU, + 0x01FBU, + 0x1E01U, + 0x2194U, + 0x21E3U, + 0x21E0U, + 0x21E2U, + 0x21E1U, + 0x21D4U, + 0x21D3U, + 0x21D0U, + 0x21D2U, + 0x21D1U, + 0x2193U, + 0x2199U, + 0x2198U, + 0x21E9U, + 0x02C5U, + 0x02C2U, + 0x02C3U, + 0x02C4U, + 0xF8E7U, + 0x2190U, + 0x21D0U, + 0x21CDU, + 0x21C6U, + 0x21E6U, + 0x2192U, + 0x21CFU, + 0x279EU, + 0x21C4U, + 0x21E8U, + 0x21E4U, + 0x21E5U, + 0x2191U, + 0x2195U, + 0x21A8U, + 0x21A8U, + 0x2196U, + 0x21C5U, + 0x2197U, + 0x21E7U, + 0xF8E6U, + 0xFF3EU, + 0xFF5EU, + 0x0251U, + 0x0252U, + 0x3041U, + 0x30A1U, + 0xFF67U, + 0x066DU, + 0x066DU, + 0x2217U, + 0xFF0AU, + 0xFE61U, + 0x2042U, + 0x2243U, + 0xFF20U, + 0xFE6BU, + 0x0250U, + 0x0994U, + 0x3120U, + 0x0914U, + 0x0A94U, + 0x0A14U, + 0x09D7U, + 0x0A4CU, + 0x09CCU, + 0x094CU, + 0x0ACCU, + 0x093DU, + 0x0561U, + 0x05E2U, + 0xFB20U, + 0x05E2U, + 0x09ACU, + 0xFF3CU, + 0x092CU, + 0x0AACU, + 0x0A2CU, + 0x3070U, + 0x0E3FU, + 0x30D0U, + 0xFF5CU, + 0x3105U, + 0x24D1U, + 0x1E03U, + 0x1E05U, + 0x266CU, + 0x2235U, + 0x0431U, + 0x0628U, + 0xFE90U, + 0xFE91U, + 0x3079U, + 0xFE92U, + 0xFC9FU, + 0xFC08U, + 0xFC6DU, + 0x30D9U, + 0x0562U, + 0x05D1U, + 0x03B2U, + 0x03D0U, + 0xFB31U, + 0xFB31U, + 0x05D1U, + 0xFB4CU, + 0x09ADU, + 0x092DU, + 0x0AADU, + 0x0A2DU, + 0x0253U, + 0x3073U, + 0x30D3U, + 0x0298U, + 0x0A02U, + 0x3331U, + 0x25CFU, + 0x25C6U, + 0x25BCU, + 0x25C4U, + 0x25C0U, + 0x3010U, + 0xFE3BU, + 0x3011U, + 0xFE3CU, + 0x25E3U, + 0x25E2U, + 0x25ACU, + 0x25BAU, + 0x25B6U, + 0x25AAU, + 0x263BU, + 0x25A0U, + 0x2605U, + 0x25E4U, + 0x25E5U, + 0x25B4U, + 0x25B2U, + 0x2423U, + 0x1E07U, + 0x2588U, + 0xFF42U, + 0x0E1AU, + 0x307CU, + 0x30DCU, + 0x249DU, + 0x33C3U, + 0xF8F4U, + 0xF8F3U, + 0xF8F2U, + 0xFF5BU, + 0xFE5BU, + 0xF8F1U, + 0xFE37U, + 0xF8FEU, + 0xF8FDU, + 0xFF5DU, + 0xFE5CU, + 0xF8FCU, + 0xFE38U, + 0xF8F0U, + 0xF8EFU, + 0xFF3BU, + 0xF8EEU, + 0xF8FBU, + 0xF8FAU, + 0xFF3DU, + 0xF8F9U, + 0x032EU, + 0x0306U, + 0x032FU, + 0x0311U, + 0x0361U, + 0x032AU, + 0x033AU, + 0x0180U, + 0x0183U, + 0x3076U, + 0x30D6U, + 0x25D8U, + 0x2219U, + 0x25CEU, + 0x056EU, + 0x099AU, + 0x0107U, + 0x091AU, + 0x0A9AU, + 0x0A1AU, + 0x3388U, + 0x0981U, + 0x0310U, + 0x0901U, + 0x0A81U, + 0x21EAU, + 0x2105U, + 0x032CU, + 0x030CU, + 0x21B5U, + 0x3118U, + 0x010DU, + 0x1E09U, + 0x24D2U, + 0x0109U, + 0x0255U, + 0x010BU, + 0x010BU, + 0x33C5U, + 0x0327U, + 0x2103U, + 0xFFE0U, + 0x0579U, + 0x099BU, + 0x091BU, + 0x0A9BU, + 0x0A1BU, + 0x3114U, + 0x04BDU, + 0x2713U, + 0x0447U, + 0x04BFU, + 0x04B7U, + 0x04F5U, + 0x0573U, + 0x04CCU, + 0x04B9U, + 0x03C7U, + 0x3277U, + 0x3217U, + 0x3269U, + 0x314AU, + 0x3209U, + 0x0E0AU, + 0x0E08U, + 0x0E09U, + 0x0E0CU, + 0x0188U, + 0x3276U, + 0x3216U, + 0x3268U, + 0x3148U, + 0x3208U, + 0x321CU, + 0x25CBU, + 0x2297U, + 0x2299U, + 0x2295U, + 0x3036U, + 0x25D0U, + 0x25D1U, + 0x032DU, + 0x0302U, + 0x2327U, + 0x01C2U, + 0x01C0U, + 0x01C1U, + 0x01C3U, + 0x2663U, + 0x2663U, + 0x2667U, + 0x33A4U, + 0xFF43U, + 0x33A0U, + 0x0581U, + 0xFF1AU, + 0x20A1U, + 0xFE55U, + 0x02D1U, + 0x02D0U, + 0x0313U, + 0x0315U, + 0xF6C3U, + 0x060CU, + 0x055DU, + 0xFF0CU, + 0x0314U, + 0x02BDU, + 0xFE50U, + 0x0312U, + 0x02BBU, + 0x263CU, + 0x2245U, + 0x222EU, + 0x2303U, + 0x0006U, + 0x0007U, + 0x0008U, + 0x0018U, + 0x000DU, + 0x0011U, + 0x0012U, + 0x0013U, + 0x0014U, + 0x007FU, + 0x0010U, + 0x0019U, + 0x0005U, + 0x0004U, + 0x001BU, + 0x0017U, + 0x0003U, + 0x000CU, + 0x001CU, + 0x001DU, + 0x0009U, + 0x000AU, + 0x0015U, + 0x001EU, + 0x000FU, + 0x000EU, + 0x0002U, + 0x0001U, + 0x001AU, + 0x0016U, + 0x001FU, + 0x000BU, + 0xF8E9U, + 0xF6D9U, + 0x300CU, + 0xFF62U, + 0xFE41U, + 0x300DU, + 0xFF63U, + 0xFE42U, + 0x337FU, + 0x33C7U, + 0x33C6U, + 0x249EU, + 0x20A2U, + 0x0297U, + 0x22CFU, + 0x22CEU, + 0xF6D1U, + 0xF6D2U, + 0xF6D4U, + 0xF6D5U, + 0x0564U, + 0x09A6U, + 0x0636U, + 0x0926U, + 0xFEBEU, + 0xFEBFU, + 0xFEC0U, + 0x05BCU, + 0x05BCU, + 0x0AA6U, + 0x0A26U, + 0x3060U, + 0x30C0U, + 0x062FU, + 0x05D3U, + 0xFB33U, + 0xFB33U, + 0, + 0, + 0, + 0, + 0x05D3U, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0xFEAAU, + 0x064FU, + 0x064FU, + 0x064CU, + 0x064CU, + 0x0964U, + 0x05A7U, + 0x05A7U, + 0x0485U, + 0xF6D3U, + 0x300AU, + 0xFE3DU, + 0x300BU, + 0xFE3EU, + 0x032BU, + 0x21D4U, + 0x21D2U, + 0x0965U, + 0xF6D6U, + 0x030FU, + 0x222CU, + 0x2017U, + 0x0333U, + 0x033FU, + 0x02BAU, + 0x2016U, + 0x030EU, + 0x3109U, + 0x33C8U, + 0x010FU, + 0x1E11U, + 0x24D3U, + 0x1E13U, + 0x0111U, + 0x09A1U, + 0x0921U, + 0x0AA1U, + 0x0A21U, + 0x0688U, + 0xFB89U, + 0x095CU, + 0x09A2U, + 0x0922U, + 0x0AA2U, + 0x0A22U, + 0x1E0BU, + 0x1E0DU, + 0x066BU, + 0x066BU, + 0x0434U, + 0x05ADU, + 0x3067U, + 0x03EFU, + 0x30C7U, + 0x232BU, + 0x2326U, + 0x03B4U, + 0x018DU, + 0x09F8U, + 0x02A4U, + 0x09A7U, + 0x0927U, + 0x0AA7U, + 0x0A27U, + 0x0257U, + 0x0385U, + 0x0344U, + 0x2666U, + 0x2662U, + 0xF6D7U, + 0x0324U, + 0x0308U, + 0xF6D8U, + 0x0385U, + 0x3062U, + 0x30C2U, + 0x3003U, + 0x2223U, + 0x2215U, + 0x0452U, + 0x2593U, + 0x1E0FU, + 0x3397U, + 0x0111U, + 0xFF44U, + 0x2584U, + 0x0E0EU, + 0x0E14U, + 0x3069U, + 0x30C9U, + 0xFF04U, + 0xFE69U, + 0x20ABU, + 0x3326U, + 0x0307U, + 0x0323U, + 0x0323U, + 0x30FBU, + 0xF6BEU, + 0x0284U, + 0x22C5U, + 0x25CCU, + 0xFB1FU, + 0xFB1FU, + 0x031EU, + 0x02D5U, + 0x249FU, + 0x0256U, + 0x018CU, + 0x3065U, + 0x30C5U, + 0x01F3U, + 0x02A3U, + 0x01C6U, + 0x02A5U, + 0x04E1U, + 0x0455U, + 0x045FU, + 0x2641U, + 0x098FU, + 0x311CU, + 0x0115U, + 0x090DU, + 0x0A8DU, + 0x0945U, + 0x0AC5U, + 0x011BU, + 0x1E1DU, + 0x0565U, + 0x0587U, + 0x24D4U, + 0x1EBFU, + 0x1E19U, + 0x1EC7U, + 0x1EC1U, + 0x1EC3U, + 0x1EC5U, + 0x0454U, + 0x0205U, + 0x090FU, + 0x0117U, + 0x0117U, + 0x1EB9U, + 0x0A0FU, + 0x0A47U, + 0x0444U, + 0x0A8FU, + 0x0567U, + 0x311DU, + 0x3048U, + 0x1EBBU, + 0x311FU, + 0x0668U, + 0x09EEU, + 0x2467U, + 0x2791U, + 0x096EU, + 0x2471U, + 0x2485U, + 0x2499U, + 0x0AEEU, + 0x0A6EU, + 0x0668U, + 0x3028U, + 0x266BU, + 0x3227U, + 0xFF18U, + 0x247BU, + 0x248FU, + 0x06F8U, + 0x2177U, + 0x0E58U, + 0x0207U, + 0x0465U, + 0x30A8U, + 0xFF74U, + 0x0A74U, + 0x3154U, + 0x043BU, + 0x2208U, + 0x246AU, + 0x247EU, + 0x2492U, + 0x217AU, + 0x22EEU, + 0x0113U, + 0x1E17U, + 0x1E15U, + 0x043CU, + 0xFE31U, + 0xFF45U, + 0x055BU, + 0x2205U, + 0x3123U, + 0x043DU, + 0xFE32U, + 0x04A3U, + 0x014BU, + 0x3125U, + 0x04A5U, + 0x04C8U, + 0x2002U, + 0x0119U, + 0x3153U, + 0x025BU, + 0x029AU, + 0x025CU, + 0x025EU, + 0x025DU, + 0x24A0U, + 0x03B5U, + 0x03ADU, + 0xFF1DU, + 0xFE66U, + 0x207CU, + 0x2261U, + 0x3126U, + 0x0440U, + 0x0258U, + 0x044DU, + 0x0441U, + 0x04ABU, + 0x0283U, + 0x0286U, + 0x090EU, + 0x0946U, + 0x01AAU, + 0x0285U, + 0x3047U, + 0x30A7U, + 0xFF6AU, + 0x212EU, + 0x03B7U, + 0x0568U, + 0x03AEU, + 0x1EBDU, + 0x1E1BU, + 0x0591U, + 0x0591U, + 0x0591U, + 0x0591U, + 0x01DDU, + 0x3161U, + 0x20ACU, + 0x09C7U, + 0x0947U, + 0x0AC7U, + 0x055CU, + 0x203CU, + 0xFF01U, + 0x2203U, + 0x0292U, + 0x01EFU, + 0x0293U, + 0x01B9U, + 0x01BAU, + 0x095EU, + 0x0A5EU, + 0x2109U, + 0x064EU, + 0x064EU, + 0x064BU, + 0x3108U, + 0x24D5U, + 0x1E1FU, + 0x0641U, + 0x0586U, + 0xFED2U, + 0xFED3U, + 0xFED4U, + 0x03E5U, + 0x2640U, + 0x246EU, + 0x2482U, + 0x2496U, + 0x25A0U, + 0x25ACU, + 0x05DAU, + 0xFB3AU, + 0xFB3AU, + 0x05DAU, + 0, + 0, + 0, + 0, + 0x05DDU, + 0x05DDU, + 0x05DFU, + 0x05DFU, + 0x05E3U, + 0x05E3U, + 0x05E5U, + 0x05E5U, + 0x02C9U, + 0x25C9U, + 0x0473U, + 0x0665U, + 0x09EBU, + 0x2464U, + 0x278EU, + 0x096BU, + 0x0AEBU, + 0x0A6BU, + 0x0665U, + 0x3025U, + 0x3224U, + 0xFF15U, + 0x2478U, + 0x248CU, + 0x06F5U, + 0x2174U, + 0x0E55U, + 0xFF46U, + 0x3399U, + 0x0E1FU, + 0x0E1DU, + 0x0E4FU, + 0x2200U, + 0x0664U, + 0x09EAU, + 0x2463U, + 0x278DU, + 0x096AU, + 0x0AEAU, + 0x0A6AU, + 0x0664U, + 0x3024U, + 0x3223U, + 0xFF14U, + 0x09F7U, + 0x2477U, + 0x248BU, + 0x06F4U, + 0x2173U, + 0x246DU, + 0x2481U, + 0x2495U, + 0x0E54U, + 0x02CBU, + 0x24A1U, + 0x20A3U, + 0x0997U, + 0x01F5U, + 0x0917U, + 0x06AFU, + 0xFB93U, + 0xFB94U, + 0xFB95U, + 0x0A97U, + 0x0A17U, + 0x304CU, + 0x30ACU, + 0x03B3U, + 0x0263U, + 0x02E0U, + 0x03EBU, + 0x310DU, + 0x011FU, + 0x01E7U, + 0x0123U, + 0x24D6U, + 0x011DU, + 0x0123U, + 0x0121U, + 0x0121U, + 0x0433U, + 0x3052U, + 0x30B2U, + 0x2251U, + 0x059CU, + 0x05F3U, + 0x059DU, + 0x059EU, + 0x05F4U, + 0x3013U, + 0x0998U, + 0x0572U, + 0x0918U, + 0x0A98U, + 0x0A18U, + 0x063AU, + 0xFECEU, + 0xFECFU, + 0xFED0U, + 0x0495U, + 0x0493U, + 0x0491U, + 0x095AU, + 0x0A5AU, + 0x0260U, + 0x3393U, + 0x304EU, + 0x30AEU, + 0x0563U, + 0x05D2U, + 0xFB32U, + 0xFB32U, + 0x05D2U, + 0x0453U, + 0x01BEU, + 0x0294U, + 0x0296U, + 0x02C0U, + 0x0295U, + 0x02C1U, + 0x02E4U, + 0x02A1U, + 0x02A2U, + 0x1E21U, + 0xFF47U, + 0x3054U, + 0x30B4U, + 0x24A2U, + 0x33ACU, + 0x2207U, + 0x0316U, + 0x0300U, + 0x0300U, + 0x0953U, + 0x02CEU, + 0xFF40U, + 0x0340U, + 0x2265U, + 0x22DBU, + 0xFF1EU, + 0x2273U, + 0x2277U, + 0x2267U, + 0xFE65U, + 0x0261U, + 0x01E5U, + 0x3050U, + 0x30B0U, + 0x3318U, + 0x33C9U, + 0x04A9U, + 0x06C1U, + 0x09B9U, + 0x04B3U, + 0x0939U, + 0x0AB9U, + 0x0A39U, + 0x062DU, + 0xFEA2U, + 0xFEA3U, + 0x306FU, + 0xFEA4U, + 0x332AU, + 0x30CFU, + 0xFF8AU, + 0x0A4DU, + 0x0621U, + 0, + 0, + 0, + 0, + 0x0621U, + 0, + 0, + 0, + 0x3164U, + 0x044AU, + 0x21BCU, + 0x21C0U, + 0x33CAU, + 0x05B2U, + 0x05B2U, + 0x05B2U, + 0x05B2U, + 0x05B2U, + 0x05B2U, + 0x05B2U, + 0x05B2U, + 0x05B3U, + 0x05B3U, + 0x05B3U, + 0x05B3U, + 0x05B3U, + 0x05B3U, + 0x05B3U, + 0x05B3U, + 0x05B1U, + 0x05B1U, + 0x05B1U, + 0x05B1U, + 0x05B1U, + 0x05B1U, + 0x05B1U, + 0x05B1U, + 0x0127U, + 0x310FU, + 0x1E2BU, + 0x1E29U, + 0x24D7U, + 0x0125U, + 0x1E27U, + 0x1E23U, + 0x1E25U, + 0x05D4U, + 0x2665U, + 0x2665U, + 0x2661U, + 0xFB34U, + 0xFB34U, + 0x06C1U, + 0x0647U, + 0x05D4U, + 0xFBA7U, + 0xFEEAU, + 0xFEEAU, + 0xFBA5U, + 0xFBA4U, + 0xFBA8U, + 0xFEEBU, + 0x3078U, + 0xFBA9U, + 0xFEECU, + 0x337BU, + 0x30D8U, + 0xFF8DU, + 0x3336U, + 0x0267U, + 0x3339U, + 0x05D7U, + 0x05D7U, + 0x0266U, + 0x02B1U, + 0x327BU, + 0x321BU, + 0x326DU, + 0x314EU, + 0x320DU, + 0x3072U, + 0x30D2U, + 0xFF8BU, + 0x05B4U, + 0x05B4U, + 0x05B4U, + 0x05B4U, + 0x05B4U, + 0x05B4U, + 0x05B4U, + 0x05B4U, + 0x1E96U, + 0xFF48U, + 0x0570U, + 0x0E2BU, + 0x307BU, + 0x30DBU, + 0xFF8EU, + 0x05B9U, + 0x05B9U, + 0x05B9U, + 0x05B9U, + 0x05B9U, + 0x05B9U, + 0x05B9U, + 0x05B9U, + 0x0E2EU, + 0x0309U, + 0x0309U, + 0x0321U, + 0x0322U, + 0x3342U, + 0x03E9U, + 0x2015U, + 0x031BU, + 0x2668U, + 0x2302U, + 0x24A3U, + 0x02B0U, + 0x0265U, + 0x3075U, + 0x3333U, + 0x30D5U, + 0xFF8CU, + 0x030BU, + 0x0195U, + 0xFF0DU, + 0xFE63U, + 0x2010U, + 0x044FU, + 0x0987U, + 0x3127U, + 0x012DU, + 0x01D0U, + 0x24D8U, + 0x0456U, + 0x0209U, + 0x328FU, + 0x328BU, + 0x323FU, + 0x323AU, + 0x32A5U, + 0x3006U, + 0x3001U, + 0xFF64U, + 0x3237U, + 0x32A3U, + 0x322FU, + 0x323DU, + 0x329DU, + 0x3240U, + 0x3296U, + 0x3236U, + 0x322BU, + 0x3232U, + 0x32A4U, + 0x3005U, + 0x3298U, + 0x3238U, + 0x32A7U, + 0x32A6U, + 0x32A9U, + 0x322EU, + 0x322AU, + 0x3234U, + 0x3002U, + 0x329EU, + 0x3243U, + 0x3239U, + 0x323EU, + 0x32A8U, + 0x3299U, + 0x3242U, + 0x3233U, + 0x3000U, + 0x3235U, + 0x3231U, + 0x323BU, + 0x3230U, + 0x323CU, + 0x322CU, + 0x322DU, + 0x3007U, + 0x328EU, + 0x328AU, + 0x3294U, + 0x3290U, + 0x328CU, + 0x328DU, + 0x0907U, + 0x1E2FU, + 0x04E5U, + 0x1ECBU, + 0x04D7U, + 0x0435U, + 0x3275U, + 0x3215U, + 0x3267U, + 0x3147U, + 0x3207U, + 0x0A87U, + 0x0A07U, + 0x3044U, + 0x1EC9U, + 0x0988U, + 0x0438U, + 0x0908U, + 0x0A88U, + 0x0A08U, + 0x0A40U, + 0x020BU, + 0x0439U, + 0x09C0U, + 0x0940U, + 0x0AC0U, + 0x0133U, + 0x30A4U, + 0xFF72U, + 0x3163U, + 0x02DCU, + 0x05ACU, + 0x012BU, + 0x04E3U, + 0x2253U, + 0x0A3FU, + 0xFF49U, + 0x2206U, + 0x221EU, + 0x056BU, + 0x222BU, + 0x2321U, + 0x2321U, + 0xF8F5U, + 0x2320U, + 0x2320U, + 0x2229U, + 0x3305U, + 0x25D8U, + 0x25D9U, + 0x263BU, + 0x0451U, + 0x012FU, + 0x03B9U, + 0x03CAU, + 0x0390U, + 0x0269U, + 0x03AFU, + 0x24A4U, + 0x0A72U, + 0x3043U, + 0x30A3U, + 0xFF68U, + 0x09FAU, + 0x0268U, + 0x309DU, + 0x30FDU, + 0x0129U, + 0x1E2DU, + 0x3129U, + 0x044EU, + 0x09BFU, + 0x093FU, + 0x0ABFU, + 0x0475U, + 0x0477U, + 0x0571U, + 0x099CU, + 0x091CU, + 0x0A9CU, + 0x0A1CU, + 0x3110U, + 0x01F0U, + 0x24D9U, + 0x0135U, + 0x029DU, + 0x025FU, + 0x0458U, + 0x062CU, + 0xFE9EU, + 0xFE9FU, + 0xFEA0U, + 0x0698U, + 0xFB8BU, + 0x099DU, + 0x091DU, + 0x0A9DU, + 0x0A1DU, + 0x057BU, + 0x3004U, + 0xFF4AU, + 0x24A5U, + 0x02B2U, + 0x04A1U, + 0x0995U, + 0x1E31U, + 0x043AU, + 0x049BU, + 0x0915U, + 0x05DBU, + 0x0643U, + 0xFB3BU, + 0xFB3BU, + 0xFEDAU, + 0x05DBU, + 0xFEDBU, + 0xFEDCU, + 0xFB4DU, + 0x0A95U, + 0x0A15U, + 0x304BU, + 0x04C4U, + 0x30ABU, + 0xFF76U, + 0x03BAU, + 0x03F0U, + 0x3171U, + 0x3184U, + 0x3178U, + 0x3179U, + 0x330DU, + 0x0640U, + 0x0640U, + 0x30F5U, + 0x3384U, + 0x0650U, + 0x064DU, + 0x049FU, + 0xFF70U, + 0x049DU, + 0x310EU, + 0x3389U, + 0x01E9U, + 0x0137U, + 0x24DAU, + 0x0137U, + 0x1E33U, + 0x0584U, + 0x3051U, + 0x30B1U, + 0xFF79U, + 0x056FU, + 0x30F6U, + 0x0138U, + 0x0996U, + 0x0445U, + 0x0916U, + 0x0A96U, + 0x0A16U, + 0x062EU, + 0xFEA6U, + 0xFEA7U, + 0xFEA8U, + 0x03E7U, + 0x0959U, + 0x0A59U, + 0x3278U, + 0x3218U, + 0x326AU, + 0x314BU, + 0x320AU, + 0x0E02U, + 0x0E05U, + 0x0E03U, + 0x0E04U, + 0x0E5BU, + 0x0199U, + 0x0E06U, + 0x3391U, + 0x304DU, + 0x30ADU, + 0xFF77U, + 0x3315U, + 0x3316U, + 0x3314U, + 0x326EU, + 0x320EU, + 0x3260U, + 0x3131U, + 0x3200U, + 0x3133U, + 0x045CU, + 0x1E35U, + 0x3398U, + 0x33A6U, + 0xFF4BU, + 0x33A2U, + 0x3053U, + 0x33C0U, + 0x0E01U, + 0x30B3U, + 0xFF7AU, + 0x331EU, + 0x0481U, + 0x327FU, + 0x0343U, + 0x24A6U, + 0x33AAU, + 0x046FU, + 0x33CFU, + 0x029EU, + 0x304FU, + 0x30AFU, + 0xFF78U, + 0x33B8U, + 0x33BEU, + 0x09B2U, + 0x013AU, + 0x0932U, + 0x0AB2U, + 0x0A32U, + 0x0E45U, + 0xFEFCU, + 0xFEF8U, + 0xFEF7U, + 0xFEFAU, + 0xFEF9U, + 0xFEFBU, + 0xFEF6U, + 0xFEF5U, + 0x0644U, + 0x03BBU, + 0x019BU, + 0x05DCU, + 0xFB3CU, + 0xFB3CU, + 0x05DCU, + 0, + 0, + 0, + 0, + 0xFEDEU, + 0xFCCAU, + 0xFEDFU, + 0xFCC9U, + 0xFCCBU, + 0xFDF2U, + 0xFEE0U, + 0xFD88U, + 0xFCCCU, + 0, + 0, + 0x25EFU, + 0x019AU, + 0x026CU, + 0x310CU, + 0x013EU, + 0x013CU, + 0x24DBU, + 0x1E3DU, + 0x013CU, + 0x0140U, + 0x0140U, + 0x1E37U, + 0x1E39U, + 0x031AU, + 0x0318U, + 0x2264U, + 0x22DAU, + 0xFF1CU, + 0x2272U, + 0x2276U, + 0x2266U, + 0xFE64U, + 0x026EU, + 0x258CU, + 0x026DU, + 0x20A4U, + 0x056CU, + 0x01C9U, + 0x0459U, + 0xF6C0U, + 0x0933U, + 0x0AB3U, + 0x1E3BU, + 0x0934U, + 0x09E1U, + 0x0961U, + 0x09E3U, + 0x0963U, + 0x026BU, + 0xFF4CU, + 0x33D0U, + 0x0E2CU, + 0x2227U, + 0x2310U, + 0x2228U, + 0x0E25U, + 0x017FU, + 0xFE4EU, + 0x0332U, + 0xFE4DU, + 0x25CAU, + 0x24A7U, + 0x2113U, + 0x2591U, + 0x0E26U, + 0x098CU, + 0x090CU, + 0x09E2U, + 0x0962U, + 0x33D3U, + 0x09AEU, + 0x0331U, + 0x0304U, + 0x02CDU, + 0xFFE3U, + 0x1E3FU, + 0x092EU, + 0x0AAEU, + 0x0A2EU, + 0x05A4U, + 0x05A4U, + 0x307EU, + 0xF895U, + 0xF894U, + 0x0E4BU, + 0xF893U, + 0xF88CU, + 0xF88BU, + 0x0E48U, + 0xF88AU, + 0xF884U, + 0x0E31U, + 0xF889U, + 0x0E47U, + 0xF88FU, + 0xF88EU, + 0x0E49U, + 0xF88DU, + 0xF892U, + 0xF891U, + 0x0E4AU, + 0xF890U, + 0x0E46U, + 0x30DEU, + 0xFF8FU, + 0x2642U, + 0x3347U, + 0x05BEU, + 0x2642U, + 0x05AFU, + 0x3383U, + 0x3107U, + 0x33D4U, + 0x24DCU, + 0x33A5U, + 0x1E41U, + 0x1E43U, + 0x0645U, + 0xFEE2U, + 0xFEE3U, + 0xFEE4U, + 0xFCD1U, + 0xFC48U, + 0x334DU, + 0x3081U, + 0x337EU, + 0x30E1U, + 0xFF92U, + 0x05DEU, + 0xFB3EU, + 0xFB3EU, + 0x05DEU, + 0x0574U, + 0x05A5U, + 0x05A6U, + 0x05A6U, + 0x05A5U, + 0x0271U, + 0x3392U, + 0xFF65U, + 0x00B7U, + 0x3272U, + 0x3212U, + 0x3264U, + 0x3141U, + 0x3170U, + 0x3204U, + 0x316EU, + 0x316FU, + 0x307FU, + 0x30DFU, + 0xFF90U, + 0x0320U, + 0x2296U, + 0x02D7U, + 0x2213U, + 0x2032U, + 0x334AU, + 0x3349U, + 0x0270U, + 0x3396U, + 0x33A3U, + 0xFF4DU, + 0x339FU, + 0x3082U, + 0x33C1U, + 0x30E2U, + 0xFF93U, + 0x33D6U, + 0x0E21U, + 0x33A7U, + 0x33A8U, + 0x24A8U, + 0x33ABU, + 0x33B3U, + 0x026FU, + 0x00B5U, + 0x3382U, + 0x226BU, + 0x226AU, + 0x338CU, + 0x03BCU, + 0x338DU, + 0x3080U, + 0x30E0U, + 0xFF91U, + 0x3395U, + 0x339BU, + 0x05A3U, + 0x05A3U, + 0x266AU, + 0x266BU, + 0x266DU, + 0x266FU, + 0x33B2U, + 0x33B6U, + 0x33BCU, + 0x33B9U, + 0x33B7U, + 0x33BFU, + 0x33BDU, + 0x09A8U, + 0x2207U, + 0x0144U, + 0x0928U, + 0x0AA8U, + 0x0A28U, + 0x306AU, + 0x30CAU, + 0xFF85U, + 0x0149U, + 0x3381U, + 0x310BU, + 0x00A0U, + 0x0148U, + 0x0146U, + 0x24DDU, + 0x1E4BU, + 0x0146U, + 0x1E45U, + 0x1E47U, + 0x306DU, + 0x30CDU, + 0xFF88U, + 0x20AAU, + 0x338BU, + 0x0999U, + 0x0919U, + 0x0A99U, + 0x0A19U, + 0x0E07U, + 0x3093U, + 0x0272U, + 0x0273U, + 0x326FU, + 0x320FU, + 0x3135U, + 0x3261U, + 0x3136U, + 0x3134U, + 0x3168U, + 0x3201U, + 0x3167U, + 0x3166U, + 0x306BU, + 0x30CBU, + 0xFF86U, + 0xF899U, + 0x0E4DU, + 0x0669U, + 0x09EFU, + 0x2468U, + 0x2792U, + 0x096FU, + 0x0AEFU, + 0x0A6FU, + 0x0669U, + 0x3029U, + 0x3228U, + 0xFF19U, + 0x247CU, + 0x2490U, + 0x06F9U, + 0x2178U, + 0x2472U, + 0x2486U, + 0x249AU, + 0x0E59U, + 0x01CCU, + 0x045AU, + 0x30F3U, + 0xFF9DU, + 0x019EU, + 0x1E49U, + 0xFF4EU, + 0x339AU, + 0x09A3U, + 0x0923U, + 0x0AA3U, + 0x0A23U, + 0x0929U, + 0x306EU, + 0x30CEU, + 0xFF89U, + 0x00A0U, + 0x0E13U, + 0x0E19U, + 0x0646U, + 0xFEE6U, + 0x06BAU, + 0xFB9FU, + 0, + 0xFEE7U, + 0xFCD2U, + 0xFC4BU, + 0xFEE8U, + 0xFCD5U, + 0xFC4EU, + 0xFC8DU, + 0x220CU, + 0x2209U, + 0x2209U, + 0x2260U, + 0x226FU, + 0x2271U, + 0x2279U, + 0x2262U, + 0x226EU, + 0x2270U, + 0x2226U, + 0x2280U, + 0x2284U, + 0x2281U, + 0x2285U, + 0x0576U, + 0x24A9U, + 0x33B1U, + 0x03BDU, + 0x306CU, + 0x30CCU, + 0xFF87U, + 0x09BCU, + 0x093CU, + 0x0ABCU, + 0x0A3CU, + 0xFF03U, + 0xFE5FU, + 0x0374U, + 0x0375U, + 0x2116U, + 0x05E0U, + 0xFB40U, + 0xFB40U, + 0x05E0U, + 0x33B5U, + 0x33BBU, + 0x099EU, + 0x091EU, + 0x0A9EU, + 0x0A1EU, + 0x0E2DU, + 0x0275U, + 0x04E9U, + 0x04EBU, + 0x0993U, + 0x311BU, + 0x014FU, + 0x0911U, + 0x0A91U, + 0x0949U, + 0x0AC9U, + 0x01D2U, + 0x24DEU, + 0x1ED1U, + 0x1ED9U, + 0x1ED3U, + 0x1ED5U, + 0x1ED7U, + 0x043EU, + 0x0151U, + 0x020DU, + 0x0913U, + 0x04E7U, + 0x1ECDU, + 0x315AU, + 0x0328U, + 0x0A93U, + 0x0585U, + 0x304AU, + 0x1ECFU, + 0x01A1U, + 0x1EDBU, + 0x1EE3U, + 0x1EDDU, + 0x1EDFU, + 0x1EE1U, + 0x0151U, + 0x01A3U, + 0x020FU, + 0x30AAU, + 0xFF75U, + 0x3157U, + 0x05ABU, + 0x014DU, + 0x1E53U, + 0x1E51U, + 0x0950U, + 0x03C9U, + 0x03D6U, + 0x0461U, + 0x0277U, + 0x047BU, + 0x047DU, + 0x03CEU, + 0x0AD0U, + 0x03BFU, + 0x03CCU, + 0xFF4FU, + 0x0661U, + 0x09E7U, + 0x2460U, + 0x278AU, + 0x0967U, + 0x0AE7U, + 0x0A67U, + 0x0661U, + 0x3021U, + 0x3220U, + 0xFF11U, + 0x09F4U, + 0x2474U, + 0x2488U, + 0x06F1U, + 0x2170U, + 0x0E51U, + 0x01EBU, + 0x01EDU, + 0x0A13U, + 0x0A4BU, + 0x0254U, + 0x24AAU, + 0x25E6U, + 0x2325U, + 0x221FU, + 0x0912U, + 0x094AU, + 0x01FFU, + 0x3049U, + 0x30A9U, + 0xFF6BU, + 0x01FFU, + 0x047FU, + 0x1E4DU, + 0x1E4FU, + 0x3121U, + 0x203EU, + 0xFE4AU, + 0x0305U, + 0xFE49U, + 0xFE4CU, + 0xFE4BU, + 0x00AFU, + 0x09CBU, + 0x094BU, + 0x0ACBU, + 0x3380U, + 0x332BU, + 0x09AAU, + 0x1E55U, + 0x092AU, + 0x21DFU, + 0x21DEU, + 0x0AAAU, + 0x0A2AU, + 0x3071U, + 0x0E2FU, + 0x30D1U, + 0x0484U, + 0x04C0U, + 0x317FU, + 0x2225U, + 0xFD3EU, + 0xF8EDU, + 0xF8ECU, + 0xFF08U, + 0xFE59U, + 0xF8EBU, + 0xFE35U, + 0xFD3FU, + 0xF8F8U, + 0xF8F7U, + 0xFF09U, + 0xFE5AU, + 0xF8F6U, + 0xFE36U, + 0x2202U, + 0x05C0U, + 0x0599U, + 0x33A9U, + 0x05B7U, + 0x05B7U, + 0x05B7U, + 0x05B7U, + 0x05B7U, + 0x05B7U, + 0x05B7U, + 0x05B7U, + 0x05A1U, + 0x3106U, + 0x24DFU, + 0x1E57U, + 0x05E4U, + 0x043FU, + 0xFB44U, + 0xFB44U, + 0x333BU, + 0xFB43U, + 0x067EU, + 0x057AU, + 0x05E4U, + 0xFB57U, + 0xFB58U, + 0x307AU, + 0xFB59U, + 0x30DAU, + 0x04A7U, + 0xFB4EU, + 0x066AU, + 0xFF05U, + 0xFE6AU, + 0x0589U, + 0xFF61U, + 0xFF0EU, + 0xFE52U, + 0x0342U, + 0x22A5U, + 0x20A7U, + 0x338AU, + 0x09ABU, + 0x092BU, + 0x0AABU, + 0x0A2BU, + 0x03C6U, + 0x03D5U, + 0x327AU, + 0x321AU, + 0x326CU, + 0x314DU, + 0x320CU, + 0x0278U, + 0x0E3AU, + 0x03D5U, + 0x01A5U, + 0x0E1EU, + 0x0E1CU, + 0x0E20U, + 0x03C0U, + 0x3273U, + 0x3213U, + 0x3176U, + 0x3265U, + 0x3172U, + 0x3142U, + 0x3205U, + 0x3174U, + 0x3144U, + 0x3175U, + 0x3177U, + 0x3173U, + 0x3074U, + 0x30D4U, + 0x03D6U, + 0x0583U, + 0x031FU, + 0x2295U, + 0x02D6U, + 0xFF0BU, + 0xFE62U, + 0x207AU, + 0xFF50U, + 0x33D8U, + 0x307DU, + 0x261FU, + 0x261CU, + 0x261EU, + 0x261DU, + 0x30DDU, + 0x0E1BU, + 0x3012U, + 0x3020U, + 0x24ABU, + 0x227AU, + 0x211EU, + 0x02B9U, + 0x2035U, + 0x220FU, + 0x2305U, + 0x30FCU, + 0x2318U, + 0x2282U, + 0x2283U, + 0x2237U, + 0x221DU, + 0x03C8U, + 0x0471U, + 0x0486U, + 0x33B0U, + 0x3077U, + 0x30D7U, + 0x33B4U, + 0x33BAU, + 0x0958U, + 0x05A8U, + 0x0642U, + 0xFED6U, + 0xFED7U, + 0xFED8U, + 0x05B8U, + 0x05B8U, + 0x05B8U, + 0x05B8U, + 0x05B8U, + 0x05B8U, + 0x05B8U, + 0x05B8U, + 0x05B8U, + 0x05B8U, + 0x05B8U, + 0x05B8U, + 0x05B8U, + 0x05B8U, + 0x05B8U, + 0x05B8U, + 0x059FU, + 0x3111U, + 0x24E0U, + 0x02A0U, + 0xFF51U, + 0x05E7U, + 0xFB47U, + 0xFB47U, + 0, + 0, + 0, + 0, + 0x05E7U, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0x24ACU, + 0x2669U, + 0x05BBU, + 0x05BBU, + 0x05BBU, + 0x05BBU, + 0x05BBU, + 0x05BBU, + 0x05BBU, + 0x05BBU, + 0x061FU, + 0x055EU, + 0x037EU, + 0xFF1FU, + 0xFF02U, + 0x301EU, + 0x301DU, + 0x201BU, + 0x201BU, + 0x0149U, + 0xFF07U, + 0x057CU, + 0x09B0U, + 0x0155U, + 0x0930U, + 0x221AU, + 0xF8E5U, + 0x33AEU, + 0x33AFU, + 0x33ADU, + 0x05BFU, + 0x05BFU, + 0x0AB0U, + 0x0A30U, + 0x3089U, + 0x30E9U, + 0xFF97U, + 0x09F1U, + 0x09F0U, + 0x0264U, + 0x2236U, + 0x3116U, + 0x0159U, + 0x0157U, + 0x24E1U, + 0x0157U, + 0x0211U, + 0x1E59U, + 0x1E5BU, + 0x1E5DU, + 0x203BU, + 0x2286U, + 0x2287U, + 0xF8E8U, + 0xF6DAU, + 0x0631U, + 0x0580U, + 0xFEAEU, + 0x308CU, + 0, + 0x30ECU, + 0xFF9AU, + 0x05E8U, + 0xFB48U, + 0, + 0, + 0, + 0, + 0x05E8U, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0x223DU, + 0x0597U, + 0x0597U, + 0x2310U, + 0x027EU, + 0x027FU, + 0x09DDU, + 0x095DU, + 0x03C1U, + 0x027DU, + 0x027BU, + 0x02B5U, + 0x03F1U, + 0x02DEU, + 0x3271U, + 0x3211U, + 0x3263U, + 0x3140U, + 0x313AU, + 0x3169U, + 0x3139U, + 0x313BU, + 0x316CU, + 0x3203U, + 0x313FU, + 0x313CU, + 0x316BU, + 0x313DU, + 0x313EU, + 0x316AU, + 0x316DU, + 0x221FU, + 0x0319U, + 0x22BFU, + 0x308AU, + 0x30EAU, + 0xFF98U, + 0x0325U, + 0x030AU, + 0x02BFU, + 0x0559U, + 0x031CU, + 0x02D3U, + 0x02BEU, + 0x0339U, + 0x02D2U, + 0x0213U, + 0x3351U, + 0x1E5FU, + 0x027CU, + 0x027AU, + 0xFF52U, + 0x308DU, + 0x30EDU, + 0xFF9BU, + 0x0E23U, + 0x24ADU, + 0x09DCU, + 0x0931U, + 0x0A5CU, + 0x0691U, + 0xFB8DU, + 0x09E0U, + 0x0960U, + 0x0AE0U, + 0x09C4U, + 0x0944U, + 0x0AC4U, + 0x2590U, + 0x0279U, + 0x02B4U, + 0x308BU, + 0x30EBU, + 0xFF99U, + 0x09F2U, + 0x09F3U, + 0x0E24U, + 0x098BU, + 0x090BU, + 0x0A8BU, + 0x09C3U, + 0x0943U, + 0x0AC3U, + 0x09B8U, + 0x015BU, + 0x1E65U, + 0x0635U, + 0x0938U, + 0xFEBAU, + 0xFEBBU, + 0xFEBCU, + 0x0AB8U, + 0x0A38U, + 0x3055U, + 0x30B5U, + 0xFF7BU, + 0xFDFAU, + 0x05E1U, + 0xFB41U, + 0xFB41U, + 0x05E1U, + 0x0E32U, + 0x0E41U, + 0x0E44U, + 0x0E43U, + 0x0E33U, + 0x0E30U, + 0x0E40U, + 0xF886U, + 0x0E35U, + 0xF885U, + 0x0E34U, + 0x0E42U, + 0xF888U, + 0x0E37U, + 0xF887U, + 0x0E36U, + 0x0E38U, + 0x0E39U, + 0x3119U, + 0x1E67U, + 0x015FU, + 0x0259U, + 0x04D9U, + 0x04DBU, + 0x025AU, + 0x24E2U, + 0x015DU, + 0x0219U, + 0x1E61U, + 0x1E63U, + 0x1E69U, + 0x033CU, + 0x2033U, + 0x02CAU, + 0x0633U, + 0xFEB2U, + 0xFEB3U, + 0xFEB4U, + 0x05B6U, + 0x05B6U, + 0x05B6U, + 0x05B6U, + 0x05B6U, + 0x05B6U, + 0x05B6U, + 0x0592U, + 0x05B6U, + 0x057DU, + 0x305BU, + 0x30BBU, + 0xFF7EU, + 0x061BU, + 0xFF1BU, + 0xFE54U, + 0x309CU, + 0xFF9FU, + 0x3322U, + 0x3323U, + 0x0667U, + 0x09EDU, + 0x2466U, + 0x2790U, + 0x096DU, + 0x0AEDU, + 0x0A6DU, + 0x0667U, + 0x3027U, + 0x3226U, + 0xFF17U, + 0x247AU, + 0x248EU, + 0x06F7U, + 0x2176U, + 0x2470U, + 0x2484U, + 0x2498U, + 0x0E57U, + 0x00ADU, + 0x0577U, + 0x09B6U, + 0x0448U, + 0x0651U, + 0xFC61U, + 0xFC5EU, + 0xFC60U, + 0, + 0xFC62U, + 0xFC5FU, + 0x2592U, + 0x2593U, + 0x2591U, + 0x2592U, + 0x0936U, + 0x0AB6U, + 0x0A36U, + 0x0593U, + 0x3115U, + 0x0449U, + 0x0634U, + 0xFEB6U, + 0xFEB7U, + 0xFEB8U, + 0x03E3U, + 0x20AAU, + 0x20AAU, + 0x05B0U, + 0x05B0U, + 0x05B0U, + 0x05B0U, + 0x05B0U, + 0x05B0U, + 0x05B0U, + 0x05B0U, + 0x05B0U, + 0x04BBU, + 0x03EDU, + 0x05E9U, + 0xFB49U, + 0xFB49U, + 0xFB2CU, + 0xFB2CU, + 0xFB2DU, + 0xFB2DU, + 0x05C1U, + 0x05E9U, + 0xFB2AU, + 0xFB2AU, + 0xFB2BU, + 0xFB2BU, + 0x0282U, + 0x03C3U, + 0x03C2U, + 0x03C2U, + 0x03F2U, + 0x3057U, + 0x30B7U, + 0xFF7CU, + 0x05BDU, + 0x05BDU, + 0x223CU, + 0x05C2U, + 0x3274U, + 0x3214U, + 0x317EU, + 0x3266U, + 0x317AU, + 0x3145U, + 0x317BU, + 0x3206U, + 0x317DU, + 0x317CU, + 0x0666U, + 0x09ECU, + 0x2465U, + 0x278FU, + 0x096CU, + 0x0AECU, + 0x0A6CU, + 0x0666U, + 0x3026U, + 0x3225U, + 0xFF16U, + 0x2479U, + 0x248DU, + 0x06F6U, + 0x2175U, + 0x246FU, + 0x09F9U, + 0x2483U, + 0x2497U, + 0x0E56U, + 0xFF0FU, + 0x017FU, + 0x1E9BU, + 0x263AU, + 0xFF53U, + 0x05C3U, + 0x00ADU, + 0x044CU, + 0x305DU, + 0x30BDU, + 0xFF7FU, + 0x0338U, + 0x0337U, + 0x0E29U, + 0x0E28U, + 0x0E0BU, + 0x0E2AU, + 0x0020U, + 0x2660U, + 0x2660U, + 0x2664U, + 0x24AEU, + 0x033BU, + 0x33C4U, + 0x339DU, + 0x25A9U, + 0x25A4U, + 0x338FU, + 0x339EU, + 0x33CEU, + 0x33D1U, + 0x33D2U, + 0x338EU, + 0x33D5U, + 0x339CU, + 0x33A1U, + 0x25A6U, + 0x25A7U, + 0x25A8U, + 0x25A5U, + 0x25A3U, + 0x33DBU, + 0x09B7U, + 0x0937U, + 0x0AB7U, + 0x3149U, + 0x3185U, + 0x3180U, + 0x3132U, + 0x3165U, + 0x3143U, + 0x3146U, + 0x3138U, + 0xFFE1U, + 0x0336U, + 0x0335U, + 0x2282U, + 0x228AU, + 0x2286U, + 0x227BU, + 0x220BU, + 0x3059U, + 0x30B9U, + 0xFF7DU, + 0x0652U, + 0x2211U, + 0x263CU, + 0x2283U, + 0x228BU, + 0x2287U, + 0x33DCU, + 0x337CU, + 0x09A4U, + 0x22A4U, + 0x22A3U, + 0x0924U, + 0x0AA4U, + 0x0A24U, + 0x0637U, + 0xFEC2U, + 0xFEC3U, + 0x305FU, + 0xFEC4U, + 0x337DU, + 0x30BFU, + 0xFF80U, + 0x0640U, + 0x03C4U, + 0x05EAU, + 0xFB4AU, + 0xFB4AU, + 0xFB4AU, + 0x05EAU, + 0x0167U, + 0x310AU, + 0x0165U, + 0x02A8U, + 0x0163U, + 0x0686U, + 0xFB7BU, + 0xFB7CU, + 0xFB7DU, + 0, + 0x24E3U, + 0x1E71U, + 0x0163U, + 0x1E97U, + 0x1E6BU, + 0x1E6DU, + 0x0442U, + 0x04ADU, + 0x062AU, + 0xFE96U, + 0xFCA2U, + 0xFC0CU, + 0xFE97U, + 0x3066U, + 0xFCA1U, + 0xFC0BU, + 0x0629U, + 0xFE94U, + 0xFE98U, + 0xFCA4U, + 0xFC0EU, + 0xFC73U, + 0x30C6U, + 0xFF83U, + 0x2121U, + 0x260EU, + 0x05A0U, + 0x05A9U, + 0x2469U, + 0x3229U, + 0x247DU, + 0x2491U, + 0x2179U, + 0x02A7U, + 0x05D8U, + 0xFB38U, + 0xFB38U, + 0x05D8U, + 0x04B5U, + 0x059BU, + 0x059BU, + 0x09A5U, + 0x0925U, + 0x0AA5U, + 0x0A25U, + 0x0630U, + 0xFEACU, + 0xF898U, + 0xF897U, + 0x0E4CU, + 0xF896U, + 0x062BU, + 0xFE9AU, + 0xFE9BU, + 0xFE9CU, + 0x2203U, + 0x2234U, + 0x03B8U, + 0x03D1U, + 0x03D1U, + 0x3279U, + 0x3219U, + 0x326BU, + 0x314CU, + 0x320BU, + 0x246CU, + 0x2480U, + 0x2494U, + 0x0E11U, + 0x01ADU, + 0x0E12U, + 0x0E17U, + 0x0E10U, + 0x0E18U, + 0x0E16U, + 0x0482U, + 0x066CU, + 0x066CU, + 0x0663U, + 0x09E9U, + 0x2462U, + 0x278CU, + 0x0969U, + 0x0AE9U, + 0x0A69U, + 0x0663U, + 0x3023U, + 0x3222U, + 0xFF13U, + 0x09F6U, + 0x2476U, + 0x248AU, + 0x06F3U, + 0x2172U, + 0x0E53U, + 0x3394U, + 0x3061U, + 0x30C1U, + 0xFF81U, + 0x3270U, + 0x3210U, + 0x3262U, + 0x3137U, + 0x3202U, + 0x0330U, + 0x0303U, + 0x0303U, + 0x0360U, + 0x223CU, + 0x0334U, + 0x033EU, + 0x2297U, + 0x0596U, + 0x0596U, + 0x0A70U, + 0x0483U, + 0x057FU, + 0x1E6FU, + 0xFF54U, + 0x0569U, + 0x3068U, + 0x30C8U, + 0xFF84U, + 0x02E5U, + 0x02E9U, + 0x02E6U, + 0x02E8U, + 0x02E7U, + 0x01BDU, + 0x0185U, + 0x01A8U, + 0x0384U, + 0x3327U, + 0x0E0FU, + 0x3014U, + 0xFE5DU, + 0xFE39U, + 0x3015U, + 0xFE5EU, + 0xFE3AU, + 0x0E15U, + 0x01ABU, + 0x24AFU, + 0xF8EAU, + 0xF6DBU, + 0x0288U, + 0x25BCU, + 0x25C4U, + 0x25BAU, + 0x25B2U, + 0x02A6U, + 0x05E6U, + 0xFB46U, + 0xFB46U, + 0x05E6U, + 0x0446U, + 0x05B5U, + 0x05B5U, + 0x05B5U, + 0x05B5U, + 0x05B5U, + 0x05B5U, + 0x05B5U, + 0x05B5U, + 0x045BU, + 0x099FU, + 0x091FU, + 0x0A9FU, + 0x0A1FU, + 0x0679U, + 0xFB67U, + 0xFB68U, + 0xFB69U, + 0x09A0U, + 0x0920U, + 0x0AA0U, + 0x0A20U, + 0x0287U, + 0x3064U, + 0x30C4U, + 0xFF82U, + 0x3063U, + 0x30C3U, + 0xFF6FU, + 0x246BU, + 0x247FU, + 0x2493U, + 0x217BU, + 0x2473U, + 0x5344U, + 0x2487U, + 0x249BU, + 0x0662U, + 0x09E8U, + 0x2461U, + 0x278BU, + 0x0968U, + 0x2025U, + 0xFE30U, + 0x0AE8U, + 0x0A68U, + 0x0662U, + 0x3022U, + 0x3221U, + 0xFF12U, + 0x09F5U, + 0x2475U, + 0x2489U, + 0x06F2U, + 0x2171U, + 0x01BBU, + 0x0E52U, + 0x0289U, + 0x0989U, + 0x3128U, + 0x016DU, + 0x01D4U, + 0x24E4U, + 0x1E77U, + 0x0443U, + 0x0951U, + 0x0171U, + 0x0215U, + 0x0909U, + 0x01D8U, + 0x1E73U, + 0x01DAU, + 0x04F1U, + 0x01DCU, + 0x01D6U, + 0x1EE5U, + 0x0A89U, + 0x0A09U, + 0x3046U, + 0x1EE7U, + 0x01B0U, + 0x1EE9U, + 0x1EF1U, + 0x1EEBU, + 0x1EEDU, + 0x1EEFU, + 0x0171U, + 0x04F3U, + 0x0217U, + 0x30A6U, + 0xFF73U, + 0x0479U, + 0x315CU, + 0x016BU, + 0x04EFU, + 0x1E7BU, + 0x0A41U, + 0xFF55U, + 0x2017U, + 0xFF3FU, + 0xFE33U, + 0xFE4FU, + 0x222AU, + 0x2200U, + 0x0173U, + 0x24B0U, + 0x2580U, + 0x05C4U, + 0x03C5U, + 0x03CBU, + 0x03B0U, + 0x028AU, + 0x03CDU, + 0x031DU, + 0x02D4U, + 0x0A73U, + 0x016FU, + 0x045EU, + 0x3045U, + 0x30A5U, + 0xFF69U, + 0x04AFU, + 0x04B1U, + 0x0169U, + 0x1E79U, + 0x1E75U, + 0x098AU, + 0x090AU, + 0x0A8AU, + 0x0A0AU, + 0x0A42U, + 0x09C2U, + 0x0942U, + 0x0AC2U, + 0x09C1U, + 0x0941U, + 0x0AC1U, + 0x0935U, + 0x0AB5U, + 0x0A35U, + 0x30F7U, + 0x05D5U, + 0xFB35U, + 0xFB35U, + 0xFB35U, + 0x05D5U, + 0xFB4BU, + 0xFB4BU, + 0x05F0U, + 0x05F1U, + 0x24E5U, + 0x1E7FU, + 0x0432U, + 0x06A4U, + 0xFB6BU, + 0xFB6CU, + 0xFB6DU, + 0x30F9U, + 0x2640U, + 0x007CU, + 0x030DU, + 0x0329U, + 0x02CCU, + 0x02C8U, + 0x057EU, + 0x028BU, + 0x30F8U, + 0x09CDU, + 0x094DU, + 0x0ACDU, + 0x0983U, + 0x0903U, + 0x0A83U, + 0xFF56U, + 0x0578U, + 0x309EU, + 0x30FEU, + 0x309BU, + 0xFF9EU, + 0x30FAU, + 0x24B1U, + 0x1E7DU, + 0x028CU, + 0x3094U, + 0x30F4U, + 0x1E83U, + 0x3159U, + 0x308FU, + 0x30EFU, + 0xFF9CU, + 0x3158U, + 0x308EU, + 0x30EEU, + 0x3357U, + 0x301CU, + 0xFE34U, + 0x0648U, + 0xFEEEU, + 0x0624U, + 0xFE86U, + 0x33DDU, + 0x24E6U, + 0x0175U, + 0x1E85U, + 0x1E87U, + 0x1E89U, + 0x3091U, + 0x2118U, + 0x30F1U, + 0x315EU, + 0x315DU, + 0x1E81U, + 0x25E6U, + 0x25CBU, + 0x25D9U, + 0x300EU, + 0xFE43U, + 0x300FU, + 0xFE44U, + 0x25C7U, + 0x25C8U, + 0x25BFU, + 0x25BDU, + 0x25C3U, + 0x25C1U, + 0x3016U, + 0x3017U, + 0x25B9U, + 0x25B7U, + 0x25ABU, + 0x263AU, + 0x25A1U, + 0x2606U, + 0x260FU, + 0x3018U, + 0x3019U, + 0x25B5U, + 0x25B3U, + 0x3090U, + 0x30F0U, + 0x315FU, + 0xFF57U, + 0x3092U, + 0x30F2U, + 0xFF66U, + 0x20A9U, + 0xFFE6U, + 0x0E27U, + 0x24B2U, + 0x1E98U, + 0x02B7U, + 0x028DU, + 0x01BFU, + 0x033DU, + 0x3112U, + 0x24E7U, + 0x1E8DU, + 0x1E8BU, + 0x056DU, + 0x03BEU, + 0xFF58U, + 0x24B3U, + 0x02E3U, + 0x334EU, + 0x09AFU, + 0x092FU, + 0x3152U, + 0x0AAFU, + 0x0A2FU, + 0x3084U, + 0x30E4U, + 0xFF94U, + 0x3151U, + 0x0E4EU, + 0x3083U, + 0x30E3U, + 0xFF6CU, + 0x0463U, + 0x24E8U, + 0x0177U, + 0x1E8FU, + 0x1EF5U, + 0x064AU, + 0x06D2U, + 0xFBAFU, + 0xFEF2U, + 0x0626U, + 0xFE8AU, + 0xFE8BU, + 0xFE8CU, + 0xFEF3U, + 0xFEF4U, + 0xFCDDU, + 0xFC58U, + 0xFC94U, + 0x06D1U, + 0x3156U, + 0xFFE5U, + 0x3155U, + 0x3186U, + 0x05AAU, + 0x05AAU, + 0x044BU, + 0x04F9U, + 0x3181U, + 0x3183U, + 0x3182U, + 0x059AU, + 0x1EF3U, + 0x01B4U, + 0x1EF7U, + 0x0575U, + 0x0457U, + 0x3162U, + 0x262FU, + 0x0582U, + 0xFF59U, + 0x05D9U, + 0xFB39U, + 0xFB39U, + 0x05D9U, + 0x05F2U, + 0xFB1FU, + 0x3088U, + 0x3189U, + 0x30E8U, + 0xFF96U, + 0x315BU, + 0x3087U, + 0x30E7U, + 0xFF6EU, + 0x03F3U, + 0x3188U, + 0x3187U, + 0x0E22U, + 0x0E0DU, + 0x24B4U, + 0x037AU, + 0x0345U, + 0x01A6U, + 0x1E99U, + 0x02B8U, + 0x1EF9U, + 0x028EU, + 0x3086U, + 0x318CU, + 0x30E6U, + 0xFF95U, + 0x3160U, + 0x046BU, + 0x046DU, + 0x0467U, + 0x0469U, + 0x3085U, + 0x30E5U, + 0xFF6DU, + 0x318BU, + 0x318AU, + 0x09DFU, + 0x095FU, + 0x0566U, + 0x017AU, + 0x095BU, + 0x0A5BU, + 0x0638U, + 0xFEC6U, + 0xFEC7U, + 0x3056U, + 0xFEC8U, + 0x0632U, + 0xFEB0U, + 0x30B6U, + 0x0595U, + 0x0594U, + 0x0598U, + 0x05D6U, + 0xFB36U, + 0xFB36U, + 0x05D6U, + 0x3117U, + 0x24E9U, + 0x1E91U, + 0x0291U, + 0x017CU, + 0x017CU, + 0x1E93U, + 0x0437U, + 0x0499U, + 0x04DFU, + 0x305CU, + 0x30BCU, + 0x0660U, + 0x09E6U, + 0x0966U, + 0x0AE6U, + 0x0A66U, + 0x0660U, + 0xFF10U, + 0x06F0U, + 0x0E50U, + 0xFEFFU, + 0x200CU, + 0x200BU, + 0x03B6U, + 0x3113U, + 0x056AU, + 0x04C2U, + 0x0436U, + 0x0497U, + 0x04DDU, + 0x3058U, + 0x30B8U, + 0x05AEU, + 0x1E95U, + 0xFF5AU, + 0x305EU, + 0x30BEU, + 0x24B5U, + 0x0290U, + 0x01B6U, + 0x305AU, + 0x30BAU, #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ 0 @@ -2964,4 +9434,4 @@ }; -/* END */ +/* END */ diff --git a/src/libs/freetype2/psnames/rules.mk b/src/libs/freetype2/psnames/rules.mk index 4ce92f41e7..06bd161e34 100644 --- a/src/libs/freetype2/psnames/rules.mk +++ b/src/libs/freetype2/psnames/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2001 by +# Copyright 1996-2000, 2001, 2003 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -15,25 +15,24 @@ # PSNames driver directory # -PSNAMES_DIR := $(SRC_)psnames -PSNAMES_DIR_ := $(PSNAMES_DIR)$(SEP) +PSNAMES_DIR := $(SRC_DIR)/psnames # compilation flags for the driver # -PSNAMES_COMPILE := $(FT_COMPILE) $I$(PSNAMES_DIR) +PSNAMES_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(PSNAMES_DIR)) # PSNames driver sources (i.e., C files) # -PSNAMES_DRV_SRC := $(PSNAMES_DIR_)psmodule.c +PSNAMES_DRV_SRC := $(PSNAMES_DIR)/psmodule.c # PSNames driver headers # PSNAMES_DRV_H := $(PSNAMES_DRV_SRC:%.c=%.h) \ - $(PSNAMES_DIR_)pstables.h \ - $(PSNAMES_DIR_)psnamerr.h + $(PSNAMES_DIR)/pstables.h \ + $(PSNAMES_DIR)/psnamerr.h # PSNames driver object(s) @@ -41,25 +40,25 @@ PSNAMES_DRV_H := $(PSNAMES_DRV_SRC:%.c=%.h) \ # PSNAMES_DRV_OBJ_M is used during `multi' builds # PSNAMES_DRV_OBJ_S is used during `single' builds # -PSNAMES_DRV_OBJ_M := $(PSNAMES_DRV_SRC:$(PSNAMES_DIR_)%.c=$(OBJ_)%.$O) -PSNAMES_DRV_OBJ_S := $(OBJ_)psnames.$O +PSNAMES_DRV_OBJ_M := $(PSNAMES_DRV_SRC:$(PSNAMES_DIR)/%.c=$(OBJ_DIR)/%.$O) +PSNAMES_DRV_OBJ_S := $(OBJ_DIR)/psnames.$O # PSNames driver source file for single build # -PSNAMES_DRV_SRC_S := $(PSNAMES_DIR_)psmodule.c +PSNAMES_DRV_SRC_S := $(PSNAMES_DIR)/psmodule.c # PSNames driver - single object # $(PSNAMES_DRV_OBJ_S): $(PSNAMES_DRV_SRC_S) $(PSNAMES_DRV_SRC) \ $(FREETYPE_H) $(PSNAMES_DRV_H) - $(PSNAMES_COMPILE) $T$@ $(PSNAMES_DRV_SRC_S) + $(PSNAMES_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(PSNAMES_DRV_SRC_S)) # PSNames driver - multiple objects # -$(OBJ_)%.$O: $(PSNAMES_DIR_)%.c $(FREETYPE_H) $(PSNAMES_DRV_H) - $(PSNAMES_COMPILE) $T$@ $< +$(OBJ_DIR)/%.$O: $(PSNAMES_DIR)/%.c $(FREETYPE_H) $(PSNAMES_DRV_H) + $(PSNAMES_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) # update main driver object lists @@ -68,4 +67,4 @@ DRV_OBJS_S += $(PSNAMES_DRV_OBJ_S) DRV_OBJS_M += $(PSNAMES_DRV_OBJ_M) -# EOF +# EOF diff --git a/src/libs/freetype2/raster/descrip.mms b/src/libs/freetype2/raster/descrip.mms index c45451d18c..d0650ebbf7 100644 --- a/src/libs/freetype2/raster/descrip.mms +++ b/src/libs/freetype2/raster/descrip.mms @@ -20,4 +20,4 @@ OBJS=raster.obj all : $(OBJS) library [--.lib]freetype.olb $(OBJS) -# EOF +# EOF diff --git a/src/libs/freetype2/raster/ftraster.c b/src/libs/freetype2/raster/ftraster.c index d988610592..757cba758c 100644 --- a/src/libs/freetype2/raster/ftraster.c +++ b/src/libs/freetype2/raster/ftraster.c @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph rasterizer (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -687,8 +687,8 @@ static Bool Insert_Y_Turn( RAS_ARGS Int y ) { - PLong y_turns; - Int y2, n; + PLong y_turns; + Int y2, n; n = ras.numTurns - 1; @@ -710,12 +710,12 @@ if ( n < 0 ) { + ras.maxBuff--; if ( ras.maxBuff <= ras.top ) { ras.error = Raster_Err_Overflow; return FAILURE; } - ras.maxBuff--; ras.numTurns++; ras.sizeBuff[-ras.numTurns] = y; } @@ -917,7 +917,7 @@ /* Take care: miny-y1 can be a very large value; we use */ /* a slow MulDiv function to avoid clipping bugs */ x1 += SMulDiv( Dx, miny - y1, Dy ); - e1 = TRUNC( miny ); + e1 = (Int)TRUNC( miny ); f1 = 0; } else @@ -3285,4 +3285,4 @@ }; -/* END */ +/* END */ diff --git a/src/libs/freetype2/raster/ftraster.h b/src/libs/freetype2/raster/ftraster.h index 3714c4f3df..80fe46deba 100644 --- a/src/libs/freetype2/raster/ftraster.h +++ b/src/libs/freetype2/raster/ftraster.h @@ -43,4 +43,4 @@ FT_END_HEADER #endif /* __FTRASTER_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/raster/ftrend1.c b/src/libs/freetype2/raster/ftrend1.c index bd15a2f2d9..a17ef9b613 100644 --- a/src/libs/freetype2/raster/ftrend1.c +++ b/src/libs/freetype2/raster/ftrend1.c @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph rasterizer interface (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -140,10 +140,10 @@ /* compute the control box, and grid fit it */ FT_Outline_Get_CBox( outline, &cbox ); - cbox.xMin &= -64; - cbox.yMin &= -64; - cbox.xMax = ( cbox.xMax + 63 ) & -64; - cbox.yMax = ( cbox.yMax + 63 ) & -64; + cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); + cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); + cbox.xMax = FT_PIX_CEIL( cbox.xMax ); + cbox.yMax = FT_PIX_CEIL( cbox.yMax ); width = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 ); height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 ); @@ -151,17 +151,17 @@ memory = render->root.memory; /* release old bitmap buffer */ - if ( slot->flags & FT_GLYPH_OWN_BITMAP ) + if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) { FT_FREE( bitmap->buffer ); - slot->flags &= ~FT_GLYPH_OWN_BITMAP; + slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; } /* allocate new one, depends on pixel format */ if ( !( mode & FT_RENDER_MODE_MONO ) ) { /* we pad to 32 bits, only for backwards compatibility with FT 1.x */ - pitch = ( width + 3 ) & -4; + pitch = FT_PAD_CEIL( width, 4 ); bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; bitmap->num_grays = 256; } @@ -178,7 +178,7 @@ if ( FT_ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) ) goto Exit; - slot->flags |= FT_GLYPH_OWN_BITMAP; + slot->internal->flags |= FT_GLYPH_OWN_BITMAP; /* translate outline to render it into the bitmap */ FT_Outline_Translate( outline, -cbox.xMin, -cbox.yMin ); @@ -193,9 +193,9 @@ /* render outline into the bitmap */ error = render->raster_render( render->raster, ¶ms ); - + FT_Outline_Translate( outline, cbox.xMin, cbox.yMin ); - + if ( error ) goto Exit; @@ -212,7 +212,7 @@ const FT_Renderer_Class ft_raster1_renderer_class = { { - ft_module_renderer, + FT_MODULE_RENDERER, sizeof( FT_RendererRec ), "raster1", @@ -245,7 +245,7 @@ const FT_Renderer_Class ft_raster5_renderer_class = { { - ft_module_renderer, + FT_MODULE_RENDERER, sizeof( FT_RendererRec ), "raster5", @@ -270,4 +270,4 @@ }; -/* END */ +/* END */ diff --git a/src/libs/freetype2/raster/ftrend1.h b/src/libs/freetype2/raster/ftrend1.h index 7cf6ce99b3..76e9a5f581 100644 --- a/src/libs/freetype2/raster/ftrend1.h +++ b/src/libs/freetype2/raster/ftrend1.h @@ -41,4 +41,4 @@ FT_END_HEADER #endif /* __FTREND1_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/raster/module.mk b/src/libs/freetype2/raster/module.mk index 2f4064202c..8a3136413d 100644 --- a/src/libs/freetype2/raster/module.mk +++ b/src/libs/freetype2/raster/module.mk @@ -19,4 +19,4 @@ add_raster_module: $(OPEN_DRIVER)ft_raster1_renderer_class$(CLOSE_DRIVER) $(ECHO_DRIVER)raster $(ECHO_DRIVER_DESC)monochrome bitmap renderer$(ECHO_DRIVER_DONE) -# EOF +# EOF diff --git a/src/libs/freetype2/raster/raster.c b/src/libs/freetype2/raster/raster.c index fe764d234b..f13a67a209 100644 --- a/src/libs/freetype2/raster/raster.c +++ b/src/libs/freetype2/raster/raster.c @@ -23,4 +23,4 @@ #include "ftrend1.c" -/* END */ +/* END */ diff --git a/src/libs/freetype2/raster/rasterrs.h b/src/libs/freetype2/raster/rasterrs.h index 615a270e4f..5df9a7ab1e 100644 --- a/src/libs/freetype2/raster/rasterrs.h +++ b/src/libs/freetype2/raster/rasterrs.h @@ -38,4 +38,4 @@ #endif /* __RASTERRS_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/raster/rules.mk b/src/libs/freetype2/raster/rules.mk index ebfaf12130..0dc8782ea4 100644 --- a/src/libs/freetype2/raster/rules.mk +++ b/src/libs/freetype2/raster/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2001 by +# Copyright 1996-2000, 2001, 2003 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -13,58 +13,57 @@ # fully. -# raster1 driver directory +# raster driver directory # -RAS1_DIR := $(SRC_)raster -RAS1_DIR_ := $(RAS1_DIR)$(SEP) +RASTER_DIR := $(SRC_DIR)/raster # compilation flags for the driver # -RAS1_COMPILE := $(FT_COMPILE) $I$(RAS1_DIR) +RASTER_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(RASTER_DIR)) -# raster1 driver sources (i.e., C files) +# raster driver sources (i.e., C files) # -RAS1_DRV_SRC := $(RAS1_DIR_)ftraster.c \ - $(RAS1_DIR_)ftrend1.c +RASTER_DRV_SRC := $(RASTER_DIR)/ftraster.c \ + $(RASTER_DIR)/ftrend1.c -# raster1 driver headers +# raster driver headers # -RAS1_DRV_H := $(RAS1_DRV_SRC:%.c=%.h) \ - $(RAS1_DIR_)rasterrs.h +RASTER_DRV_H := $(RASTER_DRV_SRC:%.c=%.h) \ + $(RASTER_DIR)/rasterrs.h -# raster1 driver object(s) +# raster driver object(s) # -# RAS1_DRV_OBJ_M is used during `multi' builds. -# RAS1_DRV_OBJ_S is used during `single' builds. +# RASTER_DRV_OBJ_M is used during `multi' builds. +# RASTER_DRV_OBJ_S is used during `single' builds. # -RAS1_DRV_OBJ_M := $(RAS1_DRV_SRC:$(RAS1_DIR_)%.c=$(OBJ_)%.$O) -RAS1_DRV_OBJ_S := $(OBJ_)raster.$O +RASTER_DRV_OBJ_M := $(RASTER_DRV_SRC:$(RASTER_DIR)/%.c=$(OBJ_DIR)/%.$O) +RASTER_DRV_OBJ_S := $(OBJ_DIR)/raster.$O -# raster1 driver source file for single build +# raster driver source file for single build # -RAS1_DRV_SRC_S := $(RAS1_DIR_)raster.c +RASTER_DRV_SRC_S := $(RASTER_DIR)/raster.c -# raster1 driver - single object +# raster driver - single object # -$(RAS1_DRV_OBJ_S): $(RAS1_DRV_SRC_S) $(RAS1_DRV_SRC) \ - $(FREETYPE_H) $(RAS1_DRV_H) - $(RAS1_COMPILE) $T$@ $(RAS1_DRV_SRC_S) +$(RASTER_DRV_OBJ_S): $(RASTER_DRV_SRC_S) $(RASTER_DRV_SRC) \ + $(FREETYPE_H) $(RASTER_DRV_H) + $(RASTER_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(RASTER_DRV_SRC_S)) -# raster1 driver - multiple objects +# raster driver - multiple objects # -$(OBJ_)%.$O: $(RAS1_DIR_)%.c $(FREETYPE_H) $(RAS1_DRV_H) - $(RAS1_COMPILE) $T$@ $< +$(OBJ_DIR)/%.$O: $(RASTER_DIR)/%.c $(FREETYPE_H) $(RASTER_DRV_H) + $(RASTER_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) # update main driver object lists # -DRV_OBJS_S += $(RAS1_DRV_OBJ_S) -DRV_OBJS_M += $(RAS1_DRV_OBJ_M) +DRV_OBJS_S += $(RASTER_DRV_OBJ_S) +DRV_OBJS_M += $(RASTER_DRV_OBJ_M) -# EOF +# EOF diff --git a/src/libs/freetype2/sfnt/Jamfile b/src/libs/freetype2/sfnt/Jamfile index 0cfff8d569..0399b6d245 100644 --- a/src/libs/freetype2/sfnt/Jamfile +++ b/src/libs/freetype2/sfnt/Jamfile @@ -10,7 +10,7 @@ UseFreeTypeHeaders ; if $(FT2_MULTI) { - _sources = sfobjs sfdriver ttcmap ttcmap0 ttpost ttload ttsbit ; + _sources = sfobjs sfdriver ttcmap0 ttpost ttload ttsbit ; } else { diff --git a/src/libs/freetype2/sfnt/descrip.mms b/src/libs/freetype2/sfnt/descrip.mms index 0f5f3edad8..811c8b3ee5 100644 --- a/src/libs/freetype2/sfnt/descrip.mms +++ b/src/libs/freetype2/sfnt/descrip.mms @@ -20,4 +20,4 @@ OBJS=sfnt.obj all : $(OBJS) library [--.lib]freetype.olb $(OBJS) -# EOF +# EOF diff --git a/src/libs/freetype2/sfnt/module.mk b/src/libs/freetype2/sfnt/module.mk index 41a3211271..52607e2afc 100644 --- a/src/libs/freetype2/sfnt/module.mk +++ b/src/libs/freetype2/sfnt/module.mk @@ -19,4 +19,4 @@ add_sfnt_module: $(OPEN_DRIVER)sfnt_module_class$(CLOSE_DRIVER) $(ECHO_DRIVER)sfnt $(ECHO_DRIVER_DESC)helper module for TrueType & OpenType formats$(ECHO_DRIVER_DONE) -# EOF +# EOF diff --git a/src/libs/freetype2/sfnt/rules.mk b/src/libs/freetype2/sfnt/rules.mk index 08690f181c..f132385491 100644 --- a/src/libs/freetype2/sfnt/rules.mk +++ b/src/libs/freetype2/sfnt/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2002 by +# Copyright 1996-2000, 2002, 2003 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -15,29 +15,27 @@ # SFNT driver directory # -SFNT_DIR := $(SRC_)sfnt -SFNT_DIR_ := $(SFNT_DIR)$(SEP) +SFNT_DIR := $(SRC_DIR)/sfnt # compilation flags for the driver # -SFNT_COMPILE := $(FT_COMPILE) $I$(SFNT_DIR) +SFNT_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(SFNT_DIR)) # SFNT driver sources (i.e., C files) # -SFNT_DRV_SRC := $(SFNT_DIR_)ttload.c \ - $(SFNT_DIR_)ttcmap.c \ - $(SFNT_DIR_)ttcmap0.c \ - $(SFNT_DIR_)ttsbit.c \ - $(SFNT_DIR_)ttpost.c \ - $(SFNT_DIR_)sfobjs.c \ - $(SFNT_DIR_)sfdriver.c +SFNT_DRV_SRC := $(SFNT_DIR)/ttload.c \ + $(SFNT_DIR)/ttcmap0.c \ + $(SFNT_DIR)/ttsbit.c \ + $(SFNT_DIR)/ttpost.c \ + $(SFNT_DIR)/sfobjs.c \ + $(SFNT_DIR)/sfdriver.c # SFNT driver headers # SFNT_DRV_H := $(SFNT_DRV_SRC:%c=%h) \ - $(SFNT_DIR_)sferrors.h + $(SFNT_DIR)/sferrors.h # SFNT driver object(s) @@ -45,25 +43,25 @@ SFNT_DRV_H := $(SFNT_DRV_SRC:%c=%h) \ # SFNT_DRV_OBJ_M is used during `multi' builds. # SFNT_DRV_OBJ_S is used during `single' builds. # -SFNT_DRV_OBJ_M := $(SFNT_DRV_SRC:$(SFNT_DIR_)%.c=$(OBJ_)%.$O) -SFNT_DRV_OBJ_S := $(OBJ_)sfnt.$O +SFNT_DRV_OBJ_M := $(SFNT_DRV_SRC:$(SFNT_DIR)/%.c=$(OBJ_DIR)/%.$O) +SFNT_DRV_OBJ_S := $(OBJ_DIR)/sfnt.$O # SFNT driver source file for single build # -SFNT_DRV_SRC_S := $(SFNT_DIR_)sfnt.c +SFNT_DRV_SRC_S := $(SFNT_DIR)/sfnt.c # SFNT driver - single object # $(SFNT_DRV_OBJ_S): $(SFNT_DRV_SRC_S) $(SFNT_DRV_SRC) \ $(FREETYPE_H) $(SFNT_DRV_H) - $(SFNT_COMPILE) $T$@ $(SFNT_DRV_SRC_S) + $(SFNT_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(SFNT_DRV_SRC_S)) # SFNT driver - multiple objects # -$(OBJ_)%.$O: $(SFNT_DIR_)%.c $(FREETYPE_H) $(SFNT_DRV_H) - $(SFNT_COMPILE) $T$@ $< +$(OBJ_DIR)/%.$O: $(SFNT_DIR)/%.c $(FREETYPE_H) $(SFNT_DRV_H) + $(SFNT_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) # update main driver object lists @@ -72,4 +70,4 @@ DRV_OBJS_S += $(SFNT_DRV_OBJ_S) DRV_OBJS_M += $(SFNT_DRV_OBJ_M) -# EOF +# EOF diff --git a/src/libs/freetype2/sfnt/sfdriver.c b/src/libs/freetype2/sfnt/sfdriver.c index 72bbb74b20..7da53d2f15 100644 --- a/src/libs/freetype2/sfnt/sfdriver.c +++ b/src/libs/freetype2/sfnt/sfdriver.c @@ -4,7 +4,7 @@ /* */ /* High-level SFNT driver interface (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,9 +22,10 @@ #include "sfdriver.h" #include "ttload.h" -#include "ttcmap.h" #include "sfobjs.h" +#include "sferrors.h" + #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS #include "ttsbit.h" #endif @@ -33,6 +34,18 @@ #include "ttpost.h" #endif +#include "ttcmap0.h" + +#include FT_SERVICE_GLYPH_DICT_H +#include FT_SERVICE_POSTSCRIPT_NAME_H +#include FT_SERVICE_SFNT_H +#include FT_SERVICE_TT_CMAP_H + + + /* + * SFNT TABLE SERVICE + * + */ static void* get_sfnt_table( TT_Face face, @@ -79,11 +92,22 @@ } + static const FT_Service_SFNT_TableRec sfnt_service_sfnt_table = + { + (FT_SFNT_TableLoadFunc)tt_face_load_any, + (FT_SFNT_TableGetFunc) get_sfnt_table + }; + + #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES + /* + * GLYPH DICT SERVICE + * + */ static FT_Error - get_sfnt_glyph_name( TT_Face face, + sfnt_get_glyph_name( TT_Face face, FT_UInt glyph_index, FT_Pointer buffer, FT_UInt buffer_max ) @@ -109,16 +133,30 @@ } + static const FT_Service_GlyphDictRec sfnt_service_glyph_dict = + { + (FT_GlyphDict_GetNameFunc) sfnt_get_glyph_name, + (FT_GlyphDict_NameIndexFunc)NULL + }; + +#endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ + + + /* + * POSTSCRIPT NAME SERVICE + * + */ + static const char* - get_sfnt_postscript_name( TT_Face face ) + sfnt_get_ps_name( TT_Face face ) { FT_Int n, found_win, found_apple; const char* result = NULL; /* shouldn't happen, but just in case to avoid memory leaks */ - if ( face->root.internal->postscript_name ) - return face->root.internal->postscript_name; + if ( face->postscript_name ) + return face->postscript_name; /* scan the name table to see whether we have a Postscript name here, */ /* either in Macintosh or Windows platform encodings */ @@ -149,7 +187,9 @@ FT_Memory memory = face->root.memory; TT_NameEntryRec* name = face->name_table.names + found_win; FT_UInt len = name->stringLength / 2; - FT_Error error; + FT_Error error = SFNT_Err_Ok; + + FT_UNUSED( error ); if ( !FT_ALLOC( result, name->stringLength + 1 ) ) @@ -189,7 +229,9 @@ FT_Memory memory = face->root.memory; TT_NameEntryRec* name = face->name_table.names + found_apple; FT_UInt len = name->stringLength; - FT_Error error; + FT_Error error = SFNT_Err_Ok; + + FT_UNUSED( error ); if ( !FT_ALLOC( result, len + 1 ) ) @@ -211,12 +253,42 @@ } Exit: - face->root.internal->postscript_name = result; + face->postscript_name = result; return result; } + static const FT_Service_PsFontNameRec sfnt_service_ps_name = + { + (FT_PsName_GetFunc)sfnt_get_ps_name + }; -#endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ + + /* + * TT CMAP INFO + * + */ + static const FT_Service_TTCMapsRec tt_service_get_cmap_info = + { + (TT_CMap_Info_GetFunc)tt_get_cmap_info + }; + + + /* + * SERVICE LIST + * + */ + + static const FT_ServiceDescRec sfnt_services[] = + { + { FT_SERVICE_ID_SFNT_TABLE, &sfnt_service_sfnt_table }, + { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &sfnt_service_ps_name }, +#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES + { FT_SERVICE_ID_GLYPH_DICT, &sfnt_service_glyph_dict }, +#endif + { FT_SERVICE_ID_TT_CMAP, &tt_service_get_cmap_info }, + + { NULL, NULL } + }; FT_CALLBACK_DEF( FT_Module_Interface ) @@ -231,15 +303,7 @@ if ( ft_strcmp( module_interface, "load_sfnt" ) == 0 ) return (FT_Module_Interface)tt_face_load_any; -#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES - if ( ft_strcmp( module_interface, "glyph_name" ) == 0 ) - return (FT_Module_Interface)get_sfnt_glyph_name; -#endif - - if ( ft_strcmp( module_interface, "postscript_name" ) == 0 ) - return (FT_Module_Interface)get_sfnt_postscript_name; - - return 0; + return ft_service_list_lookup( sfnt_services, module_interface ); } @@ -279,9 +343,11 @@ /* see `ttload.h' */ tt_face_load_bitmap_header, - /* see `ttsbit.h' */ + /* see `ttsbit.h' and `sfnt.h' */ tt_face_set_sbit_strike, tt_face_load_sbit_strikes, + tt_find_sbit_image, + tt_load_sbit_metrics, tt_face_load_sbit_image, tt_face_free_sbit_strikes, @@ -290,6 +356,8 @@ 0, 0, 0, + 0, + 0, 0, 0, @@ -308,9 +376,6 @@ #endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ - /* see `ttcmap.h' */ - tt_face_load_charmap, - tt_face_free_charmap, }; @@ -332,4 +397,4 @@ }; -/* END */ +/* END */ diff --git a/src/libs/freetype2/sfnt/sfdriver.h b/src/libs/freetype2/sfnt/sfdriver.h index 83f647cda6..92db79694d 100644 --- a/src/libs/freetype2/sfnt/sfdriver.h +++ b/src/libs/freetype2/sfnt/sfdriver.h @@ -35,4 +35,4 @@ FT_END_HEADER #endif /* __SFDRIVER_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/sfnt/sferrors.h b/src/libs/freetype2/sfnt/sferrors.h index 71bddad8f5..fd2736b6c8 100644 --- a/src/libs/freetype2/sfnt/sferrors.h +++ b/src/libs/freetype2/sfnt/sferrors.h @@ -36,4 +36,4 @@ #endif /* __SFERRORS_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/sfnt/sfnt.c b/src/libs/freetype2/sfnt/sfnt.c index 75a26eb7cb..90c1bee911 100644 --- a/src/libs/freetype2/sfnt/sfnt.c +++ b/src/libs/freetype2/sfnt/sfnt.c @@ -4,7 +4,7 @@ /* */ /* Single object library component. */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,7 +20,6 @@ #include <ft2build.h> #include "ttload.c" -#include "ttcmap.c" #include "ttcmap0.c" #include "sfobjs.c" #include "sfdriver.c" @@ -34,4 +33,4 @@ #endif -/* END */ +/* END */ diff --git a/src/libs/freetype2/sfnt/sfobjs.c b/src/libs/freetype2/sfnt/sfobjs.c index 331be8006d..cb304fdc18 100644 --- a/src/libs/freetype2/sfnt/sfobjs.c +++ b/src/libs/freetype2/sfnt/sfobjs.c @@ -4,7 +4,7 @@ /* */ /* SFNT object management (base). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,10 +21,9 @@ #include "ttload.h" #include "ttcmap0.h" #include FT_INTERNAL_SFNT_H -#include FT_INTERNAL_POSTSCRIPT_NAMES_H #include FT_TRUETYPE_IDS_H #include FT_TRUETYPE_TAGS_H - +#include FT_SERVICE_POSTSCRIPT_CMAPS_H #include "sferrors.h" @@ -258,9 +257,11 @@ { if ( rec->string == NULL ) { - FT_Error error; + FT_Error error = SFNT_Err_Ok; FT_Stream stream = face->name_table.stream; + FT_UNUSED( error ); + if ( FT_NEW_ARRAY ( rec->string, rec->stringLength ) || FT_STREAM_SEEK( rec->stringOffset ) || @@ -305,11 +306,11 @@ { TT_PLATFORM_MICROSOFT, TT_MS_ID_SYMBOL_CS, FT_ENCODING_MS_SYMBOL }, { TT_PLATFORM_MICROSOFT, TT_MS_ID_UCS_4, FT_ENCODING_UNICODE }, { TT_PLATFORM_MICROSOFT, TT_MS_ID_UNICODE_CS, FT_ENCODING_UNICODE }, - { TT_PLATFORM_MICROSOFT, TT_MS_ID_SJIS, FT_ENCODING_MS_SJIS }, - { TT_PLATFORM_MICROSOFT, TT_MS_ID_GB2312, FT_ENCODING_MS_GB2312 }, - { TT_PLATFORM_MICROSOFT, TT_MS_ID_BIG_5, FT_ENCODING_MS_BIG5 }, - { TT_PLATFORM_MICROSOFT, TT_MS_ID_WANSUNG, FT_ENCODING_MS_WANSUNG }, - { TT_PLATFORM_MICROSOFT, TT_MS_ID_JOHAB, FT_ENCODING_MS_JOHAB } + { TT_PLATFORM_MICROSOFT, TT_MS_ID_SJIS, FT_ENCODING_SJIS }, + { TT_PLATFORM_MICROSOFT, TT_MS_ID_GB2312, FT_ENCODING_GB2312 }, + { TT_PLATFORM_MICROSOFT, TT_MS_ID_BIG_5, FT_ENCODING_BIG5 }, + { TT_PLATFORM_MICROSOFT, TT_MS_ID_WANSUNG, FT_ENCODING_WANSUNG }, + { TT_PLATFORM_MICROSOFT, TT_MS_ID_JOHAB, FT_ENCODING_JOHAB } }; const TEncoding *cur, *limit; @@ -363,11 +364,7 @@ face->goto_table = sfnt->goto_table; } - if ( !face->psnames ) - { - face->psnames = (PSNames_Service) - FT_Get_Module_Interface( library, "psnames" ); - } + FT_FACE_FIND_GLOBAL_SERVICE( face, face->psnames, POSTSCRIPT_CMAPS ); /* check that we have a valid TrueType file */ error = sfnt->load_sfnt_header( face, stream, face_index, &sfnt_header ); @@ -403,7 +400,7 @@ FT_Int num_params, FT_Parameter* params ) { - FT_Error error; + FT_Error error, psnames_error; FT_Bool has_outline; FT_Bool is_apple_sbit; @@ -465,7 +462,7 @@ /* the following tables are optional in PCL fonts -- */ /* don't check for errors */ (void)LOAD_( names ); - (void)LOAD_( psnames ); + psnames_error = LOAD_( psnames ); /* do not load the metrics headers and tables if this is an Apple */ /* sbit font file */ @@ -532,9 +529,9 @@ FT_FACE_FLAG_HORIZONTAL; /* horizontal data */ #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES - /* might need more polish to detect the presence of a Postscript */ - /* name table in the font */ - flags |= FT_FACE_FLAG_GLYPH_NAMES; + if ( psnames_error == SFNT_Err_Ok && + face->postscript.FormatType != 0x00030000L ) + flags |= FT_FACE_FLAG_GLYPH_NAMES; #endif /* fixed width font? */ @@ -556,7 +553,7 @@ /* Compute style flags. */ /* */ flags = 0; - if ( has_outline == TRUE && face->os2.version != 0xFFFF ) + if ( has_outline == TRUE && face->os2.version != 0xFFFFU ) { /* we have an OS/2 table; use the `fsSelection' field */ if ( face->os2.fsSelection & 1 ) @@ -631,18 +628,30 @@ root->face_flags |= FT_FACE_FLAG_VERTICAL; } #endif - root->num_fixed_sizes = face->num_sbit_strikes; + root->num_fixed_sizes = (FT_Int)face->num_sbit_strikes; if ( FT_NEW_ARRAY( root->available_sizes, face->num_sbit_strikes ) ) goto Exit; for ( n = 0 ; n < face->num_sbit_strikes ; n++ ) { - root->available_sizes[n].width = - face->sbit_strikes[n].x_ppem; + FT_Bitmap_Size* bsize = root->available_sizes + n; + TT_SBit_Strike strike = face->sbit_strikes + n; + FT_UShort fupem = face->header.Units_Per_EM; + FT_Short height = (FT_Short)( face->horizontal.Ascender - + face->horizontal.Descender + + face->horizontal.Line_Gap ); + FT_Short avg = face->os2.xAvgCharWidth; - root->available_sizes[n].height = - face->sbit_strikes[n].y_ppem; + + /* assume 72dpi */ + bsize->height = + (FT_Short)( ( height * strike->y_ppem + fupem/2 ) / fupem ); + bsize->width = + (FT_Short)( ( avg * strike->y_ppem + fupem/2 ) / fupem ); + bsize->size = strike->y_ppem << 6; + bsize->x_ppem = strike->x_ppem << 6; + bsize->y_ppem = strike->y_ppem << 6; } } else @@ -661,7 +670,7 @@ if ( has_outline == TRUE ) { /* XXX What about if outline header is missing */ - /* (e.g. sfnt wrapped outline)? */ + /* (e.g. sfnt wrapped bitmap)? */ root->bbox.xMin = face->header.xMin; root->bbox.yMin = face->header.yMin; root->bbox.xMax = face->header.xMax; @@ -706,16 +715,18 @@ root->height = (FT_Short)( root->ascender - root->descender + face->horizontal.Line_Gap ); +#if 0 /* if the line_gap is 0, we add an extra 15% to the text height -- */ /* this computation is based on various versions of Times New Roman */ if ( face->horizontal.Line_Gap == 0 ) root->height = (FT_Short)( ( root->height * 115 + 50 ) / 100 ); +#endif #if 0 /* some fonts have the OS/2 "sTypoAscender", "sTypoDescender" & */ /* "sTypoLineGap" fields set to 0, like ARIALNB.TTF */ - if ( face->os2.version != 0xFFFF && root->ascender ) + if ( face->os2.version != 0xFFFFU && root->ascender ) { FT_Int height; @@ -826,4 +837,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/sfnt/sfobjs.h b/src/libs/freetype2/sfnt/sfobjs.h index a083d3a08c..6241c93b39 100644 --- a/src/libs/freetype2/sfnt/sfobjs.h +++ b/src/libs/freetype2/sfnt/sfobjs.h @@ -51,4 +51,4 @@ FT_END_HEADER #endif /* __SFDRIVER_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/sfnt/ttcmap.c b/src/libs/freetype2/sfnt/ttcmap.c deleted file mode 100644 index c9289cc639..0000000000 --- a/src/libs/freetype2/sfnt/ttcmap.c +++ /dev/null @@ -1,1110 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttcmap.c */ -/* */ -/* TrueType character mapping table (cmap) support (body). */ -/* */ -/* Copyright 1996-2001, 2002 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. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include "ttload.h" -#include "ttcmap.h" - -#include "sferrors.h" - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_ttcmap - - - FT_CALLBACK_DEF( FT_UInt ) - code_to_index0( TT_CMapTable charmap, - FT_ULong char_code ); - - FT_CALLBACK_DEF( FT_ULong ) - code_to_next0( TT_CMapTable charmap, - FT_ULong char_code ); - - FT_CALLBACK_DEF( FT_UInt ) - code_to_index2( TT_CMapTable charmap, - FT_ULong char_code ); - - FT_CALLBACK_DEF( FT_ULong ) - code_to_next2( TT_CMapTable charmap, - FT_ULong char_code ); - - FT_CALLBACK_DEF( FT_UInt ) - code_to_index4( TT_CMapTable charmap, - FT_ULong char_code ); - - FT_CALLBACK_DEF( FT_ULong ) - code_to_next4( TT_CMapTable charmap, - FT_ULong char_code ); - - FT_CALLBACK_DEF( FT_UInt ) - code_to_index6( TT_CMapTable charmap, - FT_ULong char_code ); - - FT_CALLBACK_DEF( FT_ULong ) - code_to_next6( TT_CMapTable charmap, - FT_ULong char_code ); - - FT_CALLBACK_DEF( FT_UInt ) - code_to_index8_12( TT_CMapTable charmap, - FT_ULong char_code ); - - FT_CALLBACK_DEF( FT_ULong ) - code_to_next8_12( TT_CMapTable charmap, - FT_ULong char_code ); - - FT_CALLBACK_DEF( FT_UInt ) - code_to_index10( TT_CMapTable charmap, - FT_ULong char_code ); - - FT_CALLBACK_DEF( FT_ULong ) - code_to_next10( TT_CMapTable charmap, - FT_ULong char_code ); - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_load_charmap */ - /* */ - /* <Description> */ - /* Loads a given TrueType character map into memory. */ - /* */ - /* <Input> */ - /* face :: A handle to the parent face object. */ - /* */ - /* stream :: A handle to the current stream object. */ - /* */ - /* <InOut> */ - /* table :: A pointer to a cmap object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - /* <Note> */ - /* The function assumes that the stream is already in use (i.e., */ - /* opened). In case of error, all partially allocated tables are */ - /* released. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_face_load_charmap( TT_Face face, - TT_CMapTable cmap, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory; - FT_UShort num_SH, num_Seg, i; - FT_ULong j, n; - - FT_UShort u, l; - - TT_CMap0 cmap0; - TT_CMap2 cmap2; - TT_CMap4 cmap4; - TT_CMap6 cmap6; - TT_CMap8_12 cmap8_12; - TT_CMap10 cmap10; - - TT_CMap2SubHeader cmap2sub; - TT_CMap4Segment segments; - TT_CMapGroup groups; - - - if ( cmap->loaded ) - return SFNT_Err_Ok; - - memory = stream->memory; - - if ( FT_STREAM_SEEK( cmap->offset ) ) - return error; - - switch ( cmap->format ) - { - case 0: - cmap0 = &cmap->c.cmap0; - - if ( FT_READ_USHORT( cmap0->language ) || - FT_ALLOC( cmap0->glyphIdArray, 256L ) || - FT_STREAM_READ( cmap0->glyphIdArray, 256L ) ) - goto Fail; - - cmap->get_index = code_to_index0; - cmap->get_next_char = code_to_next0; - break; - - case 2: - num_SH = 0; - cmap2 = &cmap->c.cmap2; - - /* allocate subheader keys */ - - if ( FT_NEW_ARRAY( cmap2->subHeaderKeys, 256 ) || - FT_FRAME_ENTER( 2L + 512L ) ) - goto Fail; - - cmap2->language = FT_GET_USHORT(); - - for ( i = 0; i < 256; i++ ) - { - u = (FT_UShort)( FT_GET_USHORT() / 8 ); - cmap2->subHeaderKeys[i] = u; - - if ( num_SH < u ) - num_SH = u; - } - - FT_FRAME_EXIT(); - - /* load subheaders */ - - cmap2->numGlyphId = l = (FT_UShort)( - ( ( cmap->length - 2L * ( 256 + 3 ) - num_SH * 8L ) & 0xFFFFU ) / 2 ); - - if ( FT_NEW_ARRAY( cmap2->subHeaders, num_SH + 1 ) || - FT_FRAME_ENTER( ( num_SH + 1 ) * 8L ) ) - { - FT_FREE( cmap2->subHeaderKeys ); - goto Fail; - } - - cmap2sub = cmap2->subHeaders; - - for ( i = 0; i <= num_SH; i++ ) - { - cmap2sub->firstCode = FT_GET_USHORT(); - cmap2sub->entryCount = FT_GET_USHORT(); - cmap2sub->idDelta = FT_GET_SHORT(); - /* we apply the location offset immediately */ - cmap2sub->idRangeOffset = (FT_UShort)( - FT_GET_USHORT() - ( num_SH - i ) * 8 - 2 ); - - cmap2sub++; - } - - FT_FRAME_EXIT(); - - /* load glyph IDs */ - - if ( FT_NEW_ARRAY( cmap2->glyphIdArray, l ) || - FT_FRAME_ENTER( l * 2L ) ) - { - FT_FREE( cmap2->subHeaders ); - FT_FREE( cmap2->subHeaderKeys ); - goto Fail; - } - - for ( i = 0; i < l; i++ ) - cmap2->glyphIdArray[i] = FT_GET_USHORT(); - - FT_FRAME_EXIT(); - - cmap->get_index = code_to_index2; - cmap->get_next_char = code_to_next2; - break; - - case 4: - cmap4 = &cmap->c.cmap4; - - /* load header */ - - if ( FT_FRAME_ENTER( 10L ) ) - goto Fail; - - cmap4->language = FT_GET_USHORT(); - cmap4->segCountX2 = FT_GET_USHORT(); - cmap4->searchRange = FT_GET_USHORT(); - cmap4->entrySelector = FT_GET_USHORT(); - cmap4->rangeShift = FT_GET_USHORT(); - - num_Seg = (FT_UShort)( cmap4->segCountX2 / 2 ); - - FT_FRAME_EXIT(); - - /* load segments */ - - if ( FT_NEW_ARRAY( cmap4->segments, num_Seg ) || - FT_FRAME_ENTER( ( num_Seg * 4 + 1 ) * 2L ) ) - goto Fail; - - segments = cmap4->segments; - - for ( i = 0; i < num_Seg; i++ ) - segments[i].endCount = FT_GET_USHORT(); - - (void)FT_GET_USHORT(); - - for ( i = 0; i < num_Seg; i++ ) - segments[i].startCount = FT_GET_USHORT(); - - for ( i = 0; i < num_Seg; i++ ) - segments[i].idDelta = FT_GET_SHORT(); - - for ( i = 0; i < num_Seg; i++ ) - segments[i].idRangeOffset = FT_GET_USHORT(); - - FT_FRAME_EXIT(); - - cmap4->numGlyphId = l = (FT_UShort)( - ( ( cmap->length - ( 16L + 8L * num_Seg ) ) & 0xFFFFU ) / 2 ); - - /* load IDs */ - - if ( FT_NEW_ARRAY( cmap4->glyphIdArray, l ) || - FT_FRAME_ENTER( l * 2L ) ) - { - FT_FREE( cmap4->segments ); - goto Fail; - } - - for ( i = 0; i < l; i++ ) - cmap4->glyphIdArray[i] = FT_GET_USHORT(); - - FT_FRAME_EXIT(); - - cmap4->last_segment = cmap4->segments; - - cmap->get_index = code_to_index4; - cmap->get_next_char = code_to_next4; - break; - - case 6: - cmap6 = &cmap->c.cmap6; - - if ( FT_FRAME_ENTER( 6L ) ) - goto Fail; - - cmap6->language = FT_GET_USHORT(); - cmap6->firstCode = FT_GET_USHORT(); - cmap6->entryCount = FT_GET_USHORT(); - - FT_FRAME_EXIT(); - - l = cmap6->entryCount; - - if ( FT_NEW_ARRAY( cmap6->glyphIdArray, l ) || - FT_FRAME_ENTER( l * 2L ) ) - goto Fail; - - for ( i = 0; i < l; i++ ) - cmap6->glyphIdArray[i] = FT_GET_USHORT(); - - FT_FRAME_EXIT(); - cmap->get_index = code_to_index6; - cmap->get_next_char = code_to_next6; - break; - - case 8: - case 12: - cmap8_12 = &cmap->c.cmap8_12; - - if ( FT_FRAME_ENTER( 8L ) ) - goto Fail; - - cmap->length = FT_GET_ULONG(); - cmap8_12->language = FT_GET_ULONG(); - - FT_FRAME_EXIT(); - - if ( cmap->format == 8 ) - if ( FT_STREAM_SKIP( 8192L ) ) - goto Fail; - - if ( FT_READ_ULONG( cmap8_12->nGroups ) ) - goto Fail; - - n = cmap8_12->nGroups; - - if ( FT_NEW_ARRAY( cmap8_12->groups, n ) || - FT_FRAME_ENTER( n * 3 * 4L ) ) - goto Fail; - - groups = cmap8_12->groups; - - for ( j = 0; j < n; j++ ) - { - groups[j].startCharCode = FT_GET_ULONG(); - groups[j].endCharCode = FT_GET_ULONG(); - groups[j].startGlyphID = FT_GET_ULONG(); - } - - FT_FRAME_EXIT(); - - cmap8_12->last_group = cmap8_12->groups; - - cmap->get_index = code_to_index8_12; - cmap->get_next_char = code_to_next8_12; - break; - - case 10: - cmap10 = &cmap->c.cmap10; - - if ( FT_FRAME_ENTER( 16L ) ) - goto Fail; - - cmap->length = FT_GET_ULONG(); - cmap10->language = FT_GET_ULONG(); - cmap10->startCharCode = FT_GET_ULONG(); - cmap10->numChars = FT_GET_ULONG(); - - FT_FRAME_EXIT(); - - n = cmap10->numChars; - - if ( FT_NEW_ARRAY( cmap10->glyphs, n ) || - FT_FRAME_ENTER( n * 2L ) ) - goto Fail; - - for ( j = 0; j < n; j++ ) - cmap10->glyphs[j] = FT_GET_USHORT(); - - FT_FRAME_EXIT(); - cmap->get_index = code_to_index10; - cmap->get_next_char = code_to_next10; - break; - - default: /* corrupt character mapping table */ - return SFNT_Err_Invalid_CharMap_Format; - - } - - return SFNT_Err_Ok; - - Fail: - tt_face_free_charmap( face, cmap ); - return error; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_free_charmap */ - /* */ - /* <Description> */ - /* Destroys a character mapping table. */ - /* */ - /* <Input> */ - /* face :: A handle to the parent face object. */ - /* */ - /* cmap :: A handle to a cmap object. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - tt_face_free_charmap( TT_Face face, - TT_CMapTable cmap ) - { - FT_Memory memory; - - - if ( !cmap ) - return SFNT_Err_Ok; - - memory = face->root.driver->root.memory; - - switch ( cmap->format ) - { - case 0: - FT_FREE( cmap->c.cmap0.glyphIdArray ); - break; - - case 2: - FT_FREE( cmap->c.cmap2.subHeaderKeys ); - FT_FREE( cmap->c.cmap2.subHeaders ); - FT_FREE( cmap->c.cmap2.glyphIdArray ); - break; - - case 4: - FT_FREE( cmap->c.cmap4.segments ); - FT_FREE( cmap->c.cmap4.glyphIdArray ); - cmap->c.cmap4.segCountX2 = 0; - break; - - case 6: - FT_FREE( cmap->c.cmap6.glyphIdArray ); - cmap->c.cmap6.entryCount = 0; - break; - - case 8: - case 12: - FT_FREE( cmap->c.cmap8_12.groups ); - cmap->c.cmap8_12.nGroups = 0; - break; - - case 10: - FT_FREE( cmap->c.cmap10.glyphs ); - cmap->c.cmap10.numChars = 0; - break; - - default: - /* invalid table format, do nothing */ - ; - } - - cmap->loaded = FALSE; - return SFNT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* code_to_index0 */ - /* */ - /* <Description> */ - /* Converts the character code into a glyph index. Uses format 0. */ - /* `charCode' must be in the range 0x00-0xFF (otherwise 0 is */ - /* returned). */ - /* */ - /* <Input> */ - /* charCode :: The wanted character code. */ - /* */ - /* cmap0 :: A pointer to a cmap table in format 0. */ - /* */ - /* <Return> */ - /* Glyph index into the glyphs array. 0 if the glyph does not exist. */ - /* */ - FT_CALLBACK_DEF( FT_UInt ) - code_to_index0( TT_CMapTable cmap, - FT_ULong charCode ) - { - TT_CMap0 cmap0 = &cmap->c.cmap0; - - - return ( charCode <= 0xFF ? cmap0->glyphIdArray[charCode] : 0 ); - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* code_to_next0 */ - /* */ - /* <Description> */ - /* Finds the next encoded character after the given one. Uses */ - /* format 0. `charCode' must be in the range 0x00-0xFF (otherwise 0 */ - /* is returned). */ - /* */ - /* <Input> */ - /* charCode :: The wanted character code. */ - /* */ - /* cmap0 :: A pointer to a cmap table in format 0. */ - /* */ - /* <Return> */ - /* Next char code. 0 if no higher one is encoded. */ - /* */ - FT_CALLBACK_DEF( FT_ULong ) - code_to_next0( TT_CMapTable cmap, - FT_ULong charCode ) - { - TT_CMap0 cmap0 = &cmap->c.cmap0; - - - while ( ++charCode <= 0xFF ) - if ( cmap0->glyphIdArray[charCode] ) - return ( charCode ); - return ( 0 ); - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* code_to_index2 */ - /* */ - /* <Description> */ - /* Converts the character code into a glyph index. Uses format 2. */ - /* */ - /* <Input> */ - /* charCode :: The wanted character code. */ - /* */ - /* cmap2 :: A pointer to a cmap table in format 2. */ - /* */ - /* <Return> */ - /* Glyph index into the glyphs array. 0 if the glyph does not exist. */ - /* */ - FT_CALLBACK_DEF( FT_UInt ) - code_to_index2( TT_CMapTable cmap, - FT_ULong charCode ) - { - FT_UInt result, index1, offset; - FT_UInt char_lo; - FT_ULong char_hi; - TT_CMap2SubHeader sh2; - TT_CMap2 cmap2; - - - cmap2 = &cmap->c.cmap2; - result = 0; - char_lo = (FT_UInt)( charCode & 0xFF ); - char_hi = charCode >> 8; - - if ( char_hi == 0 ) - { - /* an 8-bit character code -- we use the subHeader 0 in this case */ - /* to test whether the character code is in the charmap */ - index1 = cmap2->subHeaderKeys[char_lo]; - if ( index1 != 0 ) - return 0; - } - else - { - /* a 16-bit character code */ - index1 = cmap2->subHeaderKeys[char_hi & 0xFF]; - if ( index1 == 0 ) - return 0; - } - - sh2 = cmap2->subHeaders + index1; - char_lo -= sh2->firstCode; - - if ( char_lo < (FT_UInt)sh2->entryCount ) - { - offset = sh2->idRangeOffset / 2 + char_lo; - if ( offset < (FT_UInt)cmap2->numGlyphId ) - { - result = cmap2->glyphIdArray[offset]; - if ( result ) - result = ( result + sh2->idDelta ) & 0xFFFFU; - } - } - - return result; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* code_to_next2 */ - /* */ - /* <Description> */ - /* Find the next encoded character. Uses format 2. */ - /* */ - /* <Input> */ - /* charCode :: The wanted character code. */ - /* */ - /* cmap2 :: A pointer to a cmap table in format 2. */ - /* */ - /* <Return> */ - /* Next encoded character. 0 if none exists. */ - /* */ - FT_CALLBACK_DEF( FT_ULong ) - code_to_next2( TT_CMapTable cmap, - FT_ULong charCode ) - { - FT_UInt index1, offset; - FT_UInt char_lo; - FT_ULong char_hi; - TT_CMap2SubHeader sh2; - TT_CMap2 cmap2; - - - cmap2 = &cmap->c.cmap2; - charCode++; - - /* - * This is relatively simplistic -- look for a subHeader containing - * glyphs and then walk to the first glyph in that subHeader. - */ - while ( charCode < 0x10000L ) - { - char_lo = (FT_UInt)( charCode & 0xFF ); - char_hi = charCode >> 8; - - if ( char_hi == 0 ) - { - /* an 8-bit character code -- we use the subHeader 0 in this case */ - /* to test whether the character code is in the charmap */ - index1 = cmap2->subHeaderKeys[char_lo]; - if ( index1 != 0 ) - { - charCode++; - continue; - } - } - else - { - /* a 16-bit character code */ - index1 = cmap2->subHeaderKeys[char_hi & 0xFF]; - if ( index1 == 0 ) - { - charCode = ( char_hi + 1 ) << 8; - continue; - } - } - - sh2 = cmap2->subHeaders + index1; - char_lo -= sh2->firstCode; - - if ( char_lo > (FT_UInt)sh2->entryCount ) - { - charCode = ( char_hi + 1 ) << 8; - continue; - } - - offset = sh2->idRangeOffset / 2 + char_lo; - if ( offset >= (FT_UInt)cmap2->numGlyphId || - cmap2->glyphIdArray[offset] == 0 ) - { - charCode++; - continue; - } - - return charCode; - } - return 0; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* code_to_index4 */ - /* */ - /* <Description> */ - /* Converts the character code into a glyph index. Uses format 4. */ - /* */ - /* <Input> */ - /* charCode :: The wanted character code. */ - /* */ - /* cmap4 :: A pointer to a cmap table in format 4. */ - /* */ - /* <Return> */ - /* Glyph index into the glyphs array. 0 if the glyph does not exist. */ - /* */ - FT_CALLBACK_DEF( FT_UInt ) - code_to_index4( TT_CMapTable cmap, - FT_ULong charCode ) - { - FT_UInt result, index1, segCount; - TT_CMap4 cmap4; - TT_CMap4SegmentRec *seg4, *limit; - - - cmap4 = &cmap->c.cmap4; - result = 0; - segCount = cmap4->segCountX2 / 2; - limit = cmap4->segments + segCount; - - /* first, check against the last used segment */ - - seg4 = cmap4->last_segment; - - /* the following is equivalent to performing two tests, as in */ - /* */ - /* if ( charCode >= seg4->startCount && charCode <= seg4->endCount ) */ - /* */ - /* This is a bit strange, but it is faster, and the idea behind the */ - /* cache is to significantly speed up charcode to glyph index */ - /* conversion. */ - - if ( (FT_ULong)( charCode - seg4->startCount ) < - (FT_ULong)( seg4->endCount - seg4->startCount ) ) - goto Found1; - - for ( seg4 = cmap4->segments; seg4 < limit; seg4++ ) - { - /* the ranges are sorted in increasing order. If we are out of */ - /* the range here, the char code isn't in the charmap, so exit. */ - - if ( charCode > (FT_UInt)seg4->endCount ) - continue; - - if ( charCode >= (FT_UInt)seg4->startCount ) - goto Found; - } - return 0; - - Found: - cmap4->last_segment = seg4; - - Found1: - /* if the idRangeOffset is 0, we can compute the glyph index */ - /* directly */ - - if ( seg4->idRangeOffset == 0 ) - result = (FT_UInt)( charCode + seg4->idDelta ) & 0xFFFFU; - else - { - /* otherwise, we must use the glyphIdArray to do it */ - index1 = (FT_UInt)( seg4->idRangeOffset / 2 - + ( charCode - seg4->startCount ) - + ( seg4 - cmap4->segments ) - - segCount ); - - if ( index1 < (FT_UInt)cmap4->numGlyphId && - cmap4->glyphIdArray[index1] != 0 ) - result = ( cmap4->glyphIdArray[index1] + seg4->idDelta ) & 0xFFFFU; - } - - return result; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* code_to_next4 */ - /* */ - /* <Description> */ - /* Find the next encoded character. Uses format 4. */ - /* */ - /* <Input> */ - /* charCode :: The wanted character code. */ - /* */ - /* cmap :: A pointer to a cmap table in format 4. */ - /* */ - /* <Return> */ - /* Next encoded character. 0 if none exists. */ - /* */ - FT_CALLBACK_DEF( FT_ULong ) - code_to_next4( TT_CMapTable cmap, - FT_ULong charCode ) - { - FT_UInt index1, segCount; - TT_CMap4 cmap4; - TT_CMap4SegmentRec *seg4, *limit; - - - cmap4 = &cmap->c.cmap4; - segCount = cmap4->segCountX2 / 2; - limit = cmap4->segments + segCount; - - charCode++; - - for ( seg4 = cmap4->segments; seg4 < limit; seg4++ ) - { - /* The ranges are sorted in increasing order. If we are out of */ - /* the range here, the char code isn't in the charmap, so exit. */ - - if ( charCode <= (FT_UInt)seg4->endCount ) - goto Found; - } - return 0; - - Found: - if ( charCode < (FT_ULong) seg4->startCount ) - charCode = seg4->startCount; - - /* if the idRangeOffset is 0, all chars in the map exist */ - - if ( seg4->idRangeOffset == 0 ) - return ( charCode ); - - while ( charCode <= (FT_UInt) seg4->endCount ) - { - /* otherwise, we must use the glyphIdArray to do it */ - index1 = (FT_UInt)( seg4->idRangeOffset / 2 - + ( charCode - seg4->startCount ) - + ( seg4 - cmap4->segments ) - - segCount ); - - if ( index1 < (FT_UInt)cmap4->numGlyphId && - cmap4->glyphIdArray[index1] != 0 ) - return ( charCode ); - charCode++; - } - - return 0; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* code_to_index6 */ - /* */ - /* <Description> */ - /* Converts the character code into a glyph index. Uses format 6. */ - /* */ - /* <Input> */ - /* charCode :: The wanted character code. */ - /* */ - /* cmap6 :: A pointer to a cmap table in format 6. */ - /* */ - /* <Return> */ - /* Glyph index into the glyphs array. 0 if the glyph does not exist. */ - /* */ - FT_CALLBACK_DEF( FT_UInt ) - code_to_index6( TT_CMapTable cmap, - FT_ULong charCode ) - { - TT_CMap6 cmap6; - FT_UInt result = 0; - - - cmap6 = &cmap->c.cmap6; - charCode -= cmap6->firstCode; - - if ( charCode < (FT_UInt)cmap6->entryCount ) - result = cmap6->glyphIdArray[charCode]; - - return result; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* code_to_next6 */ - /* */ - /* <Description> */ - /* Find the next encoded character. Uses format 6. */ - /* */ - /* <Input> */ - /* charCode :: The wanted character code. */ - /* */ - /* cmap :: A pointer to a cmap table in format 6. */ - /* */ - /* <Return> */ - /* Next encoded character. 0 if none exists. */ - /* */ - FT_CALLBACK_DEF( FT_ULong ) - code_to_next6( TT_CMapTable cmap, - FT_ULong charCode ) - { - TT_CMap6 cmap6; - - - charCode++; - - cmap6 = &cmap->c.cmap6; - - if ( charCode < (FT_ULong) cmap6->firstCode ) - charCode = cmap6->firstCode; - - charCode -= cmap6->firstCode; - - while ( charCode < (FT_UInt)cmap6->entryCount ) - { - if ( cmap6->glyphIdArray[charCode] != 0 ) - return charCode + cmap6->firstCode; - charCode++; - } - - return 0; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* code_to_index8_12 */ - /* */ - /* <Description> */ - /* Converts the (possibly 32bit) character code into a glyph index. */ - /* Uses format 8 or 12. */ - /* */ - /* <Input> */ - /* charCode :: The wanted character code. */ - /* */ - /* cmap8_12 :: A pointer to a cmap table in format 8 or 12. */ - /* */ - /* <Return> */ - /* Glyph index into the glyphs array. 0 if the glyph does not exist. */ - /* */ - FT_CALLBACK_DEF( FT_UInt ) - code_to_index8_12( TT_CMapTable cmap, - FT_ULong charCode ) - { - TT_CMap8_12 cmap8_12; - TT_CMapGroupRec *group, *limit; - - - cmap8_12 = &cmap->c.cmap8_12; - limit = cmap8_12->groups + cmap8_12->nGroups; - - /* first, check against the last used group */ - - group = cmap8_12->last_group; - - /* the following is equivalent to performing two tests, as in */ - /* */ - /* if ( charCode >= group->startCharCode && */ - /* charCode <= group->endCharCode ) */ - /* */ - /* This is a bit strange, but it is faster, and the idea behind the */ - /* cache is to significantly speed up charcode to glyph index */ - /* conversion. */ - - if ( (FT_ULong)( charCode - group->startCharCode ) < - (FT_ULong)( group->endCharCode - group->startCharCode ) ) - goto Found1; - - for ( group = cmap8_12->groups; group < limit; group++ ) - { - /* the ranges are sorted in increasing order. If we are out of */ - /* the range here, the char code isn't in the charmap, so exit. */ - - if ( charCode > group->endCharCode ) - continue; - - if ( charCode >= group->startCharCode ) - goto Found; - } - return 0; - - Found: - cmap8_12->last_group = group; - - Found1: - return (FT_UInt)( group->startGlyphID + - ( charCode - group->startCharCode ) ); - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* code_to_next8_12 */ - /* */ - /* <Description> */ - /* Find the next encoded character. Uses format 8 or 12. */ - /* */ - /* <Input> */ - /* charCode :: The wanted character code. */ - /* */ - /* cmap :: A pointer to a cmap table in format 8 or 12. */ - /* */ - /* <Return> */ - /* Next encoded character. 0 if none exists. */ - /* */ - FT_CALLBACK_DEF( FT_ULong ) - code_to_next8_12( TT_CMapTable cmap, - FT_ULong charCode ) - { - TT_CMap8_12 cmap8_12; - TT_CMapGroupRec *group, *limit; - - - charCode++; - cmap8_12 = &cmap->c.cmap8_12; - limit = cmap8_12->groups + cmap8_12->nGroups; - - for ( group = cmap8_12->groups; group < limit; group++ ) - { - /* the ranges are sorted in increasing order. If we are out of */ - /* the range here, the char code isn't in the charmap, so exit. */ - - if ( charCode <= group->endCharCode ) - goto Found; - } - return 0; - - Found: - if ( charCode < group->startCharCode ) - charCode = group->startCharCode; - - return charCode; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* code_to_index10 */ - /* */ - /* <Description> */ - /* Converts the (possibly 32bit) character code into a glyph index. */ - /* Uses format 10. */ - /* */ - /* <Input> */ - /* charCode :: The wanted character code. */ - /* */ - /* cmap10 :: A pointer to a cmap table in format 10. */ - /* */ - /* <Return> */ - /* Glyph index into the glyphs array. 0 if the glyph does not exist. */ - /* */ - FT_CALLBACK_DEF( FT_UInt ) - code_to_index10( TT_CMapTable cmap, - FT_ULong charCode ) - { - TT_CMap10 cmap10; - FT_UInt result = 0; - - - cmap10 = &cmap->c.cmap10; - charCode -= cmap10->startCharCode; - - /* the overflow trick for comparison works here also since the number */ - /* of glyphs (even if numChars is specified as ULong in the specs) in */ - /* an OpenType font is limited to 64k */ - - if ( charCode < cmap10->numChars ) - result = cmap10->glyphs[charCode]; - - return result; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* code_to_next10 */ - /* */ - /* <Description> */ - /* Find the next encoded character. Uses format 10. */ - /* */ - /* <Input> */ - /* charCode :: The wanted character code. */ - /* */ - /* cmap :: A pointer to a cmap table in format 10. */ - /* */ - /* <Return> */ - /* Next encoded character. 0 if none exists. */ - /* */ - FT_CALLBACK_DEF( FT_ULong ) - code_to_next10( TT_CMapTable cmap, - FT_ULong charCode ) - { - TT_CMap10 cmap10; - - - charCode++; - cmap10 = &cmap->c.cmap10; - - if ( charCode < cmap10->startCharCode ) - charCode = cmap10->startCharCode; - - charCode -= cmap10->startCharCode; - - /* the overflow trick for comparison works here also since the number */ - /* of glyphs (even if numChars is specified as ULong in the specs) in */ - /* an OpenType font is limited to 64k */ - - while ( charCode < cmap10->numChars ) - { - if ( cmap10->glyphs[charCode] ) - return ( charCode + cmap10->startCharCode ); - charCode++; - } - - return 0; - } - - -/* END */ diff --git a/src/libs/freetype2/sfnt/ttcmap0.c b/src/libs/freetype2/sfnt/ttcmap0.c index 6aaf140a15..dd1c76aaa7 100644 --- a/src/libs/freetype2/sfnt/ttcmap0.c +++ b/src/libs/freetype2/sfnt/ttcmap0.c @@ -4,7 +4,7 @@ /* */ /* TrueType new character mapping table (cmap) support (body). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -144,6 +144,19 @@ } + FT_CALLBACK_DEF( FT_Error ) + tt_cmap0_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 4; + + + cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); + + return FT_Err_Ok; + } + + FT_CALLBACK_TABLE_DEF const TT_CMap_ClassRec tt_cmap0_class_rec = { @@ -156,7 +169,8 @@ (FT_CMap_CharNextFunc) tt_cmap0_char_next }, 0, - (TT_CMap_ValidateFunc) tt_cmap0_validate + (TT_CMap_ValidateFunc) tt_cmap0_validate, + (TT_CMap_Info_GetFunc) tt_cmap0_get_info }; #endif /* TT_CONFIG_CMAP_FORMAT_0 */ @@ -378,10 +392,13 @@ else { /* a 16-bit character code */ - p += char_hi * 2; /* jump to key entry */ - sub = subs + ( TT_PEEK_USHORT( p ) & -8 ); /* jump to sub-header */ - /* check that the hi byte isn't a valid one-byte value */ + /* jump to key entry */ + p += char_hi * 2; + /* jump to sub-header */ + sub = subs + ( FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 8 ) ); + + /* check that the high byte isn't a valid one-byte value */ if ( sub == subs ) goto Exit; } @@ -467,7 +484,7 @@ pos = (FT_UInt)( char_lo - start ); p += offset + pos * 2; - charcode = ( charcode & -256 ) + char_lo; + charcode = FT_PAD_FLOOR( charcode, 256 ) + char_lo; for ( ; pos < count; pos++, charcode++ ) { @@ -487,7 +504,7 @@ /* jump to next sub-header, i.e. higher byte value */ Next_SubHeader: - charcode = ( charcode & -256 ) + 256; + charcode = FT_PAD_FLOOR( charcode, 256 ) + 256; } Exit: @@ -497,6 +514,19 @@ } + FT_CALLBACK_DEF( FT_Error ) + tt_cmap2_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 4; + + + cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); + + return FT_Err_Ok; + } + + FT_CALLBACK_TABLE_DEF const TT_CMap_ClassRec tt_cmap2_class_rec = { @@ -509,7 +539,8 @@ (FT_CMap_CharNextFunc) tt_cmap2_char_next }, 2, - (TT_CMap_ValidateFunc) tt_cmap2_validate + (TT_CMap_ValidateFunc) tt_cmap2_validate, + (TT_CMap_Info_GetFunc) tt_cmap2_get_info }; #endif /* TT_CONFIG_CMAP_FORMAT_2 */ @@ -701,9 +732,18 @@ p += offset; /* start of glyph id array */ /* check that we point within the glyph ids table only */ - if ( p < glyph_ids || - p + ( end - start + 1 ) * 2 > table + length ) - FT_INVALID_DATA; + if ( valid->level >= FT_VALIDATE_TIGHT ) + { + if ( p < glyph_ids || + p + ( end - start + 1 ) * 2 > table + length ) + FT_INVALID_DATA; + } + else + { + if ( p < glyph_ids || + p + ( end - start + 1 ) * 2 > valid->limit ) + FT_INVALID_DATA; + } /* check glyph indices within the segment range */ if ( valid->level >= FT_VALIDATE_TIGHT ) @@ -758,7 +798,7 @@ p = table + 6; - num_segs2 = TT_PEEK_USHORT( p ) & -2; /* be paranoid! */ + num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 ); /* be paranoid! */ #if 1 /* Some fonts have more than 170 segments in their charmaps! */ @@ -780,10 +820,8 @@ if ( code < start ) max = mid; - else if ( code > end ) min = mid + 1; - else { /* we found the segment */ @@ -872,24 +910,117 @@ { FT_Byte* table = cmap->data; FT_UInt32 result = 0; - FT_UInt32 char_code = *pchar_code + 1; FT_UInt gindex = 0; + FT_UInt32 char_code = *pchar_code; FT_Byte* p; - FT_Byte* q; FT_UInt code, num_segs2; - if ( char_code >= 0x10000UL ) + if ( char_code >= 0xFFFFUL ) goto Exit; - code = (FT_UInt)char_code; + code = (FT_UInt)char_code + 1; p = table + 6; - num_segs2 = TT_PEEK_USHORT(p) & -2; /* ensure even-ness */ + num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT(p), 2 ); /* ensure even-ness */ + +#if 1 for (;;) { - FT_UInt offset, n; + /* Some fonts have more than 170 segments in their charmaps! */ + /* We changed this function to use a more efficient binary */ + /* search */ + FT_UInt offset; FT_Int delta; + FT_UInt min = 0; + FT_UInt max = num_segs2 >> 1; + FT_UInt mid, start, end; + FT_UInt hi; + + + /* we begin by finding the segment which end is + closer to our code point */ + hi = max + 1; + while ( min < max ) + { + mid = ( min + max ) >> 1; + p = table + 14 + mid * 2; + end = TT_PEEK_USHORT( p ); + + if ( end < code ) + min = mid + 1; + else + { + hi = mid; + max = mid; + } + } + + if ( hi > max ) + { + /* the point is behind the last segment; + we will exit right now */ + goto Exit; + } + + p = table + 14 + hi * 2; + end = TT_PEEK_USHORT( p ); + + p += 2 + num_segs2; + start = TT_PEEK_USHORT( p ); + + if ( code < start ) + code = start; + + p += num_segs2; + delta = TT_PEEK_USHORT( p ); + + p += num_segs2; + offset = TT_PEEK_USHORT( p ); + + if ( offset != 0 && offset != 0xFFFFU ) + { + /* parse the glyph ids array for non-zero index */ + p += offset + ( code - start ) * 2; + while ( code <= end ) + { + gindex = TT_NEXT_USHORT( p ); + if ( gindex != 0 ) + { + gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU; + if ( gindex != 0 ) + { + result = code; + goto Exit; + } + } + code++; + } + } + else if ( offset == 0xFFFFU ) + { + /* an offset of 0xFFFF means an empty glyph in certain fonts! */ + code = end + 1; + } + else /* offset == 0 */ + { + gindex = (FT_UInt)( code + delta ) & 0xFFFFU; + if ( gindex != 0 ) + { + result = code; + goto Exit; + } + code++; + } + } + +#else /* old code -- kept for reference */ + + for ( ;; ) + { + FT_UInt offset, n; + FT_Int delta; + FT_Byte* q; p = table + 14; /* ends table */ @@ -943,14 +1074,14 @@ goto Exit; } } - /* loop to next trial charcode */ if ( code >= 0xFFFFU ) break; code++; } - return (FT_UInt)result; + +#endif /* !1 */ Exit: *pchar_code = result; @@ -958,6 +1089,19 @@ } + FT_CALLBACK_DEF( FT_Error ) + tt_cmap4_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 4; + + + cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); + + return FT_Err_Ok; + } + + FT_CALLBACK_TABLE_DEF const TT_CMap_ClassRec tt_cmap4_class_rec = { @@ -970,7 +1114,8 @@ (FT_CMap_CharNextFunc) tt_cmap4_char_next }, 4, - (TT_CMap_ValidateFunc) tt_cmap4_validate + (TT_CMap_ValidateFunc) tt_cmap4_validate, + (TT_CMap_Info_GetFunc) tt_cmap4_get_info }; #endif /* TT_CONFIG_CMAP_FORMAT_4 */ @@ -1009,7 +1154,7 @@ FT_Validator valid ) { FT_Byte* p; - FT_UInt length, start, count; + FT_UInt length, count; if ( table + 10 > valid->limit ) @@ -1018,8 +1163,7 @@ p = table + 2; length = TT_NEXT_USHORT( p ); - p = table + 6; /* skip language */ - start = TT_NEXT_USHORT( p ); + p = table + 8; /* skip language and start index */ count = TT_NEXT_USHORT( p ); if ( table + length > valid->limit || length < 10 + count * 2 ) @@ -1103,6 +1247,19 @@ } + FT_CALLBACK_DEF( FT_Error ) + tt_cmap6_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 4; + + + cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); + + return FT_Err_Ok; + } + + FT_CALLBACK_TABLE_DEF const TT_CMap_ClassRec tt_cmap6_class_rec = { @@ -1115,7 +1272,8 @@ (FT_CMap_CharNextFunc) tt_cmap6_char_next }, 6, - (TT_CMap_ValidateFunc) tt_cmap6_validate + (TT_CMap_ValidateFunc) tt_cmap6_validate, + (TT_CMap_Info_GetFunc) tt_cmap6_get_info }; #endif /* TT_CONFIG_CMAP_FORMAT_6 */ @@ -1340,6 +1498,18 @@ } + FT_CALLBACK_DEF( FT_Error ) + tt_cmap8_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 8; + + + cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); + return FT_Err_Ok; + } + + FT_CALLBACK_TABLE_DEF const TT_CMap_ClassRec tt_cmap8_class_rec = { @@ -1352,7 +1522,8 @@ (FT_CMap_CharNextFunc) tt_cmap8_char_next }, 8, - (TT_CMap_ValidateFunc) tt_cmap8_validate + (TT_CMap_ValidateFunc) tt_cmap8_validate, + (TT_CMap_Info_GetFunc) tt_cmap8_get_info }; #endif /* TT_CONFIG_CMAP_FORMAT_8 */ @@ -1390,15 +1561,14 @@ FT_Validator valid ) { FT_Byte* p = table + 4; - FT_ULong length, start, count; + FT_ULong length, count; if ( table + 20 > valid->limit ) FT_INVALID_TOO_SHORT; length = TT_NEXT_ULONG( p ); - p = table + 12; - start = TT_NEXT_ULONG( p ); + p = table + 16; count = TT_NEXT_ULONG( p ); if ( table + length > valid->limit || length < 20 + count * 2 ) @@ -1446,7 +1616,6 @@ FT_UInt32 *pchar_code ) { FT_Byte* table = cmap->data; - FT_UInt32 result = 0; FT_UInt32 char_code = *pchar_code + 1; FT_UInt gindex = 0; FT_Byte* p = table + 12; @@ -1465,10 +1634,7 @@ { gindex = TT_NEXT_USHORT( p ); if ( gindex != 0 ) - { - result = char_code; break; - } char_code++; } @@ -1477,6 +1643,19 @@ } + FT_CALLBACK_DEF( FT_Error ) + tt_cmap10_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 8; + + + cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); + + return FT_Err_Ok; + } + + FT_CALLBACK_TABLE_DEF const TT_CMap_ClassRec tt_cmap10_class_rec = { @@ -1489,7 +1668,8 @@ (FT_CMap_CharNextFunc) tt_cmap10_char_next }, 10, - (TT_CMap_ValidateFunc) tt_cmap10_validate + (TT_CMap_ValidateFunc) tt_cmap10_validate, + (TT_CMap_Info_GetFunc) tt_cmap10_get_info }; #endif /* TT_CONFIG_CMAP_FORMAT_10 */ @@ -1647,6 +1827,19 @@ } + FT_CALLBACK_DEF( FT_Error ) + tt_cmap12_get_info( TT_CMap cmap, + TT_CMapInfo *cmap_info ) + { + FT_Byte* p = cmap->data + 8; + + + cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); + + return FT_Err_Ok; + } + + FT_CALLBACK_TABLE_DEF const TT_CMap_ClassRec tt_cmap12_class_rec = { @@ -1659,7 +1852,8 @@ (FT_CMap_CharNextFunc) tt_cmap12_char_next }, 12, - (TT_CMap_ValidateFunc) tt_cmap12_validate + (TT_CMap_ValidateFunc) tt_cmap12_validate, + (TT_CMap_Info_GetFunc) tt_cmap12_get_info }; @@ -1713,7 +1907,7 @@ if ( p + 4 > limit ) - return FT_Err_Invalid_Table; + return SFNT_Err_Invalid_Table; /* only recognize format 0 */ if ( TT_NEXT_USHORT( p ) != 0 ) @@ -1721,7 +1915,7 @@ p -= 2; FT_ERROR(( "tt_face_build_cmaps: unsupported `cmap' table format = %d\n", TT_PEEK_USHORT( p ) )); - return FT_Err_Invalid_Table; + return SFNT_Err_Invalid_Table; } num_cmaps = TT_NEXT_USHORT( p ); @@ -1741,7 +1935,7 @@ if ( offset && table + offset + 2 < limit ) { FT_Byte* cmap = table + offset; - FT_UInt format = TT_PEEK_USHORT( cmap ); + volatile FT_UInt format = TT_PEEK_USHORT( cmap ); const TT_CMap_Class* volatile pclazz = tt_cmap_classes; TT_CMap_Class clazz; @@ -1772,6 +1966,7 @@ FT_ERROR(( "tt_face_build_cmaps:" )); FT_ERROR(( " broken cmap sub-table ignored!\n" )); } + break; } } } @@ -1781,4 +1976,16 @@ } -/* END */ + FT_LOCAL( FT_Error ) + tt_get_cmap_info( FT_CharMap charmap, + TT_CMapInfo *cmap_info ) + { + FT_CMap cmap = (FT_CMap)charmap; + TT_CMap_Class clazz = (TT_CMap_Class)cmap->clazz; + + + return clazz->get_cmap_info( charmap, cmap_info ); + } + + +/* END */ diff --git a/src/libs/freetype2/sfnt/ttcmap0.h b/src/libs/freetype2/sfnt/ttcmap0.h index 324fcbffd8..6ca9ca1100 100644 --- a/src/libs/freetype2/sfnt/ttcmap0.h +++ b/src/libs/freetype2/sfnt/ttcmap0.h @@ -4,7 +4,7 @@ /* */ /* TrueType new character mapping table (cmap) support (specification). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,7 +23,7 @@ #include <ft2build.h> #include FT_INTERNAL_TRUETYPE_TYPES_H #include FT_INTERNAL_OBJECTS_H - +#include FT_SERVICE_TT_CMAP_H FT_BEGIN_HEADER @@ -46,6 +46,7 @@ FT_BEGIN_HEADER FT_CMap_ClassRec clazz; FT_UInt format; TT_CMap_ValidateFunc validate; + TT_CMap_Info_GetFunc get_cmap_info; } TT_CMap_ClassRec; @@ -65,10 +66,15 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) tt_face_build_cmaps( TT_Face face ); + /* used in tt-cmaps service */ + FT_LOCAL( FT_Error ) + tt_get_cmap_info( FT_CharMap charmap, + TT_CMapInfo *cmap_info ); + FT_END_HEADER #endif /* __TTCMAP0_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/sfnt/ttload.c b/src/libs/freetype2/sfnt/ttload.c index b50d752b61..d1b0b208b1 100644 --- a/src/libs/freetype2/sfnt/ttload.c +++ b/src/libs/freetype2/sfnt/ttload.c @@ -5,7 +5,7 @@ /* Load the basic TrueType tables, i.e., tables that can be either in */ /* TTF or OTF fonts (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,7 +22,6 @@ #include FT_INTERNAL_STREAM_H #include FT_TRUETYPE_TAGS_H #include "ttload.h" -#include "ttcmap.h" #include "sferrors.h" @@ -179,11 +178,8 @@ /* if 'num_tables' is 0, read the table count from the file */ if ( num_tables == 0 ) { - FT_ULong format_tag; - - if ( FT_STREAM_SEEK( offset ) || - FT_READ_ULONG ( format_tag ) || + FT_STREAM_SKIP( 4 ) || FT_READ_USHORT( num_tables ) || FT_STREAM_SKIP( 6 ) ) goto Bad_Format; @@ -213,13 +209,13 @@ has_head = 1; - /* the table length should be 0x36, but certain font tools - * make it 0x38, so we will just check that it is greater. - * - * note that according to the specification, - * the table must be padded to 32-bit lengths, but this doesn't - * apply to the value of its "Length" field !! - */ + /* The table length should be 0x36, but certain font tools + * make it 0x38, so we will just check that it is greater. + * + * Note that according to the specification, + * the table must be padded to 32-bit lengths, but this doesn't + * apply to the value of its "Length" field! + */ if ( table.Length < 0x36 || FT_STREAM_SEEK( table.Offset + 12 ) || FT_READ_ULONG( magic ) || @@ -238,7 +234,7 @@ return error; Bad_Format: - error = FT_Err_Unknown_File_Format; + error = SFNT_Err_Unknown_File_Format; goto Exit; } @@ -257,7 +253,7 @@ /* stream :: The input stream. */ /* */ /* face_index :: If the font is a collection, the number of the font */ - /* in the collection, ignored otherwise. */ + /* in the collection. Must be zero otherwise. */ /* */ /* <Output> */ /* sfnt :: The SFNT header. */ @@ -280,7 +276,7 @@ SFNT_Header sfnt ) { FT_Error error; - FT_ULong format_tag, offset; + FT_ULong font_format_tag, format_tag, offset; FT_Memory memory = stream->memory; static const FT_Frame_Field sfnt_header_fields[] = @@ -317,16 +313,17 @@ face->num_tables = 0; - /* first of all, read the first 4 bytes. If it is `ttcf', then the */ - /* file is a TrueType collection, otherwise it can be any other */ - /* kind of font. */ - /* */ + /* First of all, read the first 4 bytes. If it is `ttcf', then the */ + /* file is a TrueType collection, otherwise it is a single-face font. */ + /* */ offset = FT_STREAM_POS(); - if ( FT_READ_ULONG( format_tag ) ) + if ( FT_READ_ULONG( font_format_tag ) ) goto Exit; - if ( format_tag == TTAG_ttcf ) + format_tag = font_format_tag; + + if ( font_format_tag == TTAG_ttcf ) { FT_Int n; @@ -358,8 +355,8 @@ /* seek to the appropriate TrueType file, then read tag */ offset = face->ttc_header.offsets[face_index]; - if ( FT_STREAM_SEEK( offset ) || - FT_READ_LONG( format_tag ) ) + if ( FT_STREAM_SEEK( offset ) || + FT_READ_LONG( format_tag ) ) goto Exit; } @@ -376,8 +373,13 @@ { FT_TRACE2(( "tt_face_load_sfnt_header: file is not SFNT!\n" )); error = SFNT_Err_Unknown_File_Format; + goto Exit; } + /* disallow face index values > 0 for non-TTC files */ + if ( font_format_tag != TTAG_ttcf && face_index > 0 ) + error = SFNT_Err_Bad_Argument; + Exit: return error; } @@ -744,12 +746,12 @@ face->root.num_glyphs = maxProfile->numGlyphs; face->root.internal->max_points = - (FT_UShort)MAX( maxProfile->maxCompositePoints, - maxProfile->maxPoints ); + (FT_UShort)FT_MAX( maxProfile->maxCompositePoints, + maxProfile->maxPoints ); face->root.internal->max_contours = - (FT_Short)MAX( maxProfile->maxCompositeContours, - maxProfile->maxContours ); + (FT_Short)FT_MAX( maxProfile->maxCompositeContours, + maxProfile->maxContours ); face->max_components = (FT_ULong)maxProfile->maxComponentElements + maxProfile->maxComponentDepth; @@ -840,16 +842,16 @@ { #ifdef FT_CONFIG_OPTION_INCREMENTAL - /* If this is an incrementally loaded font and there are */ - /* overriding metrics tolerate a missing 'hmtx' table. */ + /* If this is an incrementally loaded font and there are */ + /* overriding metrics tolerate a missing 'hmtx' table. */ if ( face->root.internal->incremental_interface && face->root.internal->incremental_interface->funcs-> - get_glyph_metrics ) + get_glyph_metrics ) { face->horizontal.number_Of_HMetrics = 0; error = SFNT_Err_Ok; goto Exit; - } + } #endif FT_ERROR(( " no horizontal metrics in file!\n" )); @@ -900,7 +902,8 @@ /* do we have an inconsistent number of metric values? */ { TT_ShortMetrics* cur = *shorts; - TT_ShortMetrics* limit = cur + MIN( num_shorts, num_shorts_checked ); + TT_ShortMetrics* limit = cur + + FT_MIN( num_shorts, num_shorts_checked ); for ( ; cur < limit; cur++ ) @@ -1779,6 +1782,7 @@ FT_Memory memory = stream->memory; TT_Hdmx hdmx = &face->hdmx; + FT_Short num_records; FT_Long num_glyphs; FT_Long record_size; @@ -1796,7 +1800,7 @@ goto Exit; hdmx->version = FT_GET_USHORT(); - hdmx->num_records = FT_GET_SHORT(); + num_records = FT_GET_SHORT(); record_size = FT_GET_LONG(); FT_FRAME_EXIT(); @@ -1805,9 +1809,10 @@ if ( hdmx->version != 0 ) goto Exit; - if ( FT_NEW_ARRAY( hdmx->records, hdmx->num_records ) ) + if ( FT_NEW_ARRAY( hdmx->records, num_records ) ) goto Exit; + hdmx->num_records = num_records; num_glyphs = face->root.num_glyphs; record_size -= num_glyphs + 2; @@ -1867,4 +1872,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/sfnt/ttload.h b/src/libs/freetype2/sfnt/ttload.h index 198ad9d4b2..27c41b50b9 100644 --- a/src/libs/freetype2/sfnt/ttload.h +++ b/src/libs/freetype2/sfnt/ttload.h @@ -134,4 +134,4 @@ FT_END_HEADER #endif /* __TTLOAD_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/sfnt/ttpost.c b/src/libs/freetype2/sfnt/ttpost.c index b110d757b6..3d526db4cf 100644 --- a/src/libs/freetype2/sfnt/ttpost.c +++ b/src/libs/freetype2/sfnt/ttpost.c @@ -5,7 +5,7 @@ /* Postcript name table processing for TrueType and OpenType fonts */ /* (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -50,7 +50,7 @@ #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES -#include FT_INTERNAL_POSTSCRIPT_NAMES_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H #define MAC_NAME( x ) ( (FT_String*)psnames->macintosh_name( x ) ) @@ -441,7 +441,7 @@ FT_Fixed format; #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES - PSNames_Service psnames; + FT_Service_PsCMaps psnames; #endif @@ -452,7 +452,7 @@ return SFNT_Err_Invalid_Glyph_Index; #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES - psnames = (PSNames_Service)face->psnames; + psnames = (FT_Service_PsCMaps)face->psnames; if ( !psnames ) return SFNT_Err_Unimplemented_Feature; #endif @@ -510,7 +510,7 @@ *PSname = MAC_NAME( idx ); } } - + /* nothing to do for format == 0x00030000L */ End: @@ -518,4 +518,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/sfnt/ttpost.h b/src/libs/freetype2/sfnt/ttpost.h index 2286e40807..6f06d75a71 100644 --- a/src/libs/freetype2/sfnt/ttpost.h +++ b/src/libs/freetype2/sfnt/ttpost.h @@ -43,4 +43,4 @@ FT_END_HEADER #endif /* __TTPOST_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/sfnt/ttsbit.c b/src/libs/freetype2/sfnt/ttsbit.c index b67e482d83..444c27acc0 100644 --- a/src/libs/freetype2/sfnt/ttsbit.c +++ b/src/libs/freetype2/sfnt/ttsbit.c @@ -4,7 +4,7 @@ /* */ /* TrueType and OpenType embedded bitmap support (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -622,22 +622,22 @@ FT_LOCAL_DEF( FT_Error ) tt_face_set_sbit_strike( TT_Face face, - FT_Int x_ppem, - FT_Int y_ppem, + FT_UInt x_ppem, + FT_UInt y_ppem, FT_ULong *astrike_index ) { FT_ULong i; - if ( x_ppem < 0 || x_ppem > 255 || + if ( x_ppem > 255 || y_ppem < 1 || y_ppem > 255 ) return SFNT_Err_Invalid_PPem; for ( i = 0; i < face->num_sbit_strikes; i++ ) { - if ( ( face->sbit_strikes[i].y_ppem == y_ppem ) && - ( ( x_ppem == 0 ) || - ( face->sbit_strikes[i].x_ppem == x_ppem ) ) ) + if ( ( (FT_UInt)face->sbit_strikes[i].y_ppem == y_ppem ) && + ( ( x_ppem == 0 ) || + ( (FT_UInt)face->sbit_strikes[i].x_ppem == x_ppem ) ) ) { *astrike_index = i; return SFNT_Err_Ok; @@ -754,7 +754,7 @@ /*************************************************************************/ /* */ /* <Function> */ - /* find_sbit_image */ + /* tt_find_sbit_image */ /* */ /* <Description> */ /* Checks whether an embedded bitmap (an `sbit') exists for a given */ @@ -779,13 +779,13 @@ /* SFNT_Err_Invalid_Argument if no sbit exists for the requested */ /* glyph. */ /* */ - static FT_Error - find_sbit_image( TT_Face face, - FT_UInt glyph_index, - FT_ULong strike_index, - TT_SBit_Range *arange, - TT_SBit_Strike *astrike, - FT_ULong *aglyph_offset ) + FT_LOCAL( FT_Error ) + tt_find_sbit_image( TT_Face face, + FT_UInt glyph_index, + FT_ULong strike_index, + TT_SBit_Range *arange, + TT_SBit_Strike *astrike, + FT_ULong *aglyph_offset ) { FT_Error error; TT_SBit_Strike strike; @@ -819,7 +819,7 @@ /*************************************************************************/ /* */ /* <Function> */ - /* load_sbit_metrics */ + /* tt_load_sbit_metrics */ /* */ /* <Description> */ /* Gets the big metrics for a given SBit. */ @@ -843,10 +843,10 @@ /* positioned just after the metrics header in the `EBDT' table on */ /* function exit. */ /* */ - static FT_Error - load_sbit_metrics( FT_Stream stream, - TT_SBit_Range range, - TT_SBit_Metrics metrics ) + FT_LOCAL( FT_Error ) + tt_load_sbit_metrics( FT_Stream stream, + TT_SBit_Range range, + TT_SBit_Metrics metrics ) { FT_Error error = SFNT_Err_Ok; @@ -1228,13 +1228,13 @@ if ( FT_STREAM_SEEK( ebdt_pos + glyph_offset ) ) goto Exit; - error = load_sbit_metrics( stream, range, metrics ); + error = tt_load_sbit_metrics( stream, range, metrics ); if ( error ) goto Exit; - /* this function is recursive. At the top-level call, we */ + /* This function is recursive. At the top-level call, we */ /* compute the dimensions of the higher-level glyph to */ - /* allocate the final pixmap buffer */ + /* allocate the final pixmap buffer. */ if ( depth == 0 ) { FT_Long size; @@ -1355,7 +1355,7 @@ y_offset + comp->y_offset, stream, &elem_metrics, - depth+1 ); + depth + 1 ); if ( error ) goto Fail_Memory; } @@ -1419,8 +1419,8 @@ /* Check whether there is a glyph sbit for the current index */ - error = find_sbit_image( face, glyph_index, strike_index, - &range, &strike, &glyph_offset ); + error = tt_find_sbit_image( face, glyph_index, strike_index, + &range, &strike, &glyph_offset ); if ( error ) goto Exit; @@ -1464,4 +1464,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/sfnt/ttsbit.h b/src/libs/freetype2/sfnt/ttsbit.h index 26207783ce..f1b63b7ec4 100644 --- a/src/libs/freetype2/sfnt/ttsbit.h +++ b/src/libs/freetype2/sfnt/ttsbit.h @@ -4,7 +4,7 @@ /* */ /* TrueType and OpenType embedded bitmap support (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -37,10 +37,23 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) tt_face_set_sbit_strike( TT_Face face, - FT_Int x_ppem, - FT_Int y_ppem, + FT_UInt x_ppem, + FT_UInt y_ppem, FT_ULong *astrike_index ); + FT_LOCAL( FT_Error ) + tt_find_sbit_image( TT_Face face, + FT_UInt glyph_index, + FT_ULong strike_index, + TT_SBit_Range *arange, + TT_SBit_Strike *astrike, + FT_ULong *aglyph_offset ); + + FT_LOCAL( FT_Error ) + tt_load_sbit_metrics( FT_Stream stream, + TT_SBit_Range range, + TT_SBit_Metrics metrics ); + FT_LOCAL( FT_Error ) tt_face_load_sbit_image( TT_Face face, FT_ULong strike_index, @@ -56,4 +69,4 @@ FT_END_HEADER #endif /* __TTSBIT_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/smooth/descrip.mms b/src/libs/freetype2/smooth/descrip.mms index 8d37fd886f..9ebc7ff221 100644 --- a/src/libs/freetype2/smooth/descrip.mms +++ b/src/libs/freetype2/smooth/descrip.mms @@ -20,4 +20,4 @@ OBJS=smooth.obj all : $(OBJS) library [--.lib]freetype.olb $(OBJS) -# EOF +# EOF diff --git a/src/libs/freetype2/smooth/ftgrays.c b/src/libs/freetype2/smooth/ftgrays.c index e1ff104bd1..499cc8cb57 100644 --- a/src/libs/freetype2/smooth/ftgrays.c +++ b/src/libs/freetype2/smooth/ftgrays.c @@ -4,7 +4,7 @@ /* */ /* A new `perfect' anti-aliasing renderer (body). */ /* */ -/* Copyright 2000-2001, 2002 by */ +/* Copyright 2000-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -340,7 +340,7 @@ long byte_size ) { ras.cells = (PCell)buffer; - ras.max_cells = byte_size / sizeof ( TCell ); + ras.max_cells = (int)( byte_size / sizeof ( TCell ) ); ras.num_cells = 0; ras.area = 0; ras.cover = 0; @@ -567,16 +567,16 @@ if ( ex1 != ex2 ) { - p = ONE_PIXEL * ( y2 - y1 + delta ); - lift = (TCoord)( p / dx ); - rem = (TCoord)( p % dx ); + p = ONE_PIXEL * ( y2 - y1 + delta ); + lift = (TCoord)( p / dx ); + rem = (TCoord)( p % dx ); if ( rem < 0 ) { lift--; rem += (TCoord)dx; } - mod -= dx; + mod -= (int)dx; while ( ex1 != ex2 ) { @@ -2156,4 +2156,4 @@ }; -/* END */ +/* END */ diff --git a/src/libs/freetype2/smooth/ftgrays.h b/src/libs/freetype2/smooth/ftgrays.h index 783fb51ad4..2d409543dc 100644 --- a/src/libs/freetype2/smooth/ftgrays.h +++ b/src/libs/freetype2/smooth/ftgrays.h @@ -54,4 +54,4 @@ #endif /* __FTGRAYS_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/smooth/ftsmerrs.h b/src/libs/freetype2/smooth/ftsmerrs.h index 027ec6734b..0c2a2ecd90 100644 --- a/src/libs/freetype2/smooth/ftsmerrs.h +++ b/src/libs/freetype2/smooth/ftsmerrs.h @@ -38,4 +38,4 @@ #endif /* __FTSMERRS_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/smooth/ftsmooth.c b/src/libs/freetype2/smooth/ftsmooth.c index 1605d2fe97..af8783e296 100644 --- a/src/libs/freetype2/smooth/ftsmooth.c +++ b/src/libs/freetype2/smooth/ftsmooth.c @@ -4,7 +4,7 @@ /* */ /* Anti-aliasing renderer interface (body). */ /* */ -/* Copyright 2000-2001, 2002 by */ +/* Copyright 2000-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -132,21 +132,21 @@ /* compute the control box, and grid fit it */ FT_Outline_Get_CBox( outline, &cbox ); - cbox.xMin &= -64; - cbox.yMin &= -64; - cbox.xMax = ( cbox.xMax + 63 ) & -64; - cbox.yMax = ( cbox.yMax + 63 ) & -64; + cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); + cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); + cbox.xMax = FT_PIX_CEIL( cbox.xMax ); + cbox.yMax = FT_PIX_CEIL( cbox.yMax ); - width = ( cbox.xMax - cbox.xMin ) >> 6; - height = ( cbox.yMax - cbox.yMin ) >> 6; + width = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 ); + height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 ); bitmap = &slot->bitmap; memory = render->root.memory; /* release old bitmap buffer */ - if ( slot->flags & FT_GLYPH_OWN_BITMAP ) + if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) { FT_FREE( bitmap->buffer ); - slot->flags &= ~FT_GLYPH_OWN_BITMAP; + slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; } /* allocate new one, depends on pixel format */ @@ -154,7 +154,7 @@ if ( hmul ) { width = width * hmul; - pitch = ( width + 3 ) & -4; + pitch = FT_PAD_CEIL( width, 4 ); } if ( vmul ) @@ -169,7 +169,7 @@ if ( FT_ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) ) goto Exit; - slot->flags |= FT_GLYPH_OWN_BITMAP; + slot->internal->flags |= FT_GLYPH_OWN_BITMAP; /* translate outline to render it into the bitmap */ FT_Outline_Translate( outline, -cbox.xMin, -cbox.yMin ); @@ -236,6 +236,9 @@ FT_Render_Mode mode, FT_Vector* origin ) { + if ( mode == FT_RENDER_MODE_LIGHT ) + mode = FT_RENDER_MODE_NORMAL; + return ft_smooth_render_generic( render, slot, mode, origin, FT_RENDER_MODE_NORMAL, 0, 0 ); @@ -284,7 +287,7 @@ const FT_Renderer_Class ft_smooth_renderer_class = { { - ft_module_renderer, + FT_MODULE_RENDERER, sizeof( FT_RendererRec ), "smooth", @@ -313,7 +316,7 @@ const FT_Renderer_Class ft_smooth_lcd_renderer_class = { { - ft_module_renderer, + FT_MODULE_RENDERER, sizeof( FT_RendererRec ), "smooth-lcd", @@ -343,7 +346,7 @@ const FT_Renderer_Class ft_smooth_lcdv_renderer_class = { { - ft_module_renderer, + FT_MODULE_RENDERER, sizeof( FT_RendererRec ), "smooth-lcdv", @@ -368,4 +371,4 @@ }; -/* END */ +/* END */ diff --git a/src/libs/freetype2/smooth/ftsmooth.h b/src/libs/freetype2/smooth/ftsmooth.h index 4107ead2db..62cced4487 100644 --- a/src/libs/freetype2/smooth/ftsmooth.h +++ b/src/libs/freetype2/smooth/ftsmooth.h @@ -46,4 +46,4 @@ FT_END_HEADER #endif /* __FTSMOOTH_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/smooth/module.mk b/src/libs/freetype2/smooth/module.mk index 2eba7fe315..ead77cf30b 100644 --- a/src/libs/freetype2/smooth/module.mk +++ b/src/libs/freetype2/smooth/module.mk @@ -19,4 +19,4 @@ add_smooth_renderer: $(OPEN_DRIVER)ft_smooth_renderer_class$(CLOSE_DRIVER) $(ECHO_DRIVER)smooth $(ECHO_DRIVER_DESC)anti-aliased bitmap renderer$(ECHO_DRIVER_DONE) -# EOF +# EOF diff --git a/src/libs/freetype2/smooth/rules.mk b/src/libs/freetype2/smooth/rules.mk index a4713dca0c..4f27f01dba 100644 --- a/src/libs/freetype2/smooth/rules.mk +++ b/src/libs/freetype2/smooth/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2001 by +# Copyright 1996-2000, 2001, 2003 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -15,24 +15,23 @@ # smooth driver directory # -SMOOTH_DIR := $(SRC_)smooth -SMOOTH_DIR_ := $(SMOOTH_DIR)$(SEP) +SMOOTH_DIR := $(SRC_DIR)/smooth # compilation flags for the driver # -SMOOTH_COMPILE := $(FT_COMPILE) $I$(SMOOTH_DIR) +SMOOTH_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(SMOOTH_DIR)) # smooth driver sources (i.e., C files) # -SMOOTH_DRV_SRC := $(SMOOTH_DIR_)ftgrays.c \ - $(SMOOTH_DIR_)ftsmooth.c +SMOOTH_DRV_SRC := $(SMOOTH_DIR)/ftgrays.c \ + $(SMOOTH_DIR)/ftsmooth.c # smooth driver headers # SMOOTH_DRV_H := $(SMOOTH_DRV_SRC:%c=%h) \ - $(SMOOTH_DIR_)ftsmerrs.h + $(SMOOTH_DIR)/ftsmerrs.h # smooth driver object(s) @@ -40,25 +39,25 @@ SMOOTH_DRV_H := $(SMOOTH_DRV_SRC:%c=%h) \ # SMOOTH_DRV_OBJ_M is used during `multi' builds. # SMOOTH_DRV_OBJ_S is used during `single' builds. # -SMOOTH_DRV_OBJ_M := $(SMOOTH_DRV_SRC:$(SMOOTH_DIR_)%.c=$(OBJ_)%.$O) -SMOOTH_DRV_OBJ_S := $(OBJ_)smooth.$O +SMOOTH_DRV_OBJ_M := $(SMOOTH_DRV_SRC:$(SMOOTH_DIR)/%.c=$(OBJ_DIR)/%.$O) +SMOOTH_DRV_OBJ_S := $(OBJ_DIR)/smooth.$O # smooth driver source file for single build # -SMOOTH_DRV_SRC_S := $(SMOOTH_DIR_)smooth.c +SMOOTH_DRV_SRC_S := $(SMOOTH_DIR)/smooth.c # smooth driver - single object # $(SMOOTH_DRV_OBJ_S): $(SMOOTH_DRV_SRC_S) $(SMOOTH_DRV_SRC) \ - $(FREETYPE_H) $(SMOOTH_DRV_H) - $(SMOOTH_COMPILE) $T$@ $(SMOOTH_DRV_SRC_S) + $(FREETYPE_H) $(SMOOTH_DRV_H) + $(SMOOTH_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(SMOOTH_DRV_SRC_S)) # smooth driver - multiple objects # -$(OBJ_)%.$O: $(SMOOTH_DIR_)%.c $(FREETYPE_H) $(SMOOTH_DRV_H) - $(SMOOTH_COMPILE) $T$@ $< +$(OBJ_DIR)/%.$O: $(SMOOTH_DIR)/%.c $(FREETYPE_H) $(SMOOTH_DRV_H) + $(SMOOTH_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) # update main driver object lists @@ -67,4 +66,4 @@ DRV_OBJS_S += $(SMOOTH_DRV_OBJ_S) DRV_OBJS_M += $(SMOOTH_DRV_OBJ_M) -# EOF +# EOF diff --git a/src/libs/freetype2/smooth/smooth.c b/src/libs/freetype2/smooth/smooth.c index 22d9c17433..ff6be3e400 100644 --- a/src/libs/freetype2/smooth/smooth.c +++ b/src/libs/freetype2/smooth/smooth.c @@ -23,4 +23,4 @@ #include "ftsmooth.c" -/* END */ +/* END */ diff --git a/src/libs/freetype2/tools/docmaker.py b/src/libs/freetype2/tools/docmaker.py deleted file mode 100755 index a818d1a735..0000000000 --- a/src/libs/freetype2/tools/docmaker.py +++ /dev/null @@ -1,1665 +0,0 @@ -#!/usr/bin/env python -# -# DocMaker 0.1 (c) 2000-2001 David Turner <david@freetype.org> -# -# DocMaker is a very simple program used to generate the API Reference -# of programs by extracting comments from source files, and generating -# the equivalent HTML documentation. -# -# DocMaker is very similar to other tools like Doxygen, with the -# following differences: -# -# - It is written in Python (so it is slow, but easy to maintain and -# improve). -# -# - The comment syntax used by DocMaker is simpler and makes for -# clearer comments. -# -# Of course, it doesn't have all the goodies of most similar tools, -# (e.g. C++ class hierarchies), but hey, it is only 2000 lines of -# Python. -# -# DocMaker is mainly used to generate the API references of several -# FreeType packages. -# -# - David -# - -import fileinput, sys, os, time, string, glob, getopt - -# The Project's title. This can be overridden from the command line with -# the options "-t" or "--title". -# -project_title = "Project" - -# The project's filename prefix. This can be set from the command line with -# the options "-p" or "--prefix" -# -project_prefix = "" - -# The project's documentation output directory. This can be set from the -# command line with the options "-o" or "--output". -# -output_dir = None - - -# The following defines the HTML header used by all generated pages. -# -html_header_1 = """\ -<html> -<header> -<title>""" - -html_header_2= """ API Reference - - - - -

""" - -html_header_3=""" API Reference

-""" - -# This is recomputed later when the project title changes. -# -html_header = html_header_1 + project_title + html_header_2 + project_title + html_header_3 - - -# The HTML footer used by all generated pages. -# -html_footer = """\ - -""" - -# The header and footer used for each section. -# -section_title_header = "

" -section_title_footer = "

" - -# The header and footer used for code segments. -# -code_header = "
"
-code_footer = "
" - -# Paragraph header and footer. -# -para_header = "

" -para_footer = "

" - -# Block header and footer. -# -block_header = "
" -block_footer = "

" - -# Description header/footer. -# -description_header = "
" -description_footer = "

" - -# Marker header/inter/footer combination. -# -marker_header = "
" -marker_inter = "
" -marker_footer = "
" - -# Source code extracts header/footer. -# -source_header = "
"
-source_footer = "

" - -# Chapter header/inter/footer. -# -chapter_header = "

" -chapter_inter = "

    " -chapter_footer = "
" - -current_section = None - - -# This function is used to sort the index. It is a simple lexicographical -# sort, except that it places capital letters before lowercase ones. -# -def index_sort( s1, s2 ): - if not s1: - return -1 - - if not s2: - return 1 - - l1 = len( s1 ) - l2 = len( s2 ) - m1 = string.lower( s1 ) - m2 = string.lower( s2 ) - - for i in range( l1 ): - if i >= l2 or m1[i] > m2[i]: - return 1 - - if m1[i] < m2[i]: - return -1 - - if s1[i] < s2[i]: - return -1 - - if s1[i] > s2[i]: - return 1 - - if l2 > l1: - return -1 - - return 0 - - -# Sort input_list, placing the elements of order_list in front. -# -def sort_order_list( input_list, order_list ): - new_list = order_list[:] - for id in input_list: - if not id in order_list: - new_list.append( id ) - return new_list - - -# Translate a single line of source to HTML. This will convert -# a "<" into "<.", ">" into ">.", etc. -# -def html_quote( line ): - result = string.replace( line, "&", "&" ) - result = string.replace( result, "<", "<" ) - result = string.replace( result, ">", ">" ) - return result - -# same as 'html_quote', but ignores left and right brackets -# -def html_quote0( line ): - return string.replace( line, "&", "&" ) - - -# Open the standard output to a given project documentation file. Use -# "output_dir" to determine the filename location if necessary and save the -# old stdout in a tuple that is returned by this function. -# -def open_output( filename ): - global output_dir - - if output_dir and output_dir != "": - filename = output_dir + os.sep + filename - - old_stdout = sys.stdout - new_file = open( filename, "w" ) - sys.stdout = new_file - - return ( new_file, old_stdout ) - - -# Close the output that was returned by "close_output". -# -def close_output( output ): - output[0].close() - sys.stdout = output[1] - - -# Check output directory. -# -def check_output( ): - global output_dir - if output_dir: - if output_dir != "": - if not os.path.isdir( output_dir ): - sys.stderr.write( "argument" + " '" + output_dir + "' " + - "is not a valid directory" ) - sys.exit( 2 ) - else: - output_dir = None - - -def compute_time_html( ): - global html_footer - time_string = time.asctime( time.localtime( time.time() ) ) - html_footer = "

generated on " + time_string + "

" + html_footer - -# The FreeType 2 reference is extracted from the source files. These -# contain various comment blocks that follow one of the following formats: -# -# /************************** -# * -# * FORMAT1 -# * -# * -# * -# * -# *************************/ -# -# /**************************/ -# /* */ -# /* FORMAT2 */ -# /* */ -# /* */ -# /* */ -# /* */ -# -# /**************************/ -# /* */ -# /* FORMAT3 */ -# /* */ -# /* */ -# /* */ -# /* */ -# /**************************/ -# -# Each block contains a list of markers; each one can be followed by -# some arbitrary text or a list of fields. Here an example: -# -# -# MyStruct -# -# -# this structure holds some data -# -# -# x :: horizontal coordinate -# y :: vertical coordinate -# -# -# This example defines three markers: 'Struct', 'Description' & 'Fields'. -# The first two markers contain arbitrary text, while the last one contains -# a list of fields. -# -# Each field is simply of the format: WORD :: TEXT... -# -# Note that typically each comment block is followed by some source code -# declaration that may need to be kept in the reference. -# -# Note that markers can alternatively be written as "@MARKER:" instead of -# "". All marker identifiers are converted to lower case during -# parsing in order to simply sorting. -# -# We associate with each block the following source lines that do not begin -# with a comment. For example, the following: -# -# /********************************** -# * -# * blabla -# * -# */ -# -# bla_bla_bla -# bilip_bilip -# -# /* - this comment acts as a separator - */ -# -# blo_blo_blo -# -# -# will only keep the first two lines of sources with -# the "blabla" block. -# -# However, the comment will be kept, with following source lines if it -# contains a starting '#' or '@' as in: -# -# /*@.....*/ -# /*#.....*/ -# /* @.....*/ -# /* #.....*/ -# - - - -############################################################################# -# -# The DocCode class is used to store source code lines. -# -# 'self.lines' contains a set of source code lines that will be dumped as -# HTML in a
 tag.
-#
-#   The object is filled line by line by the parser; it strips the leading
-#   "margin" space from each input line before storing it in 'self.lines'.
-#
-class DocCode:
-
-    def __init__( self, margin = 0 ):
-        self.lines  = []
-        self.margin = margin
-
-
-    def add( self, line ):
-        # remove margin whitespace
-        #
-        if string.strip( line[: self.margin] ) == "":
-            line = line[self.margin :]
-        self.lines.append( line )
-
-
-    def dump( self ):
-        for line in self.lines:
-            print "--" + line
-        print ""
-
-
-    def get_identifier( self ):
-        # this function should never be called
-        #
-        return "UNKNOWN_CODE_IDENTIFIER!"
-
-
-    def dump_html( self, identifiers = None ):
-        # clean the last empty lines
-        #
-        l = len( self.lines ) - 1
-        while l > 0 and string.strip( self.lines[l - 1] ) == "":
-            l = l - 1
-
-        # The code footer should be directly appended to the last code
-        # line to avoid an additional blank line.
-        #
-        print code_header,
-        for line in self.lines[0 : l+1]:
-            print '\n' + html_quote(line),
-        print code_footer,
-
-
-
-#############################################################################
-#
-# The DocParagraph is used to store text paragraphs.
-# 'self.words' is simply a list of words for the paragraph.
-#
-# The paragraph is filled line by line by the parser.
-#
-class DocParagraph:
-
-    def __init__( self ):
-        self.words = []
-
-
-    def add( self, line ):
-        # Get rid of unwanted spaces in the paragraph.
-        #
-        # The following two lines are the same as
-        #
-        #   self.words.extend( string.split( line ) )
-        #
-        # but older Python versions don't have the `extend' attribute.
-        #
-        last = len( self.words )
-        self.words[last : last] = string.split( line )
-
-
-    # This function is used to retrieve the first word of a given
-    # paragraph.
-    #
-    def get_identifier( self ):
-        if self.words:
-            return self.words[0]
-
-        # should never happen
-        #
-        return "UNKNOWN_PARA_IDENTIFIER!"
-
-
-    def get_words( self ):
-        return self.words[:]
-
-
-    def dump( self, identifiers = None ):
-        max_width = 50
-        cursor    = 0
-        line      = ""
-        extra     = None
-        alphanum  = string.lowercase + string.uppercase + string.digits + '_'
-
-        for word in self.words:
-            # process cross references if needed
-            #
-            if identifiers and word and word[0] == '@':
-                word = word[1 :]
-
-                # we need to find non-alphanumeric characters
-                #
-                l = len( word )
-                i = 0
-                while i < l and word[i] in alphanum:
-                    i = i + 1
-
-                if i < l:
-                    extra = word[i :]
-                    word  = word[0 : i]
-
-                block = identifiers.get( word )
-                if block:
-                    word = '' + word + ''
-                else:
-                    word = '?' + word
-
-            if cursor + len( word ) + 1 > max_width:
-                print html_quote0(line)
-                cursor = 0
-                line   = ""
-
-            line = line + word
-            if not extra:
-                line = line + " "
-
-            cursor = cursor + len( word ) + 1
-
-
-            # Handle trailing periods, commas, etc. at the end of cross
-            # references.
-            #
-            if extra:
-                if cursor + len( extra ) + 1 > max_width:
-                    print html_quote0(line)
-                    cursor = 0
-                    line   = ""
-
-                line   = line + extra + " "
-                cursor = cursor + len( extra ) + 1
-                extra  = None
-
-        if cursor > 0:
-            print html_quote0(line)
-
-        # print "§" # for debugging only
-
-
-    def dump_string( self ):
-        s     = ""
-        space = ""
-        for word in self.words:
-            s     = s + space + word
-            space = " "
-
-        return s
-
-
-    def dump_html( self, identifiers = None ):
-        print para_header
-        self.dump( identifiers )
-        print para_footer
-
-
-
-#############################################################################
-#
-# DocContent is used to store the content of a given marker.
-#
-# The "self.items" list contains (field,elements) records, where "field"
-# corresponds to a given structure field or function parameter (indicated
-# by a "::"), or NULL for a normal section of text/code.
-#
-# Hence, the following example:
-#
-#   
-#      This is an example of what can be put in a content section,
-#
-#      A second line of example text.
-#
-#      x :: A simple test field, with some contents.
-#      y :: Even before, this field has some code contents.
-#           {
-#             y = x+2;
-#           }
-#
-# should be stored as
-#
-#     [ ( None, [ DocParagraph, DocParagraph] ),
-#       ( "x",  [ DocParagraph ] ),
-#       ( "y",  [ DocParagraph, DocCode ] ) ]
-#
-# in 'self.items'.
-#
-# The DocContent object is entirely built at creation time; you must pass a
-# list of input text lines in the "lines_list" parameter.
-#
-class DocContent:
-
-    def __init__( self, lines_list ):
-        self.items  = []
-        code_mode   = 0
-        code_margin = 0
-        text        = []
-        paragraph   = None   # represents the current DocParagraph
-        code        = None   # represents the current DocCode
-
-        elements    = []     # the list of elements for the current field;
-                             # contains DocParagraph or DocCode objects
-
-        field       = None   # the current field
-
-        for aline in lines_list:
-            if code_mode == 0:
-                line   = string.lstrip( aline )
-                l      = len( line )
-                margin = len( aline ) - l
-
-                # if the line is empty, this is the end of the current
-                # paragraph
-                #
-                if l == 0 or line == '{':
-                    if paragraph:
-                        elements.append( paragraph )
-                        paragraph = None
-
-                    if line == "":
-                        continue
-
-                    code_mode   = 1
-                    code_margin = margin
-                    code        = None
-                    continue
-
-                words = string.split( line )
-
-                # test for a field delimiter on the start of the line, i.e.
-                # the token `::'
-                #
-                if len( words ) >= 2 and words[1] == "::":
-                    # start a new field - complete current paragraph if any
-                    #
-                    if paragraph:
-                        elements.append( paragraph )
-                        paragraph = None
-
-                    # append previous "field" to self.items
-                    #
-                    self.items.append( ( field, elements ) )
-
-                    # start new field and elements list
-                    #
-                    field    = words[0]
-                    elements = []
-                    words    = words[2 :]
-
-                # append remaining words to current paragraph
-                #
-                if len( words ) > 0:
-                    line = string.join( words )
-                    if not paragraph:
-                        paragraph = DocParagraph()
-                    paragraph.add( line )
-
-            else:
-                # we are in code mode...
-                #
-                line = aline
-
-                # the code block ends with a line that has a single '}' on
-                # it that is located at the same column that the opening
-                # accolade...
-                #
-                if line == " " * code_margin + '}':
-                    if code:
-                        elements.append( code )
-                        code = None
-
-                    code_mode   = 0
-                    code_margin = 0
-
-                # otherwise, add the line to the current paragraph
-                #
-                else:
-                    if not code:
-                        code = DocCode()
-                    code.add( line )
-
-        if paragraph:
-            elements.append( paragraph )
-
-        if code:
-            elements.append( code )
-
-        self.items.append( ( field, elements ) )
-
-
-    def get_identifier( self ):
-        if self.items:
-            item = self.items[0]
-            for element in item[1]:
-                return element.get_identifier()
-
-        # should never happen
-        #
-        return "UNKNOWN_CONTENT_IDENTIFIER!"
-
-
-    def get_title( self ):
-        if self.items:
-            item = self.items[0]
-            for element in item[1]:
-                return element.dump_string()
-
-        # should never happen
-        #
-        return "UNKNOWN_CONTENT_TITLE!"
-
-
-    def dump( self ):
-        for item in self.items:
-            field = item[0]
-            if field:
-                print ""
-
-            for element in item[1]:
-                element.dump()
-
-            if field:
-                print ""
-
-
-    def dump_html( self, identifiers = None ):
-        n        = len( self.items )
-        in_table = 0
-
-        for i in range( n ):
-            item  = self.items[i]
-            field = item[0]
-
-            if not field:
-                if in_table:
-                    print ""
-                    in_table = 0
-
-                for element in item[1]:
-                    element.dump_html( identifiers )
-
-            else:
-                if not in_table:
-                    print "
" - in_table = 1 - else: - print "
" - - print "" + field + "" - - for element in item[1]: - element.dump_html( identifiers ) - - if in_table: - print "
" - - - def dump_html_in_table( self, identifiers = None ): - n = len( self.items ) - in_table = 0 - - for i in range( n ): - item = self.items[i] - field = item[0] - - if not field: - if item[1]: - print "" - for element in item[1]: - element.dump_html( identifiers ) - print "" - - else: - print "" + field + "" - - for element in item[1]: - element.dump_html( identifiers ) - - print "" - - - -############################################################################# -# -# The DocBlock class is used to store a given comment block. It contains -# a list of markers, as well as a list of contents for each marker. -# -# "self.items" is a list of (marker, contents) elements, where 'marker' is -# a lowercase marker string, and 'contents' is a DocContent object. -# -# "self.source" is simply a list of text lines taken from the uncommented -# source itself. -# -# Finally, "self.name" is a simple identifier used to uniquely identify -# the block. It is taken from the first word of the first paragraph of the -# first marker of a given block, i.e: -# -# Goo -# Bla bla bla -# -# will have a name of "Goo" -# -class DocBlock: - - def __init__( self, block_line_list = [], source_line_list = [] ): - self.items = [] # current ( marker, contents ) list - self.section = None # section this block belongs to - self.filename = "unknown" # filename defining this block - self.lineno = 0 # line number in filename - - marker = None # current marker - content = [] # current content lines list - alphanum = string.letters + string.digits + "_" - self.name = None - - for line in block_line_list: - line2 = string.lstrip( line ) - l = len( line2 ) - margin = len( line ) - l - - if l > 3: - ender = None - if line2[0] == '<': - ender = '>' - elif line2[0] == '@': - ender = ':' - - if ender: - i = 1 - while i < l and line2[i] in alphanum: - i = i + 1 - if i < l and line2[i] == ender: - if marker and content: - self.add( marker, content ) - marker = line2[1 : i] - content = [] - line2 = string.lstrip( line2[i+1 :] ) - l = len( line2 ) - line = " " * margin + line2 - - content.append( line ) - - if marker and content: - self.add( marker, content ) - - self.source = [] - if self.items: - self.source = source_line_list - - # now retrieve block name when possible - # - if self.items: - first = self.items[0] - self.name = first[1].get_identifier() - - - # This function adds a new element to 'self.items'. - # - # 'marker' is a marker string, or None. - # 'lines' is a list of text lines used to compute a list of - # DocContent objects. - # - def add( self, marker, lines ): - # remove the first and last empty lines from the content list - # - l = len( lines ) - if l > 0: - i = 0 - while l > 0 and string.strip( lines[l - 1] ) == "": - l = l - 1 - while i < l and string.strip( lines[i] ) == "": - i = i + 1 - lines = lines[i : l] - l = len( lines ) - - # add a new marker only if its marker and its content list - # are not empty - # - if l > 0 and marker: - content = DocContent( lines ) - self.items.append( ( string.lower( marker ), content ) ) - - - def find_content( self, marker ): - for item in self.items: - if ( item[0] == marker ): - return item[1] - return None - - - def html_address( self ): - section = self.section - if section and section.filename: - return section.filename + '#' + self.name - - return "" # this block is not in a section? - - - def location( self ): - return self.filename + ':' + str( self.lineno ) - - - def print_warning( self, message ): - sys.stderr.write( "WARNING:" + - self.location() + ": " + message + '\n' ) - - - def print_error( self, message ): - sys.stderr.write( "ERROR:" + - self.location() + ": " + message + '\n' ) - sys.exit() - - - def dump( self ): - for i in range( len( self.items ) ): - print "[" + self.items[i][0] + "]" - content = self.items[i][1] - content.dump() - - - def dump_html( self, identifiers = None ): - types = ['type', 'struct', 'functype', 'function', - 'constant', 'enum', 'macro', 'structure', 'also'] - - parameters = ['input', 'inout', 'output', 'return'] - - if not self.items: - return - - # start of a block - # - print block_header - - # place html anchor if needed - # - if self.name: - print '' - print "

" + self.name + "

" - print "
" - - # print source code - # - if not self.source: - print block_footer - return - - lines = self.source - l = len( lines ) - 1 - while l >= 0 and string.strip( lines[l] ) == "": - l = l - 1 - print source_header - print "" - for line in lines[0 : l+1]: - print html_quote(line) - print source_footer - - in_table = 0 - - # dump each (marker,content) element - # - for element in self.items: - marker = element[0] - content = element[1] - - if marker == "description": - print description_header - content.dump_html( identifiers ) - print description_footer - - elif not ( marker in types ): - sys.stdout.write( marker_header ) - sys.stdout.write( marker ) - sys.stdout.write( marker_inter + '\n' ) - content.dump_html( identifiers ) - print marker_footer - - print "" - - print block_footer - - - -############################################################################# -# -# The DocSection class is used to store a given documentation section. -# -# Each section is made of an identifier, an abstract and a description. -# -# For example, look at: -# -#
Basic_Data_Types -# -# FreeType 2 Basic Data Types -# -# <Abstract> -# Definitions of basic FreeType data types -# -# <Description> -# FreeType defines several basic data types for all its -# operations... -# -class DocSection: - - def __init__( self, block ): - self.block = block - self.name = string.lower( block.name ) - self.abstract = block.find_content( "abstract" ) - self.description = block.find_content( "description" ) - self.elements = {} - self.list = [] - self.filename = self.name + ".html" - self.chapter = None - - # sys.stderr.write( "new section '" + self.name + "'" ) - - - def add_element( self, block ): - # check that we don't have a duplicate element in this - # section - # - if self.elements.has_key( block.name ): - block.print_error( "duplicate element definition for " + - "'" + block.name + "' " + - "in section " + - "'" + self.name + "'\n" + - "previous definition in " + - "'" + self.elements[block.name].location() + "'" ) - - self.elements[block.name] = block - self.list.append( block ) - - - def print_warning( self, message ): - self.block.print_warning( message ) - - - def print_error( self, message ): - self.block.print_error( message ) - - - def dump_html( self, identifiers = None ): - """make an HTML page from a given DocSection""" - - # print HTML header - # - print html_header - - # print title - # - print section_title_header - print self.title - print section_title_footer - - # print description - # - print block_header - self.description.dump_html( identifiers ) - print block_footer - - # print elements - # - for element in self.list: - element.dump_html( identifiers ) - - print html_footer - - -class DocSectionList: - - def __init__( self ): - self.sections = {} # map section names to section objects - self.list = [] # list of sections (in creation order) - self.current_section = None # current section - self.identifiers = {} # map identifiers to blocks - - - def append_section( self, block ): - name = string.lower( block.name ) - abstract = block.find_content( "abstract" ) - - if self.sections.has_key( name ): - # There is already a section with this name in our list. We - # will try to complete it. - # - section = self.sections[name] - if section.abstract: - # This section already has an abstract defined; simply check - # that the new section doesn't provide a new one. - # - if abstract: - section.block.print_error( - "duplicate section definition for " + - "'" + name + "'\n" + - "previous definition in " + - "'" + section.block.location() + "'\n" + - "second definition in " + - "'" + block.location() + "'" ) - else: - # The old section didn't contain an abstract; we are now - # going to replace it. - # - section.abstract = abstract - section.description = block.find_content( "description" ) - section.block = block - - else: - # a new section - # - section = DocSection( block ) - self.sections[name] = section - self.list.append( section ) - - self.current_section = section - - - def append_block( self, block ): - if block.name: - section = block.find_content( "section" ) - if section: - self.append_section( block ) - - elif self.current_section: - self.current_section.add_element( block ) - block.section = self.current_section - self.identifiers[block.name] = block - - - def prepare_files( self, file_prefix = None ): - # prepare the section list, by computing section filenames and the - # index - # - if file_prefix: - prefix = file_prefix + "-" - else: - prefix = "" - - # compute section names - # - for section in self.sections.values(): - title_content = section.block.find_content( "title" ) - if title_content: - section.title = title_content.get_title() - else: - section.title = "UNKNOWN_SECTION_TITLE!" - - - # sort section elements according to the <order> marker if available - # - for section in self.sections.values(): - order = section.block.find_content( "order" ) - if order: - # sys.stderr.write( "<order> found at " - # + section.block.location() + '\n' ) - order_list = [] - for item in order.items: - for element in item[1]: - words = None - try: - words = element.get_words() - except: - section.block.print_warning( - "invalid content in <order> marker\n" ) - if words: - for word in words: - block = self.identifiers.get( word ) - if block: - if block.section == section: - order_list.append( block ) - else: - section.block.print_warning( - "invalid reference to " + - "'" + word + "' " + - "defined in other section" ) - else: - section.block.print_warning( - "invalid reference to " + - "'" + word + "'" ) - - # now sort the list of blocks according to the order list - # - new_list = order_list[:] - for block in section.list: - if not block in order_list: - new_list.append( block ) - - section.list = new_list - - # compute section filenames - # - for section in self.sections.values(): - section.filename = prefix + section.name + ".html" - - self.toc_filename = prefix + "toc.html" - self.index_filename = prefix + "index.html" - - # compute the sorted list of identifiers for the index - # - self.index = self.identifiers.keys() - self.index.sort( index_sort ) - - - def dump_html_sections( self ): - for section in self.sections.values(): - if section.filename: - output = open_output( section.filename ) - - section.dump_html( self.identifiers ) - - close_output( output ) - - - def dump_html_index( self ): - output = open_output( self.index_filename ) - - num_columns = 3 - total = len( self.index ) - line = 0 - - print html_header - print "<center><h1>General Index</h1></center>" - print "<center><table cellpadding=5><tr valign=top><td>" - - for ident in self.index: - block = self.identifiers[ident] - if block: - sys.stdout.write( '<a href="' + block.html_address() + '">' ) - sys.stdout.write( block.name ) - sys.stdout.write( '</a><br>' + '\n' ) - - if line * num_columns >= total: - print "</td><td>" - line = 0 - else: - line = line + 1 - else: - sys.stderr.write( "identifier '" + ident + - "' has no definition" + '\n' ) - - print "</tr></table></center>" - print html_footer - - close_output( output ) - - - -# Filter a given list of DocBlocks. Returns a new list of DocBlock objects -# that only contains element whose "type" (i.e. first marker) is in the -# "types" parameter. -# -class DocChapter: - - def __init__( self, block ): - self.sections_names = [] # ordered list of section names - self.sections = [] # ordered list of DocSection objects - # for this chapter - self.block = block - - # look for chapter title - content = block.find_content( "title" ) - if content: - self.title = content.get_title() - else: - self.title = "UNKNOWN CHAPTER TITLE" - - # look for section list - content = block.find_content( "sections" ) - if not content: - block.print_error( "chapter has no <sections> content" ) - - # compute list of section names - slist = [] - for item in content.items: - for element in item[1]: - try: - words = element.get_words() - l = len( slist ) - slist[l : l] = words - except: - block.print_warning( - "invalid content in <sections> marker" ) - - self.section_names = slist - - -class DocDocument: - - def __init__( self ): - self.section_list = DocSectionList() # section list object - self.chapters = [] # list of chapters - self.lost_sections = [] # list of sections with - # no chapter - - def append_block( self, block ): - if block.name: - content = block.find_content( "chapter" ) - if content: - # a chapter definition -- add it to our list - # - chapter = DocChapter( block ) - self.chapters.append( chapter ) - else: - self.section_list.append_block( block ) - - - def prepare_chapters( self ): - # check section names - # - for chapter in self.chapters: - slist = [] - for name in chapter.section_names: - section = self.section_list.sections.get( name ) - if not section: - chapter.block.print_warning( - "invalid reference to unknown section '" + name + "'" ) - else: - section.chapter = chapter - slist.append( section ) - - chapter.sections = slist - - for section in self.section_list.list: - if not section.chapter: - section.block.print_warning( - "section '" + section.name + "' is not in any chapter" ) - self.lost_sections.append( section ) - - - def prepare_files( self, file_prefix = None ): - self.section_list.prepare_files( file_prefix ) - self.prepare_chapters() - - - def dump_toc_html( self ): - # dump an html table of contents - # - output = open_output( self.section_list.toc_filename ) - - print html_header - - print "<center><h1>Table of Contents</h1></center>" - - for chapter in self.chapters: - print chapter_header + chapter.title + chapter_inter - - print "<table cellpadding=5>" - for section in chapter.sections: - if section.abstract: - print "<tr valign=top><td>" - sys.stdout.write( '<a href="' + section.filename + '">' ) - sys.stdout.write( section.title ) - sys.stdout.write( "</a></td><td>" + '\n' ) - section.abstract.dump_html( self.section_list.identifiers ) - print "</td></tr>" - - print "</table>" - - print chapter_footer - - # list lost sections - # - if self.lost_sections: - print chapter_header + "OTHER SECTIONS:" + chapter_inter - - print "<table cellpadding=5>" - for section in self.lost_sections: - if section.abstract: - print "<tr valign=top><td>" - sys.stdout.write( '<a href="' + section.filename + '">' ) - sys.stdout.write( section.title ) - sys.stdout.write( "</a></td><td>" + '\n' ) - section.abstract.dump_html( self.section_list.identifiers ) - print "</td></tr>" - - print "</table>" - - print chapter_footer - - # index - # - print chapter_header + '<a href="' + self.section_list.index_filename + '">Index</a>' + chapter_footer - - print html_footer - - close_output( output ) - - - def dump_index_html( self ): - self.section_list.dump_html_index() - - - def dump_sections_html( self ): - self.section_list.dump_html_sections() - - -def filter_blocks_by_type( block_list, types ): - new_list = [] - for block in block_list: - if block.items: - element = block.items[0] - marker = element[0] - if marker in types: - new_list.append( block ) - - return new_list - - -def filter_section_blocks( block ): - return block.section != None - - -# Perform a lexicographical comparison of two DocBlock objects. Returns -1, -# 0 or 1. -# -def block_lexicographical_compare( b1, b2 ): - if not b1.name: - return -1 - if not b2.name: - return 1 - - id1 = string.lower( b1.name ) - id2 = string.lower( b2.name ) - - if id1 < id2: - return -1 - elif id1 == id2: - return 0 - else: - return 1 - - -# Dump a list block as a single HTML page. -# -def dump_html_1( block_list ): - print html_header - - for block in block_list: - block.dump_html() - - print html_footer - - -def file_exists( pathname ): - result = 1 - try: - file = open( pathname, "r" ) - file.close() - except: - result = None - - return result - - -def add_new_block( list, filename, lineno, block_lines, source_lines ): - """add a new block to the list""" - block = DocBlock( block_lines, source_lines ) - block.filename = filename - block.lineno = lineno - list.append( block ) - - -def make_block_list( args = None ): - """parse a file and extract comments blocks from it""" - - file_list = [] - # sys.stderr.write( repr( sys.argv[1 :] ) + '\n' ) - - if not args: - args = sys.argv[1 :] - - for pathname in args: - if string.find( pathname, '*' ) >= 0: - newpath = glob.glob( pathname ) - newpath.sort() # sort files -- this is important because - # of the order of files - else: - newpath = [pathname] - - last = len( file_list ) - file_list[last : last] = newpath - - if len( file_list ) == 0: - file_list = None - else: - # now filter the file list to remove non-existing ones - file_list = filter( file_exists, file_list ) - - list = [] - block = [] - format = 0 - lineno = 0 - - # We use "format" to store the state of our parser: - # - # 0 - wait for beginning of comment - # 1 - parse comment format 1 - # 2 - parse comment format 2 - # - # 4 - wait for beginning of source (or comment?) - # 5 - process source - # - comment = [] - source = [] - state = 0 - - fileinput.close() - for line in fileinput.input( file_list ): - l = len( line ) - if l > 0 and line[l - 1] == '\012': - line = line[0 : l-1] - - # stripped version of the line - # - line2 = string.strip( line ) - l = len( line2 ) - - # if this line begins with a comment and we are processing some - # source, exit to state 0 - # - # unless we encounter something like: - # - # /*@..... - # /*#..... - # - # /* @..... - # /* #..... - # - if format >= 4 and l > 2 and line2[0 : 2] == '/*': - if l < 4 or ( line2[2] != '@' and line2[2 : 4] != ' @' and - line2[2] != '#' and line2[2 : 4] != ' #'): - add_new_block( list, fileinput.filename(), - lineno, block, source ) - format = 0 - - if format == 0: #### wait for beginning of comment #### - if l > 3 and line2[0 : 3] == '/**': - i = 3 - while i < l and line2[i] == '*': - i = i + 1 - - if i == l: - # this is '/**' followed by any number of '*', the - # beginning of a Format 1 block - # - block = [] - source = [] - format = 1 - lineno = fileinput.filelineno() - - elif i == l - 1 and line2[i] == '/': - # this is '/**' followed by any number of '*', followed - # by a '/', i.e. the beginning of a Format 2 or 3 block - # - block = [] - source = [] - format = 2 - lineno = fileinput.filelineno() - - ############################################################## - # - # FORMAT 1 - # - elif format == 1: - - # If the line doesn't begin with a "*", something went wrong, - # and we must exit, and forget the current block. - # - if l == 0 or line2[0] != '*': - block = [] - format = 0 - - # Otherwise, we test for an end of block, which is an arbitrary - # number of '*', followed by '/'. - # - else: - i = 1 - while i < l and line2[i] == '*': - i = i + 1 - - # test for the end of the block - # - if i < l and line2[i] == '/': - if block != []: - format = 4 - else: - format = 0 - else: - # otherwise simply append line to current block - # - block.append( line2[i :] ) - - continue - - ############################################################## - # - # FORMAT 2 - # - elif format == 2: - - # If the line doesn't begin with '/*' and end with '*/', this is - # the end of the format 2 format. - # - if l < 4 or line2[: 2] != '/*' or line2[-2 :] != '*/': - if block != []: - format = 4 - else: - format = 0 - else: - # remove the start and end comment delimiters, then - # right-strip the line - # - line2 = string.rstrip( line2[2 : -2] ) - - # check for end of a format2 block, i.e. a run of '*' - # - if string.count( line2, '*' ) == l - 4: - if block != []: - format = 4 - else: - format = 0 - else: - # otherwise, add the line to the current block - # - block.append( line2 ) - - continue - - if format >= 4: #### source processing #### - if l > 0: - format = 5 - - if format == 5: - source.append( line ) - - if format >= 4: - add_new_block( list, fileinput.filename(), lineno, block, source ) - - return list - - - -# This function is only used for debugging -# -def dump_block_list( list ): - """dump a comment block list""" - for block in list: - print "----------------------------------------" - for line in block[0]: - print line - for line in block[1]: - print line - - print "---------the end-----------------------" - - -def usage(): - print "\nDocMaker 0.1 Usage information\n" - print " docmaker [options] file1 [ file2 ... ]\n" - print "using the following options:\n" - print " -h : print this page" - print " -t : set project title, as in '-t \"My Project\"'" - print " -o : set output directory, as in '-o mydir'" - print " -p : set documentation prefix, as in '-p ft2'" - print "" - print " --title : same as -t, as in '--title=\"My Project\"'" - print " --output : same as -o, as in '--output=mydir'" - print " --prefix : same as -p, as in '--prefix=ft2'" - - -def main( argv ): - """main program loop""" - - global output_dir, project_title, project_prefix - global html_header, html_header1, html_header2, html_header3 - - try: - opts, args = getopt.getopt( sys.argv[1:], - "ht:o:p:", - [ "help", "title=", "output=", "prefix=" ] ) - - except getopt.GetoptError: - usage() - sys.exit( 2 ) - - if args == []: - usage() - sys.exit( 1 ) - - # process options - # - project_title = "Project" - project_prefix = None - output_dir = None - - for opt in opts: - if opt[0] in ( "-h", "--help" ): - usage() - sys.exit( 0 ) - - if opt[0] in ( "-t", "--title" ): - project_title = opt[1] - - if opt[0] in ( "-o", "--output" ): - output_dir = opt[1] - - if opt[0] in ( "-p", "--prefix" ): - project_prefix = opt[1] - - html_header = html_header_1 + project_title + html_header_2 + project_title + html_header_3 - check_output( ) - compute_time_html() - - # we begin by simply building a list of DocBlock elements - # - list = make_block_list( args ) - - # now, sort the blocks into sections - # - document = DocDocument() - for block in list: - document.append_block( block ) - - document.prepare_files( project_prefix ) - - document.dump_toc_html() - document.dump_sections_html() - document.dump_index_html() - -# if called from the command line -# -if __name__ == '__main__': - main( sys.argv ) - - -# eof diff --git a/src/libs/freetype2/tools/docmaker/content.py b/src/libs/freetype2/tools/docmaker/content.py index ba77a114d4..ebfeb8bf48 100644 --- a/src/libs/freetype2/tools/docmaker/content.py +++ b/src/libs/freetype2/tools/docmaker/content.py @@ -1,547 +1,585 @@ -# -# this file contains routines used to parse the content of documentation -# comment block and build a more structured objects out of them -# - -from sources import * -from utils import * -import string, re - - -# this regular expresion is used to detect code sequences. these -# are simply code fragments embedded in '{' and '}' like in: -# -# { -# x = y + z; -# if ( zookoo == 2 ) -# { -# foobar(); -# } -# } -# -# note that identation of the starting and ending accolades must be -# exactly the same. the code sequence can contain accolades at greater -# indentation -# -re_code_start = re.compile( r"(\s*){\s*$" ) -re_code_end = re.compile( r"(\s*)}\s*$" ) - - -# this regular expression is used to isolate identifiers from -# other text -# -re_identifier = re.compile( r'(\w*)' ) - - -############################################################################# -# -# The DocCode class is used to store source code lines. -# -# 'self.lines' contains a set of source code lines that will be dumped as -# HTML in a <PRE> tag. -# -# The object is filled line by line by the parser; it strips the leading -# "margin" space from each input line before storing it in 'self.lines'. -# -class DocCode: - - def __init__( self, margin, lines ): - self.lines = [] - self.words = None - - # remove margin spaces - for l in lines: - if string.strip( l[:margin] ) == "": - l = l[margin:] - self.lines.append( l ) - - def dump( self, prefix = "", width=60 ): - for l in self.lines: - print prefix + l - - -############################################################################# -# -# The DocPara class is used to store "normal" text paragraph. -# -# 'self.words' contains the list of words that make up the paragraph -# -class DocPara: - - def __init__( self, lines ): - self.lines = None - self.words = [] - for l in lines: - l = string.strip(l) - self.words.extend( string.split( l ) ) - - def dump( self, prefix = "", width = 60 ): - cur = "" # current line - col = 0 # current width - - for word in self.words: - ln = len(word) - if col > 0: - ln = ln+1 - - if col + ln > width: - print prefix + cur - cur = word - col = len(word) - else: - if col > 0: - cur = cur + " " - cur = cur + word - col = col + ln - - if col > 0: - print prefix + cur - - - -############################################################################# -# -# The DocField class is used to store a list containing either DocPara or -# DocCode objects. Each DocField also has an optional "name" which is used -# when the object corresponds to a field of value definition -# -class DocField: - - def __init__( self, name, lines ): - - self.name = name # can be None for normal paragraphs/sources - self.items = [] # list of items - - mode_none = 0 # start parsing mode - mode_code = 1 # parsing code sequences - mode_para = 3 # parsing normal paragraph - - margin = -1 # current code sequence indentation - cur_lines = [] - - # now analyze the markup lines to see if they contain paragraphs, - # code sequences or fields definitions - # - start = 0 - mode = mode_none - for l in lines: - - # are we parsing a code sequence ? - if mode == mode_code: - - m = re_code_end.match( l ) - if m and len(m.group(1)) <= margin: - # that's it, we finised the code sequence - code = DocCode( 0, cur_lines ) - self.items.append( code ) - margin = -1 - cur_lines = [] - mode = mode_none - else: - # nope, continue the code sequence - cur_lines.append( l[margin:] ) - else: - # start of code sequence ? - m = re_code_start.match( l ) - if m: - # save current lines - if cur_lines: - para = DocPara( cur_lines ) - self.items.append( para ) - cur_lines = [] - - # switch to code extraction mode - margin = len(m.group(1)) - mode = mode_code - - else: - if not string.split( l ) and cur_lines: - # if the line is empty, we end the current paragraph, - # if any - para = DocPara( cur_lines ) - self.items.append( para ) - cur_lines = [] - else: - # otherwise, simply add the line to the current - # paragraph - cur_lines.append( l ) - - if mode == mode_code: - # unexpected end of code sequence - code = DocCode( margin, cur_lines ) - self.items.append( code ) - - elif cur_lines: - para = DocPara( cur_lines ) - self.items.append( para ) - - def dump( self, prefix = "" ): - if self.field: - print prefix + self.field + " ::" - prefix = prefix + "----" - - first = 1 - for p in self.items: - if not first: - print "" - p.dump( prefix ) - first = 0 - - -# this regular expression is used to detect field definitions -# -re_field = re.compile( r"\s*(\w*)\s*::" ) - - - -class DocMarkup: - - def __init__( self, tag, lines ): - self.tag = string.lower(tag) - self.fields = [] - - cur_lines = [] - field = None - mode = 0 - - for l in lines: - m = re_field.match( l ) - if m: - # we detected the start of a new field definition - - # first, save the current one - if cur_lines: - f = DocField( field, cur_lines ) - self.fields.append( f ) - cur_lines = [] - field = None - - field = m.group(1) # record field name - ln = len(m.group(0)) - l = " "*ln + l[ln:] - cur_lines = [ l ] - else: - cur_lines.append( l ) - - if field or cur_lines: - f = DocField( field, cur_lines ) - self.fields.append( f ) - - def get_name( self ): - try: - return self.fields[0].items[0].words[0] - - except: - return None - - def dump( self, margin ): - print " "*margin + "<" + self.tag + ">" - for f in self.fields: - f.dump( " " ) - print " "*margin + "</" + self.tag + ">" - - - - -class DocChapter: - - def __init__( self, block ): - self.block = block - self.sections = [] - if block: - self.name = block.name - self.title = block.get_markup_words( "title" ) - self.order = block.get_markup_words( "sections" ) - else: - self.name = "Other" - self.title = string.split( "Miscellaneous" ) - self.order = [] - - - -class DocSection: - - def __init__( self, name = "Other" ): - self.name = name - self.blocks = {} - self.block_names = [] # ordered block names in section - self.defs = [] - self.abstract = "" - self.description = "" - self.order = [] - self.title = "ERROR" - self.chapter = None - - def add_def( self, block ): - self.defs.append( block ) - - def add_block( self, block ): - self.block_names.append( block.name ) - self.blocks[ block.name ] = block - - def process( self ): - # lookup one block that contains a valid section description - for block in self.defs: - title = block.get_markup_text( "Title" ) - if title: - self.title = title - self.abstract = block.get_markup_words( "abstract" ) - self.description = block.get_markup_items( "description" ) - self.order = block.get_markup_words( "order" ) - return - - def reorder( self ): - - self.block_names = sort_order_list( self.block_names, self.order ) - - -class ContentProcessor: - - def __init__( self ): - """initialize a block content processor""" - self.reset() - - self.sections = {} # dictionary of documentation sections - self.section = None # current documentation section - - self.chapters = [] # list of chapters - - def set_section( self, section_name ): - """set current section during parsing""" - if not self.sections.has_key( section_name ): - section = DocSection( section_name ) - self.sections[ section_name ] = section - self.section = section - else: - self.section = self.sections[ section_name ] - - def add_chapter( self, block ): - chapter = DocChapter( block ) - self.chapters.append( chapter ) - - - def reset( self ): - """reset the content processor for a new block""" - self.markups = [] - self.markup = None - self.markup_lines = [] - - def add_markup( self ): - """add a new markup section""" - if self.markup and self.markup_lines: - - # get rid of last line of markup if it's empty - marks = self.markup_lines - if len(marks) > 0 and not string.strip(marks[-1]): - self.markup_lines = marks[:-1] - - m = DocMarkup( self.markup, self.markup_lines ) - - self.markups.append( m ) - - self.markup = None - self.markup_lines = [] - - - def process_content( self, content ): - """process a block content and return a list of DocMarkup objects - corresponding to it""" - markup = None - markup_lines = [] - first = 1 - - for line in content: - found = None - for t in re_markup_tags: - m = t.match( line ) - if m: - found = string.lower(m.group(1)) - prefix = len(m.group(0)) - line = " "*prefix + line[prefix:] # remove markup from line - break - - # is it the start of a new markup section ? - if found: - first = 0 - self.add_markup() # add current markup content - self.markup = found - if len(string.strip( line )) > 0: - self.markup_lines.append( line ) - elif first == 0: - self.markup_lines.append( line ) - - self.add_markup() - - return self.markups - - - def parse_sources( self, source_processor ): - blocks = source_processor.blocks - count = len(blocks) - for n in range(count): - - source = blocks[n] - if source.content: - # this is a documentation comment, we need to catch - # all following normal blocks in the "follow" list - # - follow = [] - m = n+1 - while m < count and not blocks[m].content: - follow.append( blocks[m] ) - m = m+1 - - doc_block = DocBlock( source, follow, self ) - - - def finish( self ): - - # process all sections to extract their abstract, description - # and ordered list of items - # - for sec in self.sections.values(): - sec.process() - - # process chapters to check that all sections are correctly - # listed there - for chap in self.chapters: - for sec in chap.order: - if self.sections.has_key(sec): - section = self.sections[ sec ] - section.chapter = chap - section.reorder() - chap.sections.append( section ) - else: - sys.stderr.write( "WARNING: chapter '" + - chap.name + "' in " + chap.block.location() + \ - " lists unknown section '" + sec + "'\n" ) - - # check that all sections are in a chapter - # - others = [] - for sec in self.sections.values(): - if not sec.chapter: - others.append(sec) - - # create a new special chapter for all remaining sections - # when necessary - # - if others: - chap = DocChapter( None ) - chap.sections = others - self.chapters.append( chap ) - - - -class DocBlock: - - def __init__( self, source, follow, processor ): - - processor.reset() - - self.source = source - self.code = [] - self.type = "ERRTYPE" - self.name = "ERRNAME" - self.section = processor.section - self.markups = processor.process_content( source.content ) - - # compute block type from first markup tag - try: - self.type = self.markups[0].tag - except: - pass - - - # compute block name from first markup paragraph - try: - markup = self.markups[0] - para = markup.fields[0].items[0] - name = para.words[0] - m = re_identifier.match( name ) - if m: - name = m.group(1) - self.name = name - except: - pass - - # detect new section starts - if self.type == "section": - processor.set_section( self.name ) - processor.section.add_def( self ) - - # detect new chapter - elif self.type == "chapter": - processor.add_chapter( self ) - - else: - processor.section.add_block( self ) - - # now, compute the source lines relevant to this documentation - # block. We keep normal comments in for obvious reasons (??) - source = [] - for b in follow: - if b.format: - break - for l in b.lines: - # we use "/* */" as a separator - if re_source_sep.match( l ): - break - source.append( l ) - - # now strip the leading and trailing empty lines from the sources - start = 0 - end = len( source )-1 - - while start < end and not string.strip( source[start] ): - start = start + 1 - - while start < end and not string.strip( source[end] ): - end = end - 1 - - source = source[start:end+1] - - self.code = source - - - def location( self ): - return self.source.location() - - - - def get_markup( self, tag_name ): - """return the DocMarkup corresponding to a given tag in a block""" - for m in self.markups: - if m.tag == string.lower(tag_name): - return m - return None - - - def get_markup_name( self, tag_name ): - """return the name of a given primary markup in a block""" - try: - m = self.get_markup( tag_name ) - return m.get_name() - except: - return None - - - def get_markup_words( self, tag_name ): - try: - m = self.get_markup( tag_name ) - return m.fields[0].items[0].words - except: - return [] - - - def get_markup_text( self, tag_name ): - result = self.get_markup_words( tag_name ) - return string.join( result ) - - - def get_markup_items( self, tag_name ): - try: - m = self.get_markup( tag_name ) - return m.fields[0].items - except: - return None \ No newline at end of file +# +# this file contains routines used to parse the content of documentation +# comment block and build a more structured objects out of them +# + +from sources import * +from utils import * +import string, re + + +# this regular expresion is used to detect code sequences. these +# are simply code fragments embedded in '{' and '}' like in: +# +# { +# x = y + z; +# if ( zookoo == 2 ) +# { +# foobar(); +# } +# } +# +# note that identation of the starting and ending accolades must be +# exactly the same. the code sequence can contain accolades at greater +# indentation +# +re_code_start = re.compile( r"(\s*){\s*$" ) +re_code_end = re.compile( r"(\s*)}\s*$" ) + + +# this regular expression is used to isolate identifiers from +# other text +# +re_identifier = re.compile( r'(\w*)' ) + + +############################################################################# +# +# The DocCode class is used to store source code lines. +# +# 'self.lines' contains a set of source code lines that will be dumped as +# HTML in a <PRE> tag. +# +# The object is filled line by line by the parser; it strips the leading +# "margin" space from each input line before storing it in 'self.lines'. +# +class DocCode: + + def __init__( self, margin, lines ): + self.lines = [] + self.words = None + + # remove margin spaces + for l in lines: + if string.strip( l[:margin] ) == "": + l = l[margin:] + self.lines.append( l ) + + def dump( self, prefix = "", width=60 ): + lines = self.dump_lines( 0, width ) + for l in lines: + print prefix + l + + def dump_lines( self, margin=0, width=60 ): + result = [] + for l in self.lines: + result.append( " "*margin + l ) + return result + + + +############################################################################# +# +# The DocPara class is used to store "normal" text paragraph. +# +# 'self.words' contains the list of words that make up the paragraph +# +class DocPara: + + def __init__( self, lines ): + self.lines = None + self.words = [] + for l in lines: + l = string.strip(l) + self.words.extend( string.split( l ) ) + + def dump( self, prefix = "", width = 60 ): + lines = self.dump_lines( 0, width ) + for l in lines: + print prefix + l + + def dump_lines( self, margin=0, width = 60 ): + cur = "" # current line + col = 0 # current width + result = [] + + for word in self.words: + ln = len(word) + if col > 0: + ln = ln+1 + + if col + ln > width: + result.append( " "*margin + cur ) + cur = word + col = len(word) + else: + if col > 0: + cur = cur + " " + cur = cur + word + col = col + ln + + if col > 0: + result.append( " "*margin + cur ) + + return result + + + + +############################################################################# +# +# The DocField class is used to store a list containing either DocPara or +# DocCode objects. Each DocField also has an optional "name" which is used +# when the object corresponds to a field of value definition +# +class DocField: + + def __init__( self, name, lines ): + + self.name = name # can be None for normal paragraphs/sources + self.items = [] # list of items + + mode_none = 0 # start parsing mode + mode_code = 1 # parsing code sequences + mode_para = 3 # parsing normal paragraph + + margin = -1 # current code sequence indentation + cur_lines = [] + + # now analyze the markup lines to see if they contain paragraphs, + # code sequences or fields definitions + # + start = 0 + mode = mode_none + for l in lines: + + # are we parsing a code sequence ? + if mode == mode_code: + + m = re_code_end.match( l ) + if m and len(m.group(1)) <= margin: + # that's it, we finised the code sequence + code = DocCode( 0, cur_lines ) + self.items.append( code ) + margin = -1 + cur_lines = [] + mode = mode_none + else: + # nope, continue the code sequence + cur_lines.append( l[margin:] ) + else: + # start of code sequence ? + m = re_code_start.match( l ) + if m: + # save current lines + if cur_lines: + para = DocPara( cur_lines ) + self.items.append( para ) + cur_lines = [] + + # switch to code extraction mode + margin = len(m.group(1)) + mode = mode_code + + else: + if not string.split( l ) and cur_lines: + # if the line is empty, we end the current paragraph, + # if any + para = DocPara( cur_lines ) + self.items.append( para ) + cur_lines = [] + else: + # otherwise, simply add the line to the current + # paragraph + cur_lines.append( l ) + + if mode == mode_code: + # unexpected end of code sequence + code = DocCode( margin, cur_lines ) + self.items.append( code ) + + elif cur_lines: + para = DocPara( cur_lines ) + self.items.append( para ) + + def dump( self, prefix = "" ): + if self.field: + print prefix + self.field + " ::" + prefix = prefix + "----" + + first = 1 + for p in self.items: + if not first: + print "" + p.dump( prefix ) + first = 0 + + def dump_lines( self, margin=0, width=60 ): + result = [] + nl = None + for p in self.items: + if nl: + result.append( "" ) + + result.extend( p.dump_lines( margin, width ) ) + nl = 1 + + return result + +# this regular expression is used to detect field definitions +# +re_field = re.compile( r"\s*(\w*)\s*::" ) + + + +class DocMarkup: + + def __init__( self, tag, lines ): + self.tag = string.lower(tag) + self.fields = [] + + cur_lines = [] + field = None + mode = 0 + + for l in lines: + m = re_field.match( l ) + if m: + # we detected the start of a new field definition + + # first, save the current one + if cur_lines: + f = DocField( field, cur_lines ) + self.fields.append( f ) + cur_lines = [] + field = None + + field = m.group(1) # record field name + ln = len(m.group(0)) + l = " "*ln + l[ln:] + cur_lines = [ l ] + else: + cur_lines.append( l ) + + if field or cur_lines: + f = DocField( field, cur_lines ) + self.fields.append( f ) + + def get_name( self ): + try: + return self.fields[0].items[0].words[0] + + except: + return None + + def get_start( self ): + try: + result = "" + for word in self.fields[0].items[0].words: + result = result + " " + word + return result[1:] + + except: + return "ERROR" + + def dump( self, margin ): + print " "*margin + "<" + self.tag + ">" + for f in self.fields: + f.dump( " " ) + print " "*margin + "</" + self.tag + ">" + + + + +class DocChapter: + + def __init__( self, block ): + self.block = block + self.sections = [] + if block: + self.name = block.name + self.title = block.get_markup_words( "title" ) + self.order = block.get_markup_words( "sections" ) + else: + self.name = "Other" + self.title = string.split( "Miscellaneous" ) + self.order = [] + + + +class DocSection: + + def __init__( self, name = "Other" ): + self.name = name + self.blocks = {} + self.block_names = [] # ordered block names in section + self.defs = [] + self.abstract = "" + self.description = "" + self.order = [] + self.title = "ERROR" + self.chapter = None + + def add_def( self, block ): + self.defs.append( block ) + + def add_block( self, block ): + self.block_names.append( block.name ) + self.blocks[ block.name ] = block + + def process( self ): + # lookup one block that contains a valid section description + for block in self.defs: + title = block.get_markup_text( "Title" ) + if title: + self.title = title + self.abstract = block.get_markup_words( "abstract" ) + self.description = block.get_markup_items( "description" ) + self.order = block.get_markup_words( "order" ) + return + + def reorder( self ): + + self.block_names = sort_order_list( self.block_names, self.order ) + + +class ContentProcessor: + + def __init__( self ): + """initialize a block content processor""" + self.reset() + + self.sections = {} # dictionary of documentation sections + self.section = None # current documentation section + + self.chapters = [] # list of chapters + + def set_section( self, section_name ): + """set current section during parsing""" + if not self.sections.has_key( section_name ): + section = DocSection( section_name ) + self.sections[ section_name ] = section + self.section = section + else: + self.section = self.sections[ section_name ] + + def add_chapter( self, block ): + chapter = DocChapter( block ) + self.chapters.append( chapter ) + + + def reset( self ): + """reset the content processor for a new block""" + self.markups = [] + self.markup = None + self.markup_lines = [] + + def add_markup( self ): + """add a new markup section""" + if self.markup and self.markup_lines: + + # get rid of last line of markup if it's empty + marks = self.markup_lines + if len(marks) > 0 and not string.strip(marks[-1]): + self.markup_lines = marks[:-1] + + m = DocMarkup( self.markup, self.markup_lines ) + + self.markups.append( m ) + + self.markup = None + self.markup_lines = [] + + + def process_content( self, content ): + """process a block content and return a list of DocMarkup objects + corresponding to it""" + markup = None + markup_lines = [] + first = 1 + + for line in content: + found = None + for t in re_markup_tags: + m = t.match( line ) + if m: + found = string.lower(m.group(1)) + prefix = len(m.group(0)) + line = " "*prefix + line[prefix:] # remove markup from line + break + + # is it the start of a new markup section ? + if found: + first = 0 + self.add_markup() # add current markup content + self.markup = found + if len(string.strip( line )) > 0: + self.markup_lines.append( line ) + elif first == 0: + self.markup_lines.append( line ) + + self.add_markup() + + return self.markups + + + def parse_sources( self, source_processor ): + blocks = source_processor.blocks + count = len(blocks) + for n in range(count): + + source = blocks[n] + if source.content: + # this is a documentation comment, we need to catch + # all following normal blocks in the "follow" list + # + follow = [] + m = n+1 + while m < count and not blocks[m].content: + follow.append( blocks[m] ) + m = m+1 + + doc_block = DocBlock( source, follow, self ) + + + def finish( self ): + + # process all sections to extract their abstract, description + # and ordered list of items + # + for sec in self.sections.values(): + sec.process() + + # process chapters to check that all sections are correctly + # listed there + for chap in self.chapters: + for sec in chap.order: + if self.sections.has_key(sec): + section = self.sections[ sec ] + section.chapter = chap + section.reorder() + chap.sections.append( section ) + else: + sys.stderr.write( "WARNING: chapter '" + + chap.name + "' in " + chap.block.location() + \ + " lists unknown section '" + sec + "'\n" ) + + # check that all sections are in a chapter + # + others = [] + for sec in self.sections.values(): + if not sec.chapter: + others.append(sec) + + # create a new special chapter for all remaining sections + # when necessary + # + if others: + chap = DocChapter( None ) + chap.sections = others + self.chapters.append( chap ) + + + +class DocBlock: + + def __init__( self, source, follow, processor ): + + processor.reset() + + self.source = source + self.code = [] + self.type = "ERRTYPE" + self.name = "ERRNAME" + self.section = processor.section + self.markups = processor.process_content( source.content ) + + # compute block type from first markup tag + try: + self.type = self.markups[0].tag + except: + pass + + + # compute block name from first markup paragraph + try: + markup = self.markups[0] + para = markup.fields[0].items[0] + name = para.words[0] + m = re_identifier.match( name ) + if m: + name = m.group(1) + self.name = name + except: + pass + + # detect new section starts + if self.type == "section": + processor.set_section( self.name ) + processor.section.add_def( self ) + + # detect new chapter + elif self.type == "chapter": + processor.add_chapter( self ) + + else: + processor.section.add_block( self ) + + # now, compute the source lines relevant to this documentation + # block. We keep normal comments in for obvious reasons (??) + source = [] + for b in follow: + if b.format: + break + for l in b.lines: + # we use "/* */" as a separator + if re_source_sep.match( l ): + break + source.append( l ) + + # now strip the leading and trailing empty lines from the sources + start = 0 + end = len( source )-1 + + while start < end and not string.strip( source[start] ): + start = start + 1 + + while start < end and not string.strip( source[end] ): + end = end - 1 + + source = source[start:end+1] + + self.code = source + + + def location( self ): + return self.source.location() + + + + def get_markup( self, tag_name ): + """return the DocMarkup corresponding to a given tag in a block""" + for m in self.markups: + if m.tag == string.lower(tag_name): + return m + return None + + + def get_markup_name( self, tag_name ): + """return the name of a given primary markup in a block""" + try: + m = self.get_markup( tag_name ) + return m.get_name() + except: + return None + + + def get_markup_words( self, tag_name ): + try: + m = self.get_markup( tag_name ) + return m.fields[0].items[0].words + except: + return [] + + + def get_markup_text( self, tag_name ): + result = self.get_markup_words( tag_name ) + return string.join( result ) + + + def get_markup_items( self, tag_name ): + try: + m = self.get_markup( tag_name ) + return m.fields[0].items + except: + return None diff --git a/src/libs/freetype2/tools/docmaker/docbeauty.py b/src/libs/freetype2/tools/docmaker/docbeauty.py new file mode 100644 index 0000000000..94b266b6d1 --- /dev/null +++ b/src/libs/freetype2/tools/docmaker/docbeauty.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python +# +# DocBeauty (c) 2003, 2004 David Turner <david@freetype.org> +# +# This program is used to beautify the documentation comments used +# in the FreeType 2 public headers. +# + +from sources import * +from content import * +from utils import * + +import utils + +import sys, os, time, string, getopt + +content_processor = ContentProcessor() + + +def beautify_block( block ): + if block.content: + content_processor.reset() + + markups = content_processor.process_content( block.content ) + text = [] + first = 1 + + for markup in markups: + text.extend( markup.beautify( first ) ) + first = 0 + + # now beautify the documentation "borders" themselves + lines = [ " /*************************************************************************" ] + for l in text: + lines.append( " *" + l ) + lines.append( " */" ) + + block.lines = lines + + +def usage(): + print "\nDocBeauty 0.1 Usage information\n" + print " docbeauty [options] file1 [ file2 ... ]\n" + print "using the following options:\n" + print " -h : print this page" + print " -b : backup original files with the 'orig' extension" + print "" + print " --backup : same as -b" + + +def main( argv ): + """main program loop""" + + global output_dir + + try: + opts, args = getopt.getopt( sys.argv[1:], + "hb", + [ "help", "backup" ] ) + + except getopt.GetoptError: + usage() + sys.exit( 2 ) + + if args == []: + usage() + sys.exit( 1 ) + + # process options + # + output_dir = None + do_backup = None + + for opt in opts: + if opt[0] in ( "-h", "--help" ): + usage() + sys.exit( 0 ) + + if opt[0] in ( "-b", "--backup" ): + do_backup = 1 + + # create context and processor + source_processor = SourceProcessor() + + # retrieve the list of files to process + file_list = make_file_list( args ) + for filename in file_list: + source_processor.parse_file( filename ) + for block in source_processor.blocks: + beautify_block( block ) + new_name = filename + ".new" + ok = None + try: + file = open( new_name, "wt" ) + for block in source_processor.blocks: + for line in block.lines: + file.write( line ) + file.write( "\n" ) + file.close() + except: + ok = 0 + +# if called from the command line +# +if __name__ == '__main__': + main( sys.argv ) + + +# eof diff --git a/src/libs/freetype2/tools/docmaker/docmaker.py b/src/libs/freetype2/tools/docmaker/docmaker.py index bf2fa8b0d2..9da4bbf8ea 100644 --- a/src/libs/freetype2/tools/docmaker/docmaker.py +++ b/src/libs/freetype2/tools/docmaker/docmaker.py @@ -1,149 +1,107 @@ -#!/usr/bin/env python -# -# DocMaker 0.2 (c) 2002 David Turner <david@freetype.org> -# -# This program is a re-write of the original DocMaker took used -# to generate the API Reference of the FreeType font engine -# by converting in-source comments into structured HTML -# -# This new version is capable of outputting XML data, as well -# as accepts more liberal formatting options -# -# It also uses regular expression matching and substitution -# to speed things significantly -# - -from sources import * -from content import * -from utils import * -from formatter import * -from tohtml import * - -import utils - -import sys, os, time, string, glob, getopt - - -def file_exists( pathname ): - """checks that a given file exists""" - result = 1 - try: - file = open( pathname, "r" ) - file.close() - except: - result = None - sys.stderr.write( pathname + " couldn't be accessed\n" ) - - return result - - -def make_file_list( args = None ): - """builds a list of input files from command-line arguments""" - - file_list = [] - # sys.stderr.write( repr( sys.argv[1 :] ) + '\n' ) - - if not args: - args = sys.argv[1 :] - - for pathname in args: - if string.find( pathname, '*' ) >= 0: - newpath = glob.glob( pathname ) - newpath.sort() # sort files -- this is important because - # of the order of files - else: - newpath = [pathname] - - file_list.extend( newpath ) - - if len( file_list ) == 0: - file_list = None - else: - # now filter the file list to remove non-existing ones - file_list = filter( file_exists, file_list ) - - return file_list - - - -def usage(): - print "\nDocMaker 0.2 Usage information\n" - print " docmaker [options] file1 [ file2 ... ]\n" - print "using the following options:\n" - print " -h : print this page" - print " -t : set project title, as in '-t \"My Project\"'" - print " -o : set output directory, as in '-o mydir'" - print " -p : set documentation prefix, as in '-p ft2'" - print "" - print " --title : same as -t, as in '--title=\"My Project\"'" - print " --output : same as -o, as in '--output=mydir'" - print " --prefix : same as -p, as in '--prefix=ft2'" - - -def main( argv ): - """main program loop""" - - global output_dir - - try: - opts, args = getopt.getopt( sys.argv[1:], - "ht:o:p:", - [ "help", "title=", "output=", "prefix=" ] ) - - except getopt.GetoptError: - usage() - sys.exit( 2 ) - - if args == []: - usage() - sys.exit( 1 ) - - # process options - # - project_title = "Project" - project_prefix = None - output_dir = None - - for opt in opts: - if opt[0] in ( "-h", "--help" ): - usage() - sys.exit( 0 ) - - if opt[0] in ( "-t", "--title" ): - project_title = opt[1] - - if opt[0] in ( "-o", "--output" ): - utils.output_dir = opt[1] - - if opt[0] in ( "-p", "--prefix" ): - project_prefix = opt[1] - - check_output( ) - - # create context and processor - source_processor = SourceProcessor() - content_processor = ContentProcessor() - - # retrieve the list of files to process - file_list = make_file_list( args ) - for filename in file_list: - source_processor.parse_file( filename ) - content_processor.parse_sources( source_processor ) - - # process sections - content_processor.finish() - - formatter = HtmlFormatter( content_processor, project_title, project_prefix ) - - formatter.toc_dump() - formatter.index_dump() - formatter.section_dump_all() - - -# if called from the command line -# -if __name__ == '__main__': - main( sys.argv ) - - -# eof +#!/usr/bin/env python +# +# DocMaker (c) 2002, 2004 David Turner <david@freetype.org> +# +# This program is a re-write of the original DocMaker took used +# to generate the API Reference of the FreeType font engine +# by converting in-source comments into structured HTML. +# +# This new version is capable of outputting XML data, as well +# as accepts more liberal formatting options. +# +# It also uses regular expression matching and substitution +# to speed things significantly. +# + +from sources import * +from content import * +from utils import * +from formatter import * +from tohtml import * + +import utils + +import sys, os, time, string, glob, getopt + + +def usage(): + print "\nDocMaker Usage information\n" + print " docmaker [options] file1 [ file2 ... ]\n" + print "using the following options:\n" + print " -h : print this page" + print " -t : set project title, as in '-t \"My Project\"'" + print " -o : set output directory, as in '-o mydir'" + print " -p : set documentation prefix, as in '-p ft2'" + print "" + print " --title : same as -t, as in '--title=\"My Project\"'" + print " --output : same as -o, as in '--output=mydir'" + print " --prefix : same as -p, as in '--prefix=ft2'" + + +def main( argv ): + """main program loop""" + + global output_dir + + try: + opts, args = getopt.getopt( sys.argv[1:], + "ht:o:p:", + [ "help", "title=", "output=", "prefix=" ] ) + + except getopt.GetoptError: + usage() + sys.exit( 2 ) + + if args == []: + usage() + sys.exit( 1 ) + + # process options + # + project_title = "Project" + project_prefix = None + output_dir = None + + for opt in opts: + if opt[0] in ( "-h", "--help" ): + usage() + sys.exit( 0 ) + + if opt[0] in ( "-t", "--title" ): + project_title = opt[1] + + if opt[0] in ( "-o", "--output" ): + utils.output_dir = opt[1] + + if opt[0] in ( "-p", "--prefix" ): + project_prefix = opt[1] + + check_output( ) + + # create context and processor + source_processor = SourceProcessor() + content_processor = ContentProcessor() + + # retrieve the list of files to process + file_list = make_file_list( args ) + for filename in file_list: + source_processor.parse_file( filename ) + content_processor.parse_sources( source_processor ) + + # process sections + content_processor.finish() + + formatter = HtmlFormatter( content_processor, project_title, project_prefix ) + + formatter.toc_dump() + formatter.index_dump() + formatter.section_dump_all() + + +# if called from the command line +# +if __name__ == '__main__': + main( sys.argv ) + + +# eof diff --git a/src/libs/freetype2/tools/docmaker/formatter.py b/src/libs/freetype2/tools/docmaker/formatter.py index 67d620b12a..63ecddc973 100644 --- a/src/libs/freetype2/tools/docmaker/formatter.py +++ b/src/libs/freetype2/tools/docmaker/formatter.py @@ -1,194 +1,203 @@ -from sources import * -from content import * -from utils import * - -class Formatter: - - def __init__( self, processor ): - - self.processor = processor - self.identifiers = {} - self.chapters = processor.chapters - self.sections = processor.sections.values() - self.block_index = [] - - # store all blocks in a dictionary - self.blocks = [] - for section in self.sections: - for block in section.blocks.values(): - self.add_identifier( block.name, block ) - - # add enumeration values to the index, since this is useful - for markup in block.markups: - if markup.tag == 'values': - for field in markup.fields: - self.add_identifier( field.name, block ) - - - self.block_index = self.identifiers.keys() - self.block_index.sort( index_sort ) - - - def add_identifier( self, name, block ): - if self.identifiers.has_key( name ): - # duplicate name !! - sys.stderr.write( \ - "WARNING: duplicate definition for '" + name + "' in " + \ - block.location() + ", previous definition in " + \ - self.identifiers[ name ].location() + "\n" ) - else: - self.identifiers[name] = block - - - # - # Formatting the table of contents - # - - def toc_enter( self ): - pass - - def toc_chapter_enter( self, chapter ): - pass - - def toc_section_enter( self, section ): - pass - - def toc_section_exit( self, section ): - pass - - def toc_chapter_exit( self, chapter ): - pass - - def toc_index( self, index_filename ): - pass - - def toc_exit( self ): - pass - - def toc_dump( self, toc_filename = None, index_filename = None ): - - output = None - if toc_filename: - output = open_output( toc_filename ) - - self.toc_enter() - - for chap in self.processor.chapters: - - self.toc_chapter_enter( chap ) - - for section in chap.sections: - self.toc_section_enter( section ) - self.toc_section_exit( section ) - - self.toc_chapter_exit ( chap ) - - self.toc_index( index_filename ) - - self.toc_exit() - - if output: - close_output( output ) - - # - # Formatting the index - # - - def index_enter( self ): - pass - - def index_name_enter( self, name ): - pass - - def index_name_exit( self, name ): - pass - - def index_exit( self ): - pass - - def index_dump( self, index_filename = None ): - - output = None - if index_filename: - output = open_output( index_filename ) - - self.index_enter() - - for name in self.block_index: - self.index_name_enter( name ) - self.index_name_exit ( name ) - - self.index_exit() - - if output: - close_output( output ) - - # - # Formatting a section - # - def section_enter( self, section ): - pass - - def block_enter( self, block ): - pass - - def markup_enter( self, markup, block = None ): - pass - - def field_enter( self, field, markup = None, block = None ): - pass - - def field_exit( self, field, markup = None, block = None ): - pass - - def markup_exit( self, markup, block = None ): - pass - - def block_exit( self, block ): - pass - - def section_exit( self, section ): - pass - - - def section_dump( self, section, section_filename = None ): - - output = None - if section_filename: - output = open_output( section_filename ) - - self.section_enter( section ) - - for name in section.block_names: - block = self.identifiers[ name ] - self.block_enter( block ) - - for markup in block.markups[1:]: # always ignore first markup !! - self.markup_enter( markup, block ) - - for field in markup.fields: - self.field_enter( field, markup, block ) - - self.field_exit ( field, markup, block ) - - self.markup_exit( markup, block ) - - self.block_exit( block ) - - self.section_exit ( section ) - - if output: - close_output( output ) - - - def section_dump_all( self ): - for section in self.sections: - self.section_dump( section ) - - # - # Formatting a block - # - - - - +from sources import * +from content import * +from utils import * + +# This is the base Formatter class. its purpose is to convert +# a content processor's data into specific documents (i.e. table of +# contents, global index, and individual API reference indices). +# +# You'll need to sub-class it to output anything sensible. For example, +# the file tohtml.py contains the definition of the HtmlFormatter sub-class +# used to output, you guessed it, HTML. +# + +class Formatter: + + def __init__( self, processor ): + + self.processor = processor + self.identifiers = {} + self.chapters = processor.chapters + self.sections = processor.sections.values() + self.block_index = [] + + # store all blocks in a dictionary + self.blocks = [] + for section in self.sections: + for block in section.blocks.values(): + self.add_identifier( block.name, block ) + + # add enumeration values to the index, since this is useful + for markup in block.markups: + if markup.tag == 'values': + for field in markup.fields: + self.add_identifier( field.name, block ) + + + self.block_index = self.identifiers.keys() + self.block_index.sort( index_sort ) + + + def add_identifier( self, name, block ): + if self.identifiers.has_key( name ): + # duplicate name !! + sys.stderr.write( \ + "WARNING: duplicate definition for '" + name + "' in " + \ + block.location() + ", previous definition in " + \ + self.identifiers[ name ].location() + "\n" ) + else: + self.identifiers[name] = block + + + # + # Formatting the table of contents + # + + def toc_enter( self ): + pass + + def toc_chapter_enter( self, chapter ): + pass + + def toc_section_enter( self, section ): + pass + + def toc_section_exit( self, section ): + pass + + def toc_chapter_exit( self, chapter ): + pass + + def toc_index( self, index_filename ): + pass + + def toc_exit( self ): + pass + + def toc_dump( self, toc_filename = None, index_filename = None ): + + output = None + if toc_filename: + output = open_output( toc_filename ) + + self.toc_enter() + + for chap in self.processor.chapters: + + self.toc_chapter_enter( chap ) + + for section in chap.sections: + self.toc_section_enter( section ) + self.toc_section_exit( section ) + + self.toc_chapter_exit ( chap ) + + self.toc_index( index_filename ) + + self.toc_exit() + + if output: + close_output( output ) + + # + # Formatting the index + # + + def index_enter( self ): + pass + + def index_name_enter( self, name ): + pass + + def index_name_exit( self, name ): + pass + + def index_exit( self ): + pass + + def index_dump( self, index_filename = None ): + + output = None + if index_filename: + output = open_output( index_filename ) + + self.index_enter() + + for name in self.block_index: + self.index_name_enter( name ) + self.index_name_exit ( name ) + + self.index_exit() + + if output: + close_output( output ) + + # + # Formatting a section + # + def section_enter( self, section ): + pass + + def block_enter( self, block ): + pass + + def markup_enter( self, markup, block = None ): + pass + + def field_enter( self, field, markup = None, block = None ): + pass + + def field_exit( self, field, markup = None, block = None ): + pass + + def markup_exit( self, markup, block = None ): + pass + + def block_exit( self, block ): + pass + + def section_exit( self, section ): + pass + + + def section_dump( self, section, section_filename = None ): + + output = None + if section_filename: + output = open_output( section_filename ) + + self.section_enter( section ) + + for name in section.block_names: + block = self.identifiers[ name ] + self.block_enter( block ) + + for markup in block.markups[1:]: # always ignore first markup !! + self.markup_enter( markup, block ) + + for field in markup.fields: + self.field_enter( field, markup, block ) + + self.field_exit ( field, markup, block ) + + self.markup_exit( markup, block ) + + self.block_exit( block ) + + self.section_exit ( section ) + + if output: + close_output( output ) + + + def section_dump_all( self ): + for section in self.sections: + self.section_dump( section ) + + # + # Formatting a block + # + + + + diff --git a/src/libs/freetype2/tools/docmaker/sources.py b/src/libs/freetype2/tools/docmaker/sources.py index 5145ba5ed2..4923005624 100644 --- a/src/libs/freetype2/tools/docmaker/sources.py +++ b/src/libs/freetype2/tools/docmaker/sources.py @@ -1,355 +1,355 @@ -# -# this file contains definitions of classes needed to decompose -# C sources files into a series of multi-line "blocks". There are -# two kinds of blocks: -# -# - normal blocks, which contain source code or ordinary comments -# -# - documentation blocks, which have restricted formatting, and -# whose text always start with a documentation markup tag like -# "<Function>", "<Type>", etc.. -# -# the routines used to process the content of documentation blocks -# are not contained here, but in "content.py" -# -# the classes and methods found here only deal with text parsing -# and basic documentation block extraction -# -import fileinput, re, sys, os, string - - - - - - -################################################################ -## -## BLOCK FORMAT PATTERN -## -## A simple class containing compiled regular expressions used -## to detect potential documentation format block comments within -## C source code -## -## note that the 'column' pattern must contain a group that will -## be used to "unbox" the content of documentation comment blocks -## -class SourceBlockFormat: - - def __init__( self, id, start, column, end ): - """create a block pattern, used to recognize special documentation blocks""" - - self.id = id - self.start = re.compile( start, re.VERBOSE ) - self.column = re.compile( column, re.VERBOSE ) - self.end = re.compile( end, re.VERBOSE ) - - - -# -# format 1 documentation comment blocks look like the following: -# -# /************************************/ -# /* */ -# /* */ -# /* */ -# /************************************/ -# -# we define a few regular expressions here to detect them -# - -start = r''' - \s* # any number of whitespace - /\*{2,}/ # followed by '/' and at least two asterisks then '/' - \s*$ # eventually followed by whitespace -''' - -column = r''' - \s* # any number of whitespace - /\*{1} # followed by '/' and precisely one asterisk - ([^*].*) # followed by anything (group 1) - \*{1}/ # followed by one asterisk and a '/' - \s*$ # enventually followed by whitespace -''' - -re_source_block_format1 = SourceBlockFormat( 1, start, column, start ) - -# -# format 2 documentation comment blocks look like the following: -# -# /************************************ (at least 2 asterisks) -# * -# * -# * -# * -# **/ (1 or more asterisks at the end) -# -# we define a few regular expressions here to detect them -# -start = r''' - \s* # any number of whitespace - /\*{2,} # followed by '/' and at least two asterisks - \s*$ # eventually followed by whitespace -''' - -column = r''' - \s* # any number of whitespace - \*{1} # followed by precisely one asterisk - (.*) # then anything (group1) -''' - -end = r''' - \s* # any number of whitespace - \*+/ # followed by at least one asterisk, then '/' -''' - -re_source_block_format2 = SourceBlockFormat( 2, start, column, end ) - -# -# the list of supported documentation block formats, we could add new ones -# relatively easily -# -re_source_block_formats = [ re_source_block_format1, re_source_block_format2 ] - - -# -# the following regular expressions corresponds to markup tags -# within the documentation comment blocks. they're equivalent -# despite their different syntax -# -# notice how each markup tag _must_ begin a new line -# -re_markup_tag1 = re.compile( r'''\s*<(\w*)>''' ) # <xxxx> format -re_markup_tag2 = re.compile( r'''\s*@(\w*):''' ) # @xxxx: format - -# -# the list of supported markup tags, we could add new ones relatively -# easily -# -re_markup_tags = [ re_markup_tag1, re_markup_tag2 ] - -# -# used to detect a cross-reference, after markup tags have been stripped -# -re_crossref = re.compile( r'@(\w*)' ) - -# -# used to detect italic and bold styles in paragraph text -# -re_italic = re.compile( r'_(\w+)_' ) -re_bold = re.compile( r'\*(\w+)\*' ) - -# -# used to detect the end of commented source lines -# -re_source_sep = re.compile( r'\s*/\*\s*\*/' ) - -# -# used to perform cross-reference within source output -# -re_source_crossref = re.compile( r'(\W*)(\w*)' ) - -# -# a list of reserved source keywords -# -re_source_keywords = re.compile( '''( typedef | - struct | - enum | - union | - const | - char | - int | - short | - long | - void | - signed | - unsigned | - \#include | - \#define | - \#undef | - \#if | - \#ifdef | - \#ifndef | - \#else | - \#endif )''', re.VERBOSE ) - -################################################################ -## -## SOURCE BLOCK CLASS -## -## A SourceProcessor is in charge or reading a C source file -## and decomposing it into a series of different "SourceBlocks". -## each one of these blocks can be made of the following data: -## -## - A documentation comment block that starts with "/**" and -## whose exact format will be discussed later -## -## - normal sources lines, include comments -## -## the important fields in a text block are the following ones: -## -## self.lines : a list of text lines for the corresponding block -## -## self.content : for documentation comment blocks only, this is the -## block content that has been "unboxed" from its -## decoration. This is None for all other blocks -## (i.e. sources or ordinary comments with no starting -## markup tag) -## -class SourceBlock: - def __init__( self, processor, filename, lineno, lines ): - self.processor = processor - self.filename = filename - self.lineno = lineno - self.lines = lines - self.format = processor.format - self.content = [] - - if self.format == None: - return - - words = [] - - # extract comment lines - lines = [] - - for line0 in self.lines[1:]: - m = self.format.column.match( line0 ) - if m: - lines.append( m.group(1) ) - - # now, look for a markup tag - for l in lines: - l = string.strip(l) - if len(l) > 0: - for tag in re_markup_tags: - if tag.match( l ): - self.content = lines - return - - def location( self ): - return "(" + self.filename + ":" + repr(self.lineno) + ")" - - - # debugging only - not used in normal operations - def dump( self ): - - if self.content: - print "{{{content start---" - for l in self.content: - print l - print "---content end}}}" - return - - fmt = "" - if self.format: - fmt = repr(self.format.id) + " " - - for line in self.lines: - print line - - -################################################################ -## -## SOURCE PROCESSOR CLASS -## -## The SourceProcessor is in charge or reading a C source file -## and decomposing it into a series of different "SourceBlock" -## objects. -## -## each one of these blocks can be made of the following data: -## -## - A documentation comment block that starts with "/**" and -## whose exact format will be discussed later -## -## - normal sources lines, include comments -## -## -class SourceProcessor: - - def __init__( self ): - """initialize a source processor""" - self.blocks = [] - self.filename = None - self.format = None - self.lines = [] - - def reset( self ): - """reset a block processor, clean all its blocks""" - self.blocks = [] - self.format = None - - - def parse_file( self, filename ): - """parse a C source file, and adds its blocks to the processor's list""" - - self.reset() - - self.filename = filename - - fileinput.close() - self.format = None - self.lineno = 0 - self.lines = [] - - for line in fileinput.input( filename ): - - # strip trailing newlines, important on Windows machines !! - if line[-1] == '\012': - line = line[0:-1] - - if self.format == None: - self.process_normal_line( line ) - - else: - if self.format.end.match( line ): - # that's a normal block end, add it to lines and - # create a new block - # self.lines.append( line ) - self.add_block_lines() - - elif self.format.column.match( line ): - # that's a normal column line, add it to 'lines' - self.lines.append( line ) - - else: - # humm.. this is an unexcepted block end, - # create a new block, but don't process the line - self.add_block_lines() - - # we need to process the line again - self.process_normal_line( line ) - - # record the last lines - self.add_block_lines() - - - - def process_normal_line( self, line ): - """process a normal line and check if it's the start of a new block""" - for f in re_source_block_formats: - if f.start.match( line ): - self.add_block_lines() - self.format = f - self.lineno = fileinput.filelineno() - - self.lines.append( line ) - - - - def add_block_lines( self ): - """add the current accumulated lines, and create a new block""" - if self.lines != []: - block = SourceBlock( self, self.filename, self.lineno, self.lines ) - - self.blocks.append( block ) - self.format = None - self.lines = [] - - - # debugging only, not used in normal operations - def dump( self ): - """print all blocks in a processor""" - for b in self.blocks: - b.dump() - -# eof +# +# this file contains definitions of classes needed to decompose +# C sources files into a series of multi-line "blocks". There are +# two kinds of blocks: +# +# - normal blocks, which contain source code or ordinary comments +# +# - documentation blocks, which have restricted formatting, and +# whose text always start with a documentation markup tag like +# "<Function>", "<Type>", etc.. +# +# the routines used to process the content of documentation blocks +# are not contained here, but in "content.py" +# +# the classes and methods found here only deal with text parsing +# and basic documentation block extraction +# +import fileinput, re, sys, os, string + + + + + + +################################################################ +## +## BLOCK FORMAT PATTERN +## +## A simple class containing compiled regular expressions used +## to detect potential documentation format block comments within +## C source code +## +## note that the 'column' pattern must contain a group that will +## be used to "unbox" the content of documentation comment blocks +## +class SourceBlockFormat: + + def __init__( self, id, start, column, end ): + """create a block pattern, used to recognize special documentation blocks""" + + self.id = id + self.start = re.compile( start, re.VERBOSE ) + self.column = re.compile( column, re.VERBOSE ) + self.end = re.compile( end, re.VERBOSE ) + + + +# +# format 1 documentation comment blocks look like the following: +# +# /************************************/ +# /* */ +# /* */ +# /* */ +# /************************************/ +# +# we define a few regular expressions here to detect them +# + +start = r''' + \s* # any number of whitespace + /\*{2,}/ # followed by '/' and at least two asterisks then '/' + \s*$ # eventually followed by whitespace +''' + +column = r''' + \s* # any number of whitespace + /\*{1} # followed by '/' and precisely one asterisk + ([^*].*) # followed by anything (group 1) + \*{1}/ # followed by one asterisk and a '/' + \s*$ # enventually followed by whitespace +''' + +re_source_block_format1 = SourceBlockFormat( 1, start, column, start ) + +# +# format 2 documentation comment blocks look like the following: +# +# /************************************ (at least 2 asterisks) +# * +# * +# * +# * +# **/ (1 or more asterisks at the end) +# +# we define a few regular expressions here to detect them +# +start = r''' + \s* # any number of whitespace + /\*{2,} # followed by '/' and at least two asterisks + \s*$ # eventually followed by whitespace +''' + +column = r''' + \s* # any number of whitespace + \*{1} # followed by precisely one asterisk + (.*) # then anything (group1) +''' + +end = r''' + \s* # any number of whitespace + \*+/ # followed by at least one asterisk, then '/' +''' + +re_source_block_format2 = SourceBlockFormat( 2, start, column, end ) + +# +# the list of supported documentation block formats, we could add new ones +# relatively easily +# +re_source_block_formats = [ re_source_block_format1, re_source_block_format2 ] + + +# +# the following regular expressions corresponds to markup tags +# within the documentation comment blocks. they're equivalent +# despite their different syntax +# +# notice how each markup tag _must_ begin a new line +# +re_markup_tag1 = re.compile( r'''\s*<(\w*)>''' ) # <xxxx> format +re_markup_tag2 = re.compile( r'''\s*@(\w*):''' ) # @xxxx: format + +# +# the list of supported markup tags, we could add new ones relatively +# easily +# +re_markup_tags = [ re_markup_tag1, re_markup_tag2 ] + +# +# used to detect a cross-reference, after markup tags have been stripped +# +re_crossref = re.compile( r'@(\w*)(.*)' ) + +# +# used to detect italic and bold styles in paragraph text +# +re_italic = re.compile( r'_(\w+)_' ) +re_bold = re.compile( r'\*(\w+)\*' ) + +# +# used to detect the end of commented source lines +# +re_source_sep = re.compile( r'\s*/\*\s*\*/' ) + +# +# used to perform cross-reference within source output +# +re_source_crossref = re.compile( r'(\W*)(\w*)' ) + +# +# a list of reserved source keywords +# +re_source_keywords = re.compile( '''( typedef | + struct | + enum | + union | + const | + char | + int | + short | + long | + void | + signed | + unsigned | + \#include | + \#define | + \#undef | + \#if | + \#ifdef | + \#ifndef | + \#else | + \#endif )''', re.VERBOSE ) + +################################################################ +## +## SOURCE BLOCK CLASS +## +## A SourceProcessor is in charge or reading a C source file +## and decomposing it into a series of different "SourceBlocks". +## each one of these blocks can be made of the following data: +## +## - A documentation comment block that starts with "/**" and +## whose exact format will be discussed later +## +## - normal sources lines, include comments +## +## the important fields in a text block are the following ones: +## +## self.lines : a list of text lines for the corresponding block +## +## self.content : for documentation comment blocks only, this is the +## block content that has been "unboxed" from its +## decoration. This is None for all other blocks +## (i.e. sources or ordinary comments with no starting +## markup tag) +## +class SourceBlock: + def __init__( self, processor, filename, lineno, lines ): + self.processor = processor + self.filename = filename + self.lineno = lineno + self.lines = lines[:] + self.format = processor.format + self.content = [] + + if self.format == None: + return + + words = [] + + # extract comment lines + lines = [] + + for line0 in self.lines: + m = self.format.column.match( line0 ) + if m: + lines.append( m.group(1) ) + + # now, look for a markup tag + for l in lines: + l = string.strip(l) + if len(l) > 0: + for tag in re_markup_tags: + if tag.match( l ): + self.content = lines + return + + def location( self ): + return "(" + self.filename + ":" + repr(self.lineno) + ")" + + + # debugging only - not used in normal operations + def dump( self ): + + if self.content: + print "{{{content start---" + for l in self.content: + print l + print "---content end}}}" + return + + fmt = "" + if self.format: + fmt = repr(self.format.id) + " " + + for line in self.lines: + print line + + +################################################################ +## +## SOURCE PROCESSOR CLASS +## +## The SourceProcessor is in charge or reading a C source file +## and decomposing it into a series of different "SourceBlock" +## objects. +## +## each one of these blocks can be made of the following data: +## +## - A documentation comment block that starts with "/**" and +## whose exact format will be discussed later +## +## - normal sources lines, include comments +## +## +class SourceProcessor: + + def __init__( self ): + """initialize a source processor""" + self.blocks = [] + self.filename = None + self.format = None + self.lines = [] + + def reset( self ): + """reset a block processor, clean all its blocks""" + self.blocks = [] + self.format = None + + + def parse_file( self, filename ): + """parse a C source file, and adds its blocks to the processor's list""" + + self.reset() + + self.filename = filename + + fileinput.close() + self.format = None + self.lineno = 0 + self.lines = [] + + for line in fileinput.input( filename ): + + # strip trailing newlines, important on Windows machines !! + if line[-1] == '\012': + line = line[0:-1] + + if self.format == None: + self.process_normal_line( line ) + + else: + if self.format.end.match( line ): + # that's a normal block end, add it to lines and + # create a new block + self.lines.append( line ) + self.add_block_lines() + + elif self.format.column.match( line ): + # that's a normal column line, add it to 'lines' + self.lines.append( line ) + + else: + # humm.. this is an unexcepted block end, + # create a new block, but don't process the line + self.add_block_lines() + + # we need to process the line again + self.process_normal_line( line ) + + # record the last lines + self.add_block_lines() + + + + def process_normal_line( self, line ): + """process a normal line and check if it's the start of a new block""" + for f in re_source_block_formats: + if f.start.match( line ): + self.add_block_lines() + self.format = f + self.lineno = fileinput.filelineno() + + self.lines.append( line ) + + + + def add_block_lines( self ): + """add the current accumulated lines, and create a new block""" + if self.lines != []: + block = SourceBlock( self, self.filename, self.lineno, self.lines ) + + self.blocks.append( block ) + self.format = None + self.lines = [] + + + # debugging only, not used in normal operations + def dump( self ): + """print all blocks in a processor""" + for b in self.blocks: + b.dump() + +# eof diff --git a/src/libs/freetype2/tools/docmaker/tohtml.py b/src/libs/freetype2/tools/docmaker/tohtml.py index 5b8f31b726..2a3cf239b4 100644 --- a/src/libs/freetype2/tools/docmaker/tohtml.py +++ b/src/libs/freetype2/tools/docmaker/tohtml.py @@ -1,476 +1,489 @@ -from sources import * -from content import * -from formatter import * - -import time - -# The following defines the HTML header used by all generated pages. -# -html_header_1 = """\ -<html> -<header> -<title>""" - -html_header_2= """ API Reference - - - - -

""" - -html_header_3=""" API Reference

-""" - - - -# The HTML footer used by all generated pages. -# -html_footer = """\ - -""" - -# The header and footer used for each section. -# -section_title_header = "

" -section_title_footer = "

" - -# The header and footer used for code segments. -# -code_header = "
"
-code_footer = "
" - -# Paragraph header and footer. -# -para_header = "

" -para_footer = "

" - -# Block header and footer. -# -block_header = "
" -block_footer = "

" - -# Description header/footer. -# -description_header = "
" -description_footer = "

" - -# Marker header/inter/footer combination. -# -marker_header = "
" -marker_inter = "
" -marker_footer = "
" - -# Source code extracts header/footer. -# -source_header = "
\n"
-source_footer = "\n

" - -# Chapter header/inter/footer. -# -chapter_header = "

" -chapter_inter = "

    " -chapter_footer = "
" - - -# source language keyword coloration/styling -# -keyword_prefix = '' -keyword_suffix = '' - -section_synopsis_header = '

Synopsys

' -section_synopsis_footer = '' - -# Translate a single line of source to HTML. This will convert -# a "<" into "<.", ">" into ">.", etc. -# -def html_quote( line ): - result = string.replace( line, "&", "&" ) - result = string.replace( result, "<", "<" ) - result = string.replace( result, ">", ">" ) - return result - - -# same as 'html_quote', but ignores left and right brackets -# -def html_quote0( line ): - return string.replace( line, "&", "&" ) - - -def dump_html_code( lines, prefix = "" ): - # clean the last empty lines - # - l = len( self.lines ) - while l > 0 and string.strip( self.lines[l - 1] ) == "": - l = l - 1 - - # The code footer should be directly appended to the last code - # line to avoid an additional blank line. - # - print prefix + code_header, - for line in self.lines[0 : l+1]: - print '\n' + prefix + html_quote(line), - print prefix + code_footer, - - - -class HtmlFormatter(Formatter): - - def __init__( self, processor, project_title, file_prefix ): - - Formatter.__init__( self, processor ) - - global html_header_1, html_header_2, html_header_3, html_footer - - if file_prefix: - file_prefix = file_prefix + "-" - else: - file_prefix = "" - - self.project_title = project_title - self.file_prefix = file_prefix - self.html_header = html_header_1 + project_title + html_header_2 + \ - project_title + html_header_3 - - self.html_footer = "

generated on " + \ - time.asctime( time.localtime( time.time() ) ) + \ - "

" + html_footer - - self.columns = 3 - - def make_section_url( self, section ): - return self.file_prefix + section.name + ".html" - - - def make_block_url( self, block ): - return self.make_section_url( block.section ) + "#" + block.name - - - def make_html_words( self, words ): - """ convert a series of simple words into some HTML text """ - line = "" - if words: - line = html_quote( words[0] ) - for w in words[1:]: - line = line + " " + html_quote( w ) - - return line - - - def make_html_word( self, word ): - """analyze a simple word to detect cross-references and styling""" - # look for cross-references - # - m = re_crossref.match( word ) - if m: - try: - name = m.group(1) - block = self.identifiers[ name ] - url = self.make_block_url( block ) - return '' + name + '' - except: - return '?' + name + '?' - - # look for italics and bolds - m = re_italic.match( word ) - if m: - name = m.group(1) - return ''+name+'' - - m = re_bold.match( word ) - if m: - name = m.group(1) - return ''+name+'' - - return html_quote(word) - - - def make_html_para( self, words ): - """ convert a paragraph's words into tagged HTML text, handle xrefs """ - line = "" - if words: - line = self.make_html_word( words[0] ) - for word in words[1:]: - line = line + " " + self.make_html_word( word ) - - return "

" + line + "

" - - - def make_html_code( self, lines ): - """ convert a code sequence to HTML """ - line = code_header + '\n' - for l in lines: - line = line + html_quote( l ) + '\n' - - return line + code_footer - - - def make_html_items( self, items ): - """ convert a field's content into some valid HTML """ - lines = [] - for item in items: - if item.lines: - lines.append( self.make_html_code( item.lines ) ) - else: - lines.append( self.make_html_para( item.words ) ) - - return string.join( lines, '\n' ) - - - def print_html_items( self, items ): - print self.make_html_items( items ) - - - def print_html_field( self, field ): - if field.name: - print "
"+field.name+"" - - print self.make_html_items( field.items ) - - if field.name: - print "
" - - - def html_source_quote( self, line, block_name = None ): - result = "" - while line: - m = re_source_crossref.match( line ) - if m: - name = m.group(2) - prefix = html_quote( m.group(1) ) - length = len( m.group(0) ) - - if name == block_name: - # this is the current block name, if any - result = result + prefix + '' + name + '' - - elif re_source_keywords.match(name): - # this is a C keyword - result = result + prefix + keyword_prefix + name + keyword_suffix - - elif self.identifiers.has_key(name): - # this is a known identifier - block = self.identifiers[name] - result = result + prefix + '' + name + '' - else: - result = result + html_quote(line[ : length ]) - - line = line[ length : ] - else: - result = result + html_quote(line) - line = [] - - return result - - - def print_html_field_list( self, fields ): - print "" - for field in fields: - print "" - print "
" + field.name + "" - self.print_html_items( field.items ) - print "
" - - - def print_html_markup( self, markup ): - table_fields = [] - for field in markup.fields: - if field.name: - # we begin a new series of field or value definitions, we - # will record them in the 'table_fields' list before outputting - # all of them as a single table - # - table_fields.append( field ) - - else: - if table_fields: - self.print_html_field_list( table_fields ) - table_fields = [] - - self.print_html_items( field.items ) - - if table_fields: - self.print_html_field_list( table_fields ) - - # - # Formatting the index - # - - def index_enter( self ): - print self.html_header - self.index_items = {} - - def index_name_enter( self, name ): - block = self.identifiers[ name ] - url = self.make_block_url( block ) - self.index_items[ name ] = url - - def index_exit( self ): - - # block_index already contains the sorted list of index names - count = len( self.block_index ) - rows = (count + self.columns - 1)/self.columns - - print "
" - for r in range(rows): - line = "" - for c in range(self.columns): - i = r + c*rows - if i < count: - bname = self.block_index[ r + c*rows ] - url = self.index_items[ bname ] - line = line + '' - else: - line = line + '' - line = line + "" - print line - - print "
' + bname + '
" - print self.html_footer - self.index_items = {} - - def index_dump( self, index_filename = None ): - - if index_filename == None: - index_filename = self.file_prefix + "index.html" - - Formatter.index_dump( self, index_filename ) - - # - # Formatting the table of content - # - def toc_enter( self ): - print self.html_header - print "

Table of Contents

" - - def toc_chapter_enter( self, chapter ): - print chapter_header + string.join(chapter.title) + chapter_inter - print "" - - def toc_section_enter( self, section ): - print "" - - def toc_chapter_exit( self, chapter ): - print "
" - print '' + \ - section.title + '' - - print self.make_html_para( section.abstract ) - - def toc_section_exit( self, section ): - print "
" - print chapter_footer - - def toc_index( self, index_filename ): - print chapter_header + 'Global Index' + chapter_inter + chapter_footer - - def toc_exit( self ): - print "" - print self.html_footer - - def toc_dump( self, toc_filename = None, index_filename = None ): - if toc_filename == None: - toc_filename = self.file_prefix + "toc.html" - - if index_filename == None: - index_filename = self.file_prefix + "index.html" - - Formatter.toc_dump( self, toc_filename, index_filename ) - - # - # Formatting sections - # - def section_enter( self, section ): - print self.html_header - - print section_title_header - print section.title - print section_title_footer - - # print section synopsys - print section_synopsis_header - print "
" - - maxwidth = 0 - for b in section.blocks.values(): - if len(b.name) > maxwidth: - maxwidth = len(b.name) - - width = 70 # XXX magic number - columns = width / maxwidth - if columns < 1: - columns = 1 - - count = len(section.block_names) - rows = (count + columns-1)/columns - for r in range(rows): - line = "" - for c in range(columns): - i = r + c*rows - line = line + '' - line = line + "" - print line - - print "
' - if i < count: - name = section.block_names[i] - line = line + '' + name + '' - - line = line + '


" - print section_synopsis_footer - - print description_header - print self.make_html_items( section.description ) - print description_footer - - def block_enter( self, block ): - print block_header - - # place html anchor if needed - if block.name: - print '' - print "

" + block.name + "

" - print "
" - - # dump the block C source lines now - if block.code: - print source_header - for l in block.code: - print self.html_source_quote( l, block.name ) - print source_footer - - - def markup_enter( self, markup, block ): - if markup.tag == "description": - print description_header - else: - print marker_header + markup.tag + marker_inter - - self.print_html_markup( markup ) - - def markup_exit( self, markup, block ): - if markup.tag == "description": - print description_footer - else: - print marker_footer - - def block_exit( self, block ): - print block_footer - - - def section_exit( self, section ): - print html_footer - - - def section_dump_all( self ): - for section in self.sections: - self.section_dump( section, self.file_prefix + section.name + '.html' ) - \ No newline at end of file +from sources import * +from content import * +from formatter import * + +import time + +# The following defines the HTML header used by all generated pages. +# +html_header_1 = """\ + + + + +""" + +html_header_2= """ API Reference + + + +

""" + +html_header_3=""" API Reference

+""" + + + +# The HTML footer used by all generated pages. +# +html_footer = """\ + +""" + +# The header and footer used for each section. +# +section_title_header = "

" +section_title_footer = "

" + +# The header and footer used for code segments. +# +code_header = '
'
+code_footer = '
' + +# Paragraph header and footer. +# +para_header = "

" +para_footer = "

" + +# Block header and footer. +# +block_header = '
' +block_footer = '

' + +# Description header/footer. +# +description_header = '
' +description_footer = "

" + +# Marker header/inter/footer combination. +# +marker_header = '
' +marker_inter = "
" +marker_footer = "
" + +# Source code extracts header/footer. +# +source_header = '
\n'
+source_footer = "\n

" + +# Chapter header/inter/footer. +# +chapter_header = '

' +chapter_inter = '

  • ' +chapter_footer = '
' + + +# source language keyword coloration/styling +# +keyword_prefix = '' +keyword_suffix = '' + +section_synopsis_header = '

Synopsis

' +section_synopsis_footer = '' + +# Translate a single line of source to HTML. This will convert +# a "<" into "<.", ">" into ">.", etc. +# +def html_quote( line ): + result = string.replace( line, "&", "&" ) + result = string.replace( result, "<", "<" ) + result = string.replace( result, ">", ">" ) + return result + + +# same as 'html_quote', but ignores left and right brackets +# +def html_quote0( line ): + return string.replace( line, "&", "&" ) + + +def dump_html_code( lines, prefix = "" ): + # clean the last empty lines + # + l = len( self.lines ) + while l > 0 and string.strip( self.lines[l - 1] ) == "": + l = l - 1 + + # The code footer should be directly appended to the last code + # line to avoid an additional blank line. + # + print prefix + code_header, + for line in self.lines[0 : l+1]: + print '\n' + prefix + html_quote(line), + print prefix + code_footer, + + + +class HtmlFormatter(Formatter): + + def __init__( self, processor, project_title, file_prefix ): + + Formatter.__init__( self, processor ) + + global html_header_1, html_header_2, html_header_3, html_footer + + if file_prefix: + file_prefix = file_prefix + "-" + else: + file_prefix = "" + + self.project_title = project_title + self.file_prefix = file_prefix + self.html_header = html_header_1 + project_title + html_header_2 + \ + project_title + html_header_3 + + self.html_footer = "
generated on " + \ + time.asctime( time.localtime( time.time() ) ) + \ + "
" + html_footer + + self.columns = 3 + + def make_section_url( self, section ): + return self.file_prefix + section.name + ".html" + + + def make_block_url( self, block ): + return self.make_section_url( block.section ) + "#" + block.name + + + def make_html_words( self, words ): + """ convert a series of simple words into some HTML text """ + line = "" + if words: + line = html_quote( words[0] ) + for w in words[1:]: + line = line + " " + html_quote( w ) + + return line + + + def make_html_word( self, word ): + """analyze a simple word to detect cross-references and styling""" + # look for cross-references + # + m = re_crossref.match( word ) + if m: + try: + name = m.group(1) + rest = m.group(2) + block = self.identifiers[ name ] + url = self.make_block_url( block ) + return '' + name + '' + rest + except: + return '?' + name + '?' + rest + + # look for italics and bolds + m = re_italic.match( word ) + if m: + name = m.group(1) + return ''+name+'' + + m = re_bold.match( word ) + if m: + name = m.group(1) + return ''+name+'' + + return html_quote(word) + + + def make_html_para( self, words ): + """ convert a paragraph's words into tagged HTML text, handle xrefs """ + line = "" + if words: + line = self.make_html_word( words[0] ) + for word in words[1:]: + line = line + " " + self.make_html_word( word ) + + return "

" + line + "

" + + + def make_html_code( self, lines ): + """ convert a code sequence to HTML """ + line = code_header + '\n' + for l in lines: + line = line + html_quote( l ) + '\n' + + return line + code_footer + + + def make_html_items( self, items ): + """ convert a field's content into some valid HTML """ + lines = [] + for item in items: + if item.lines: + lines.append( self.make_html_code( item.lines ) ) + else: + lines.append( self.make_html_para( item.words ) ) + + return string.join( lines, '\n' ) + + + def print_html_items( self, items ): + print self.make_html_items( items ) + + + def print_html_field( self, field ): + if field.name: + print "
"+field.name+"" + + print self.make_html_items( field.items ) + + if field.name: + print "
" + + + def html_source_quote( self, line, block_name = None ): + result = "" + while line: + m = re_source_crossref.match( line ) + if m: + name = m.group(2) + prefix = html_quote( m.group(1) ) + length = len( m.group(0) ) + + if name == block_name: + # this is the current block name, if any + result = result + prefix + '' + name + '' + + elif re_source_keywords.match(name): + # this is a C keyword + result = result + prefix + keyword_prefix + name + keyword_suffix + + elif self.identifiers.has_key(name): + # this is a known identifier + block = self.identifiers[name] + result = result + prefix + '' + name + '' + else: + result = result + html_quote(line[ : length ]) + + line = line[ length : ] + else: + result = result + html_quote(line) + line = [] + + return result + + + def print_html_field_list( self, fields ): + print "" + for field in fields: + print "" + print "
" + field.name + "" + self.print_html_items( field.items ) + print "
" + + + def print_html_markup( self, markup ): + table_fields = [] + for field in markup.fields: + if field.name: + # we begin a new series of field or value definitions, we + # will record them in the 'table_fields' list before outputting + # all of them as a single table + # + table_fields.append( field ) + + else: + if table_fields: + self.print_html_field_list( table_fields ) + table_fields = [] + + self.print_html_items( field.items ) + + if table_fields: + self.print_html_field_list( table_fields ) + + # + # Formatting the index + # + + def index_enter( self ): + print self.html_header + self.index_items = {} + + def index_name_enter( self, name ): + block = self.identifiers[ name ] + url = self.make_block_url( block ) + self.index_items[ name ] = url + + def index_exit( self ): + + # block_index already contains the sorted list of index names + count = len( self.block_index ) + rows = (count + self.columns - 1)/self.columns + + print "" + for r in range(rows): + line = "" + for c in range(self.columns): + i = r + c*rows + if i < count: + bname = self.block_index[ r + c*rows ] + url = self.index_items[ bname ] + line = line + '' + else: + line = line + '' + line = line + "" + print line + + print "
' + bname + '
" + print self.html_footer + self.index_items = {} + + def index_dump( self, index_filename = None ): + + if index_filename == None: + index_filename = self.file_prefix + "index.html" + + Formatter.index_dump( self, index_filename ) + + # + # Formatting the table of content + # + def toc_enter( self ): + print self.html_header + print "

Table of Contents

" + + def toc_chapter_enter( self, chapter ): + print chapter_header + string.join(chapter.title) + chapter_inter + print "" + + def toc_section_enter( self, section ): + print "" + + def toc_chapter_exit( self, chapter ): + print "
" + print '' + \ + section.title + '' + + print self.make_html_para( section.abstract ) + + def toc_section_exit( self, section ): + print "
" + print chapter_footer + + def toc_index( self, index_filename ): + print chapter_header + 'Global Index' + chapter_inter + chapter_footer + + def toc_exit( self ): + print self.html_footer + + def toc_dump( self, toc_filename = None, index_filename = None ): + if toc_filename == None: + toc_filename = self.file_prefix + "toc.html" + + if index_filename == None: + index_filename = self.file_prefix + "index.html" + + Formatter.toc_dump( self, toc_filename, index_filename ) + + # + # Formatting sections + # + def section_enter( self, section ): + print self.html_header + + print section_title_header + print section.title + print section_title_footer + + # print section synopsys + print section_synopsis_header + print "" + + maxwidth = 0 + for b in section.blocks.values(): + if len(b.name) > maxwidth: + maxwidth = len(b.name) + + width = 70 # XXX magic number + columns = width / maxwidth + if columns < 1: + columns = 1 + + count = len(section.block_names) + rows = (count + columns-1)/columns + for r in range(rows): + line = "" + for c in range(columns): + i = r + c*rows + line = line + '' + line = line + "" + print line + + print "
' + if i < count: + name = section.block_names[i] + line = line + '' + name + '' + + line = line + '


" + print section_synopsis_footer + + print description_header + print self.make_html_items( section.description ) + print description_footer + + def block_enter( self, block ): + print block_header + + # place html anchor if needed + if block.name: + print '

' + block.name + '

' + + # dump the block C source lines now + if block.code: + print source_header + for l in block.code: + print self.html_source_quote( l, block.name ) + print source_footer + + + def markup_enter( self, markup, block ): + if markup.tag == "description": + print description_header + else: + print marker_header + markup.tag + marker_inter + + self.print_html_markup( markup ) + + def markup_exit( self, markup, block ): + if markup.tag == "description": + print description_footer + else: + print marker_footer + + def block_exit( self, block ): + print block_footer + + + def section_exit( self, section ): + print html_footer + + + def section_dump_all( self ): + for section in self.sections: + self.section_dump( section, self.file_prefix + section.name + '.html' ) + diff --git a/src/libs/freetype2/tools/docmaker/utils.py b/src/libs/freetype2/tools/docmaker/utils.py index 6c6715d9b3..c3e9e2700f 100644 --- a/src/libs/freetype2/tools/docmaker/utils.py +++ b/src/libs/freetype2/tools/docmaker/utils.py @@ -1,87 +1,128 @@ -import string, sys, os - -# current output directory -# -output_dir = None - - -# This function is used to sort the index. It is a simple lexicographical -# sort, except that it places capital letters before lowercase ones. -# -def index_sort( s1, s2 ): - if not s1: - return -1 - - if not s2: - return 1 - - l1 = len( s1 ) - l2 = len( s2 ) - m1 = string.lower( s1 ) - m2 = string.lower( s2 ) - - for i in range( l1 ): - if i >= l2 or m1[i] > m2[i]: - return 1 - - if m1[i] < m2[i]: - return -1 - - if s1[i] < s2[i]: - return -1 - - if s1[i] > s2[i]: - return 1 - - if l2 > l1: - return -1 - - return 0 - -# Sort input_list, placing the elements of order_list in front. -# -def sort_order_list( input_list, order_list ): - new_list = order_list[:] - for id in input_list: - if not id in order_list: - new_list.append( id ) - return new_list - - - -# Open the standard output to a given project documentation file. Use -# "output_dir" to determine the filename location if necessary and save the -# old stdout in a tuple that is returned by this function. -# -def open_output( filename ): - global output_dir - - if output_dir and output_dir != "": - filename = output_dir + os.sep + filename - - old_stdout = sys.stdout - new_file = open( filename, "w" ) - sys.stdout = new_file - - return ( new_file, old_stdout ) - - -# Close the output that was returned by "close_output". -# -def close_output( output ): - output[0].close() - sys.stdout = output[1] - - -# Check output directory. -# -def check_output( ): - global output_dir - if output_dir: - if output_dir != "": - if not os.path.isdir( output_dir ): - sys.stderr.write( "argument" + " '" + output_dir + "' " + - "is not a valid directory" ) - sys.exit( 2 ) - else: - output_dir = None +import string, sys, os, glob + +# current output directory +# +output_dir = None + + +# This function is used to sort the index. It is a simple lexicographical +# sort, except that it places capital letters before lowercase ones. +# +def index_sort( s1, s2 ): + if not s1: + return -1 + + if not s2: + return 1 + + l1 = len( s1 ) + l2 = len( s2 ) + m1 = string.lower( s1 ) + m2 = string.lower( s2 ) + + for i in range( l1 ): + if i >= l2 or m1[i] > m2[i]: + return 1 + + if m1[i] < m2[i]: + return -1 + + if s1[i] < s2[i]: + return -1 + + if s1[i] > s2[i]: + return 1 + + if l2 > l1: + return -1 + + return 0 + +# Sort input_list, placing the elements of order_list in front. +# +def sort_order_list( input_list, order_list ): + new_list = order_list[:] + for id in input_list: + if not id in order_list: + new_list.append( id ) + return new_list + + + +# Open the standard output to a given project documentation file. Use +# "output_dir" to determine the filename location if necessary and save the +# old stdout in a tuple that is returned by this function. +# +def open_output( filename ): + global output_dir + + if output_dir and output_dir != "": + filename = output_dir + os.sep + filename + + old_stdout = sys.stdout + new_file = open( filename, "w" ) + sys.stdout = new_file + + return ( new_file, old_stdout ) + + +# Close the output that was returned by "close_output". +# +def close_output( output ): + output[0].close() + sys.stdout = output[1] + + +# Check output directory. +# +def check_output( ): + global output_dir + if output_dir: + if output_dir != "": + if not os.path.isdir( output_dir ): + sys.stderr.write( "argument" + " '" + output_dir + "' " + + "is not a valid directory" ) + sys.exit( 2 ) + else: + output_dir = None + +def file_exists( pathname ): + """checks that a given file exists""" + result = 1 + try: + file = open( pathname, "r" ) + file.close() + except: + result = None + sys.stderr.write( pathname + " couldn't be accessed\n" ) + + return result + + +def make_file_list( args = None ): + """builds a list of input files from command-line arguments""" + + file_list = [] + # sys.stderr.write( repr( sys.argv[1 :] ) + '\n' ) + + if not args: + args = sys.argv[1 :] + + for pathname in args: + if string.find( pathname, '*' ) >= 0: + newpath = glob.glob( pathname ) + newpath.sort() # sort files -- this is important because + # of the order of files + else: + newpath = [pathname] + + file_list.extend( newpath ) + + if len( file_list ) == 0: + file_list = None + else: + # now filter the file list to remove non-existing ones + file_list = filter( file_exists, file_list ) + + return file_list + diff --git a/src/libs/freetype2/tools/glnames.py b/src/libs/freetype2/tools/glnames.py index e8a835447a..e8e80ec6cf 100755 --- a/src/libs/freetype2/tools/glnames.py +++ b/src/libs/freetype2/tools/glnames.py @@ -1,1722 +1,4954 @@ -#!/usr/bin/env python -# - -# -# FreeType 2 glyph name builder -# - - -# Copyright 1996-2000 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. - - -"""\ - -usage: %s - - This very simple python script is used to generate the glyph names - tables defined in the PSNames module. - - Its single argument is the name of the header file to be created. -""" - - -import sys, string - - -# This table is used to name the glyph according to the Macintosh -# specification. It is used by the TrueType Postscript names table -# -# see http://fonts.apple.com/TTRefMan/RM06/Chap6post.html -# for the official list -# -mac_standard_names = \ -[ - # 0 - ".notdef", ".null", "nonmarkingreturn", "space", "exclam", - "quotedbl", "numbersign", "dollar", "percent", "ampersand", - - # 10 - "quotesingle", "parenleft", "parenright", "asterisk", "plus", - "comma", "hyphen", "period", "slash", "zero", - - # 20 - "one", "two", "three", "four", "five", - "six", "seven", "eight", "nine", "colon", - - # 30 - "semicolon", "less", "equal", "greater", "question", - "at", "A", "B", "C", "D", - - # 40 - "E", "F", "G", "H", "I", - "J", "K", "L", "M", "N", - - # 50 - "O", "P", "Q", "R", "S", - "T", "U", "V", "W", "X", - - # 60 - "Y", "Z", "bracketleft", "backslash", "bracketright", - "asciicircum", "underscore", "grave", "a", "b", - - # 70 - "c", "d", "e", "f", "g", - "h", "i", "j", "k", "l", - - # 80 - "m", "n", "o", "p", "q", - "r", "s", "t", "u", "v", - - # 90 - "w", "x", "y", "z", "braceleft", - "bar", "braceright", "asciitilde", "Adieresis", "Aring", - - # 100 - "Ccedilla", "Eacute", "Ntilde", "Odieresis", "Udieresis", - "aacute", "agrave", "acircumflex", "adieresis", "atilde", - - # 110 - "aring", "ccedilla", "eacute", "egrave", "ecircumflex", - "edieresis", "iacute", "igrave", "icircumflex", "idieresis", - - # 120 - "ntilde", "oacute", "ograve", "ocircumflex", "odieresis", - "otilde", "uacute", "ugrave", "ucircumflex", "udieresis", - - # 130 - "dagger", "degree", "cent", "sterling", "section", - "bullet", "paragraph", "germandbls", "registered", "copyright", - - # 140 - "trademark", "acute", "dieresis", "notequal", "AE", - "Oslash", "infinity", "plusminus", "lessequal", "greaterequal", - - # 150 - "yen", "mu", "partialdiff", "summation", "product", - "pi", "integral", "ordfeminine", "ordmasculine", "Omega", - - # 160 - "ae", "oslash", "questiondown", "exclamdown", "logicalnot", - "radical", "florin", "approxequal", "Delta", "guillemotleft", - - # 170 - "guillemotright", "ellipsis", "nonbreakingspace", "Agrave", "Atilde", - "Otilde", "OE", "oe", "endash", "emdash", - - # 180 - "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide", - "lozenge", "ydieresis", "Ydieresis", "fraction", "currency", - - # 190 - "guilsinglleft", "guilsinglright", "fi", "fl", "daggerdbl", - "periodcentered", "quotesinglbase", "quotedblbase", "perthousand", - "Acircumflex", - - # 200 - "Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute", - "Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex", - - # 210 - "apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave", - "dotlessi", "circumflex", "tilde", "macron", "breve", - - # 220 - "dotaccent", "ring", "cedilla", "hungarumlaut", "ogonek", - "caron", "Lslash", "lslash", "Scaron", "scaron", - - # 230 - "Zcaron", "zcaron", "brokenbar", "Eth", "eth", - "Yacute", "yacute", "Thorn", "thorn", "minus", - - # 240 - "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf", - "onequarter", "threequarters", "franc", "Gbreve", "gbreve", - - # 250 - "Idotaccent", "Scedilla", "scedilla", "Cacute", "cacute", - "Ccaron", "ccaron", "dcroat" -] - - -# the list of standard "SID" glyph names. For the official list, -# see Annex A of document at -# http://partners.adobe.com/asn/developer/pdfs/tn/5176.CFF.pdf -# -sid_standard_names = \ -[ - # 0 - ".notdef", "space", "exclam", "quotedbl", "numbersign", - "dollar", "percent", "ampersand", "quoteright", "parenleft", - - # 10 - "parenright", "asterisk", "plus", "comma", "hyphen", - "period", "slash", "zero", "one", "two", - - # 20 - "three", "four", "five", "six", "seven", - "eight", "nine", "colon", "semicolon", "less", - - # 30 - "equal", "greater", "question", "at", "A", - "B", "C", "D", "E", "F", - - # 40 - "G", "H", "I", "J", "K", - "L", "M", "N", "O", "P", - - # 50 - "Q", "R", "S", "T", "U", - "V", "W", "X", "Y", "Z", - - # 60 - "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", - "quoteleft", "a", "b", "c", "d", - - # 70 - "e", "f", "g", "h", "i", - "j", "k", "l", "m", "n", - - # 80 - "o", "p", "q", "r", "s", - "t", "u", "v", "w", "x", - - # 90 - "y", "z", "braceleft", "bar", "braceright", - "asciitilde", "exclamdown", "cent", "sterling", "fraction", - - # 100 - "yen", "florin", "section", "currency", "quotesingle", - "quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi", - - # 110 - "fl", "endash", "dagger", "daggerdbl", "periodcentered", - "paragraph", "bullet", "quotesinglbase", "quotedblbase", "quotedblright", - - # 120 - "guillemotright", "ellipsis", "perthousand", "questiondown", "grave", - "acute", "circumflex", "tilde", "macron", "breve", - - # 130 - "dotaccent", "dieresis", "ring", "cedilla", "hungarumlaut", - "ogonek", "caron", "emdash", "AE", "ordfeminine", - - # 140 - "Lslash", "Oslash", "OE", "ordmasculine", "ae", - "dotlessi", "lslash", "oslash", "oe", "germandbls", - - # 150 - "onesuperior", "logicalnot", "mu", "trademark", "Eth", - "onehalf", "plusminus", "Thorn", "onequarter", "divide", - - # 160 - "brokenbar", "degree", "thorn", "threequarters", "twosuperior", - "registered", "minus", "eth", "multiply", "threesuperior", - - # 170 - "copyright", "Aacute", "Acircumflex", "Adieresis", "Agrave", - "Aring", "Atilde", "Ccedilla", "Eacute", "Ecircumflex", - - # 180 - "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", - "Igrave", "Ntilde", "Oacute", "Ocircumflex", "Odieresis", - - # 190 - "Ograve", "Otilde", "Scaron", "Uacute", "Ucircumflex", - "Udieresis", "Ugrave", "Yacute", "Ydieresis", "Zcaron", - - # 200 - "aacute", "acircumflex", "adieresis", "agrave", "aring", - "atilde", "ccedilla", "eacute", "ecircumflex", "edieresis", - - # 210 - "egrave", "iacute", "icircumflex", "idieresis", "igrave", - "ntilde", "oacute", "ocircumflex", "odieresis", "ograve", - - # 220 - "otilde", "scaron", "uacute", "ucircumflex", "udieresis", - "ugrave", "yacute", "ydieresis", "zcaron", "exclamsmall", - - # 230 - "Hungarumlautsmall", "dollaroldstyle", "dollarsuperior", "ampersandsmall", - "Acutesmall", - "parenleftsuperior", "parenrightsuperior", "twodotenleader", - "onedotenleader", "zerooldstyle", - - # 240 - "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle", - "fiveoldstyle", - "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", - "commasuperior", - - # 250 - "threequartersemdash", "periodsuperior", "questionsmall", "asuperior", - "bsuperior", - "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior", - - # 260 - "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior", - "tsuperior", "ff", "ffi", "ffl", "parenleftinferior", - - # 270 - "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall", - "Asmall", - "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", - - # 280 - "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall", - "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall", - - # 290 - "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", - "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", - - # 300 - "colonmonetary", "onefitted", "rupiah", "Tildesmall", "exclamdownsmall", - "centoldstyle", "Lslashsmall", "Scaronsmall", "Zcaronsmall", - "Dieresissmall", - - # 310 - "Brevesmall", "Caronsmall", "Dotaccentsmall", "Macronsmall", "figuredash", - "hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall", - "questiondownsmall", - - # 320 - "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird", - "twothirds", "zerosuperior", "foursuperior", "fivesuperior", - "sixsuperior", - - # 330 - "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior", - "oneinferior", - "twoinferior", "threeinferior", "fourinferior", "fiveinferior", - "sixinferior", - - # 340 - "seveninferior", "eightinferior", "nineinferior", "centinferior", - "dollarinferior", - "periodinferior", "commainferior", "Agravesmall", "Aacutesmall", - "Acircumflexsmall", - - # 350 - "Atildesmall", "Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall", - "Egravesmall", "Eacutesmall", "Ecircumflexsmall", "Edieresissmall", - "Igravesmall", - - # 360 - "Iacutesmall", "Icircumflexsmall", "Idieresissmall", "Ethsmall", - "Ntildesmall", - "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall", - "Odieresissmall", - - # 370 - "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall", - "Ucircumflexsmall", - "Udieresissmall", "Yacutesmall", "Thornsmall", "Ydieresissmall", - "001.000", - - # 380 - "001.001", "001.002", "001.003", "Black", "Bold", - "Book", "Light", "Medium", "Regular", "Roman", - - # 390 - "Semibold" -] - - -# this table maps character code of the Adobe Standard Type 1 -# encoding to glyph indexes in the sid_standard_names table -# -t1_standard_encoding = \ -[ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, - - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 0, 111, 112, 113, - 114, 0, 115, 116, 117, 118, 119, 120, 121, 122, - 0, 123, 0, 124, 125, 126, 127, 128, 129, 130, - - 131, 0, 132, 133, 0, 134, 135, 136, 137, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 138, 0, 139, 0, 0, - 0, 0, 140, 141, 142, 143, 0, 0, 0, 0, - 0, 144, 0, 0, 0, 145, 0, 0, 146, 147, - - 148, 149, 0, 0, 0, 0 -] - - -# this table maps character code of the Adobe Expert Type 1 -# encoding to glyph indexes in the sid_standard_names table -# -t1_expert_encoding = \ -[ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 229, 230, 0, 231, 232, 233, 234, - 235, 236, 237, 238, 13, 14, 15, 99, 239, 240, - - 241, 242, 243, 244, 245, 246, 247, 248, 27, 28, - 249, 250, 251, 252, 0, 253, 254, 255, 256, 257, - 0, 0, 0, 258, 0, 0, 259, 260, 261, 262, - 0, 0, 263, 264, 265, 0, 266, 109, 110, 267, - 268, 269, 0, 270, 271, 272, 273, 274, 275, 276, - - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 303, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 304, 305, 306, 0, 0, 307, 308, 309, 310, - 311, 0, 312, 0, 0, 313, 0, 0, 314, 315, - 0, 0, 316, 317, 318, 0, 0, 0, 158, 155, - 163, 319, 320, 321, 322, 323, 324, 325, 0, 0, - - 326, 150, 164, 169, 327, 328, 329, 330, 331, 332, - 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, - - 373, 374, 375, 376, 377, 378 -] - - -# This data has been taken literally from the file `glyphlist.txt', -# version 1.2, 22 Oct 1998. It is available from -# -# http://partners.adobe.com/asn/developer/typeforum/unicodegn.html -# -adobe_glyph_list = """\ -0041;A;LATIN CAPITAL LETTER A -00C6;AE;LATIN CAPITAL LETTER AE -01FC;AEacute;LATIN CAPITAL LETTER AE WITH ACUTE -F7E6;AEsmall;LATIN SMALL CAPITAL LETTER AE -00C1;Aacute;LATIN CAPITAL LETTER A WITH ACUTE -F7E1;Aacutesmall;LATIN SMALL CAPITAL LETTER A WITH ACUTE -0102;Abreve;LATIN CAPITAL LETTER A WITH BREVE -00C2;Acircumflex;LATIN CAPITAL LETTER A WITH CIRCUMFLEX -F7E2;Acircumflexsmall;LATIN SMALL CAPITAL LETTER A WITH CIRCUMFLEX -F6C9;Acute;CAPITAL ACUTE ACCENT -F7B4;Acutesmall;SMALL CAPITAL ACUTE ACCENT -00C4;Adieresis;LATIN CAPITAL LETTER A WITH DIAERESIS -F7E4;Adieresissmall;LATIN SMALL CAPITAL LETTER A WITH DIAERESIS -00C0;Agrave;LATIN CAPITAL LETTER A WITH GRAVE -F7E0;Agravesmall;LATIN SMALL CAPITAL LETTER A WITH GRAVE -0391;Alpha;GREEK CAPITAL LETTER ALPHA -0386;Alphatonos;GREEK CAPITAL LETTER ALPHA WITH TONOS -0100;Amacron;LATIN CAPITAL LETTER A WITH MACRON -0104;Aogonek;LATIN CAPITAL LETTER A WITH OGONEK -00C5;Aring;LATIN CAPITAL LETTER A WITH RING ABOVE -01FA;Aringacute;LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE -F7E5;Aringsmall;LATIN SMALL CAPITAL LETTER A WITH RING ABOVE -F761;Asmall;LATIN SMALL CAPITAL LETTER A -00C3;Atilde;LATIN CAPITAL LETTER A WITH TILDE -F7E3;Atildesmall;LATIN SMALL CAPITAL LETTER A WITH TILDE -0042;B;LATIN CAPITAL LETTER B -0392;Beta;GREEK CAPITAL LETTER BETA -F6F4;Brevesmall;SMALL CAPITAL BREVE -F762;Bsmall;LATIN SMALL CAPITAL LETTER B -0043;C;LATIN CAPITAL LETTER C -0106;Cacute;LATIN CAPITAL LETTER C WITH ACUTE -F6CA;Caron;CAPITAL CARON -F6F5;Caronsmall;SMALL CAPITAL CARON -010C;Ccaron;LATIN CAPITAL LETTER C WITH CARON -00C7;Ccedilla;LATIN CAPITAL LETTER C WITH CEDILLA -F7E7;Ccedillasmall;LATIN SMALL CAPITAL LETTER C WITH CEDILLA -0108;Ccircumflex;LATIN CAPITAL LETTER C WITH CIRCUMFLEX -010A;Cdotaccent;LATIN CAPITAL LETTER C WITH DOT ABOVE -F7B8;Cedillasmall;SMALL CAPITAL CEDILLA -03A7;Chi;GREEK CAPITAL LETTER CHI -F6F6;Circumflexsmall;SMALL CAPITAL MODIFIER LETTER CIRCUMFLEX ACCENT -F763;Csmall;LATIN SMALL CAPITAL LETTER C -0044;D;LATIN CAPITAL LETTER D -010E;Dcaron;LATIN CAPITAL LETTER D WITH CARON -0110;Dcroat;LATIN CAPITAL LETTER D WITH STROKE -2206;Delta;INCREMENT -0394;Delta;GREEK CAPITAL LETTER DELTA;Duplicate -F6CB;Dieresis;CAPITAL DIAERESIS -F6CC;DieresisAcute;CAPITAL DIAERESIS ACUTE ACCENT -F6CD;DieresisGrave;CAPITAL DIAERESIS GRAVE ACCENT -F7A8;Dieresissmall;SMALL CAPITAL DIAERESIS -F6F7;Dotaccentsmall;SMALL CAPITAL DOT ABOVE -F764;Dsmall;LATIN SMALL CAPITAL LETTER D -0045;E;LATIN CAPITAL LETTER E -00C9;Eacute;LATIN CAPITAL LETTER E WITH ACUTE -F7E9;Eacutesmall;LATIN SMALL CAPITAL LETTER E WITH ACUTE -0114;Ebreve;LATIN CAPITAL LETTER E WITH BREVE -011A;Ecaron;LATIN CAPITAL LETTER E WITH CARON -00CA;Ecircumflex;LATIN CAPITAL LETTER E WITH CIRCUMFLEX -F7EA;Ecircumflexsmall;LATIN SMALL CAPITAL LETTER E WITH CIRCUMFLEX -00CB;Edieresis;LATIN CAPITAL LETTER E WITH DIAERESIS -F7EB;Edieresissmall;LATIN SMALL CAPITAL LETTER E WITH DIAERESIS -0116;Edotaccent;LATIN CAPITAL LETTER E WITH DOT ABOVE -00C8;Egrave;LATIN CAPITAL LETTER E WITH GRAVE -F7E8;Egravesmall;LATIN SMALL CAPITAL LETTER E WITH GRAVE -0112;Emacron;LATIN CAPITAL LETTER E WITH MACRON -014A;Eng;LATIN CAPITAL LETTER ENG -0118;Eogonek;LATIN CAPITAL LETTER E WITH OGONEK -0395;Epsilon;GREEK CAPITAL LETTER EPSILON -0388;Epsilontonos;GREEK CAPITAL LETTER EPSILON WITH TONOS -F765;Esmall;LATIN SMALL CAPITAL LETTER E -0397;Eta;GREEK CAPITAL LETTER ETA -0389;Etatonos;GREEK CAPITAL LETTER ETA WITH TONOS -00D0;Eth;LATIN CAPITAL LETTER ETH -F7F0;Ethsmall;LATIN SMALL CAPITAL LETTER ETH -20AC;Euro;EURO SIGN -0046;F;LATIN CAPITAL LETTER F -F766;Fsmall;LATIN SMALL CAPITAL LETTER F -0047;G;LATIN CAPITAL LETTER G -0393;Gamma;GREEK CAPITAL LETTER GAMMA -011E;Gbreve;LATIN CAPITAL LETTER G WITH BREVE -01E6;Gcaron;LATIN CAPITAL LETTER G WITH CARON -011C;Gcircumflex;LATIN CAPITAL LETTER G WITH CIRCUMFLEX -0122;Gcommaaccent;LATIN CAPITAL LETTER G WITH CEDILLA -0120;Gdotaccent;LATIN CAPITAL LETTER G WITH DOT ABOVE -F6CE;Grave;CAPITAL GRAVE ACCENT -F760;Gravesmall;SMALL CAPITAL GRAVE ACCENT -F767;Gsmall;LATIN SMALL CAPITAL LETTER G -0048;H;LATIN CAPITAL LETTER H -25CF;H18533;BLACK CIRCLE -25AA;H18543;BLACK SMALL SQUARE -25AB;H18551;WHITE SMALL SQUARE -25A1;H22073;WHITE SQUARE -0126;Hbar;LATIN CAPITAL LETTER H WITH STROKE -0124;Hcircumflex;LATIN CAPITAL LETTER H WITH CIRCUMFLEX -F768;Hsmall;LATIN SMALL CAPITAL LETTER H -F6CF;Hungarumlaut;CAPITAL DOUBLE ACUTE ACCENT -F6F8;Hungarumlautsmall;SMALL CAPITAL DOUBLE ACUTE ACCENT -0049;I;LATIN CAPITAL LETTER I -0132;IJ;LATIN CAPITAL LIGATURE IJ -00CD;Iacute;LATIN CAPITAL LETTER I WITH ACUTE -F7ED;Iacutesmall;LATIN SMALL CAPITAL LETTER I WITH ACUTE -012C;Ibreve;LATIN CAPITAL LETTER I WITH BREVE -00CE;Icircumflex;LATIN CAPITAL LETTER I WITH CIRCUMFLEX -F7EE;Icircumflexsmall;LATIN SMALL CAPITAL LETTER I WITH CIRCUMFLEX -00CF;Idieresis;LATIN CAPITAL LETTER I WITH DIAERESIS -F7EF;Idieresissmall;LATIN SMALL CAPITAL LETTER I WITH DIAERESIS -0130;Idotaccent;LATIN CAPITAL LETTER I WITH DOT ABOVE -2111;Ifraktur;BLACK-LETTER CAPITAL I -00CC;Igrave;LATIN CAPITAL LETTER I WITH GRAVE -F7EC;Igravesmall;LATIN SMALL CAPITAL LETTER I WITH GRAVE -012A;Imacron;LATIN CAPITAL LETTER I WITH MACRON -012E;Iogonek;LATIN CAPITAL LETTER I WITH OGONEK -0399;Iota;GREEK CAPITAL LETTER IOTA -03AA;Iotadieresis;GREEK CAPITAL LETTER IOTA WITH DIALYTIKA -038A;Iotatonos;GREEK CAPITAL LETTER IOTA WITH TONOS -F769;Ismall;LATIN SMALL CAPITAL LETTER I -0128;Itilde;LATIN CAPITAL LETTER I WITH TILDE -004A;J;LATIN CAPITAL LETTER J -0134;Jcircumflex;LATIN CAPITAL LETTER J WITH CIRCUMFLEX -F76A;Jsmall;LATIN SMALL CAPITAL LETTER J -004B;K;LATIN CAPITAL LETTER K -039A;Kappa;GREEK CAPITAL LETTER KAPPA -0136;Kcommaaccent;LATIN CAPITAL LETTER K WITH CEDILLA -F76B;Ksmall;LATIN SMALL CAPITAL LETTER K -004C;L;LATIN CAPITAL LETTER L -F6BF;LL;LATIN CAPITAL LETTER LL -0139;Lacute;LATIN CAPITAL LETTER L WITH ACUTE -039B;Lambda;GREEK CAPITAL LETTER LAMDA -013D;Lcaron;LATIN CAPITAL LETTER L WITH CARON -013B;Lcommaaccent;LATIN CAPITAL LETTER L WITH CEDILLA -013F;Ldot;LATIN CAPITAL LETTER L WITH MIDDLE DOT -0141;Lslash;LATIN CAPITAL LETTER L WITH STROKE -F6F9;Lslashsmall;LATIN SMALL CAPITAL LETTER L WITH STROKE -F76C;Lsmall;LATIN SMALL CAPITAL LETTER L -004D;M;LATIN CAPITAL LETTER M -F6D0;Macron;CAPITAL MACRON -F7AF;Macronsmall;SMALL CAPITAL MACRON -F76D;Msmall;LATIN SMALL CAPITAL LETTER M -039C;Mu;GREEK CAPITAL LETTER MU -004E;N;LATIN CAPITAL LETTER N -0143;Nacute;LATIN CAPITAL LETTER N WITH ACUTE -0147;Ncaron;LATIN CAPITAL LETTER N WITH CARON -0145;Ncommaaccent;LATIN CAPITAL LETTER N WITH CEDILLA -F76E;Nsmall;LATIN SMALL CAPITAL LETTER N -00D1;Ntilde;LATIN CAPITAL LETTER N WITH TILDE -F7F1;Ntildesmall;LATIN SMALL CAPITAL LETTER N WITH TILDE -039D;Nu;GREEK CAPITAL LETTER NU -004F;O;LATIN CAPITAL LETTER O -0152;OE;LATIN CAPITAL LIGATURE OE -F6FA;OEsmall;LATIN SMALL CAPITAL LIGATURE OE -00D3;Oacute;LATIN CAPITAL LETTER O WITH ACUTE -F7F3;Oacutesmall;LATIN SMALL CAPITAL LETTER O WITH ACUTE -014E;Obreve;LATIN CAPITAL LETTER O WITH BREVE -00D4;Ocircumflex;LATIN CAPITAL LETTER O WITH CIRCUMFLEX -F7F4;Ocircumflexsmall;LATIN SMALL CAPITAL LETTER O WITH CIRCUMFLEX -00D6;Odieresis;LATIN CAPITAL LETTER O WITH DIAERESIS -F7F6;Odieresissmall;LATIN SMALL CAPITAL LETTER O WITH DIAERESIS -F6FB;Ogoneksmall;SMALL CAPITAL OGONEK -00D2;Ograve;LATIN CAPITAL LETTER O WITH GRAVE -F7F2;Ogravesmall;LATIN SMALL CAPITAL LETTER O WITH GRAVE -01A0;Ohorn;LATIN CAPITAL LETTER O WITH HORN -0150;Ohungarumlaut;LATIN CAPITAL LETTER O WITH DOUBLE ACUTE -014C;Omacron;LATIN CAPITAL LETTER O WITH MACRON -2126;Omega;OHM SIGN -03A9;Omega;GREEK CAPITAL LETTER OMEGA;Duplicate -038F;Omegatonos;GREEK CAPITAL LETTER OMEGA WITH TONOS -039F;Omicron;GREEK CAPITAL LETTER OMICRON -038C;Omicrontonos;GREEK CAPITAL LETTER OMICRON WITH TONOS -00D8;Oslash;LATIN CAPITAL LETTER O WITH STROKE -01FE;Oslashacute;LATIN CAPITAL LETTER O WITH STROKE AND ACUTE -F7F8;Oslashsmall;LATIN SMALL CAPITAL LETTER O WITH STROKE -F76F;Osmall;LATIN SMALL CAPITAL LETTER O -00D5;Otilde;LATIN CAPITAL LETTER O WITH TILDE -F7F5;Otildesmall;LATIN SMALL CAPITAL LETTER O WITH TILDE -0050;P;LATIN CAPITAL LETTER P -03A6;Phi;GREEK CAPITAL LETTER PHI -03A0;Pi;GREEK CAPITAL LETTER PI -03A8;Psi;GREEK CAPITAL LETTER PSI -F770;Psmall;LATIN SMALL CAPITAL LETTER P -0051;Q;LATIN CAPITAL LETTER Q -F771;Qsmall;LATIN SMALL CAPITAL LETTER Q -0052;R;LATIN CAPITAL LETTER R -0154;Racute;LATIN CAPITAL LETTER R WITH ACUTE -0158;Rcaron;LATIN CAPITAL LETTER R WITH CARON -0156;Rcommaaccent;LATIN CAPITAL LETTER R WITH CEDILLA -211C;Rfraktur;BLACK-LETTER CAPITAL R -03A1;Rho;GREEK CAPITAL LETTER RHO -F6FC;Ringsmall;SMALL CAPITAL RING ABOVE -F772;Rsmall;LATIN SMALL CAPITAL LETTER R -0053;S;LATIN CAPITAL LETTER S -250C;SF010000;BOX DRAWINGS LIGHT DOWN AND RIGHT -2514;SF020000;BOX DRAWINGS LIGHT UP AND RIGHT -2510;SF030000;BOX DRAWINGS LIGHT DOWN AND LEFT -2518;SF040000;BOX DRAWINGS LIGHT UP AND LEFT -253C;SF050000;BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL -252C;SF060000;BOX DRAWINGS LIGHT DOWN AND HORIZONTAL -2534;SF070000;BOX DRAWINGS LIGHT UP AND HORIZONTAL -251C;SF080000;BOX DRAWINGS LIGHT VERTICAL AND RIGHT -2524;SF090000;BOX DRAWINGS LIGHT VERTICAL AND LEFT -2500;SF100000;BOX DRAWINGS LIGHT HORIZONTAL -2502;SF110000;BOX DRAWINGS LIGHT VERTICAL -2561;SF190000;BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE -2562;SF200000;BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE -2556;SF210000;BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE -2555;SF220000;BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE -2563;SF230000;BOX DRAWINGS DOUBLE VERTICAL AND LEFT -2551;SF240000;BOX DRAWINGS DOUBLE VERTICAL -2557;SF250000;BOX DRAWINGS DOUBLE DOWN AND LEFT -255D;SF260000;BOX DRAWINGS DOUBLE UP AND LEFT -255C;SF270000;BOX DRAWINGS UP DOUBLE AND LEFT SINGLE -255B;SF280000;BOX DRAWINGS UP SINGLE AND LEFT DOUBLE -255E;SF360000;BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE -255F;SF370000;BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE -255A;SF380000;BOX DRAWINGS DOUBLE UP AND RIGHT -2554;SF390000;BOX DRAWINGS DOUBLE DOWN AND RIGHT -2569;SF400000;BOX DRAWINGS DOUBLE UP AND HORIZONTAL -2566;SF410000;BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL -2560;SF420000;BOX DRAWINGS DOUBLE VERTICAL AND RIGHT -2550;SF430000;BOX DRAWINGS DOUBLE HORIZONTAL -256C;SF440000;BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL -2567;SF450000;BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE -2568;SF460000;BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE -2564;SF470000;BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE -2565;SF480000;BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE -2559;SF490000;BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE -2558;SF500000;BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE -2552;SF510000;BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE -2553;SF520000;BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE -256B;SF530000;BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE -256A;SF540000;BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE -015A;Sacute;LATIN CAPITAL LETTER S WITH ACUTE -0160;Scaron;LATIN CAPITAL LETTER S WITH CARON -F6FD;Scaronsmall;LATIN SMALL CAPITAL LETTER S WITH CARON -015E;Scedilla;LATIN CAPITAL LETTER S WITH CEDILLA -F6C1;Scedilla;LATIN CAPITAL LETTER S WITH CEDILLA;Duplicate -015C;Scircumflex;LATIN CAPITAL LETTER S WITH CIRCUMFLEX -0218;Scommaaccent;LATIN CAPITAL LETTER S WITH COMMA BELOW -03A3;Sigma;GREEK CAPITAL LETTER SIGMA -F773;Ssmall;LATIN SMALL CAPITAL LETTER S -0054;T;LATIN CAPITAL LETTER T -03A4;Tau;GREEK CAPITAL LETTER TAU -0166;Tbar;LATIN CAPITAL LETTER T WITH STROKE -0164;Tcaron;LATIN CAPITAL LETTER T WITH CARON -0162;Tcommaaccent;LATIN CAPITAL LETTER T WITH CEDILLA -021A;Tcommaaccent;LATIN CAPITAL LETTER T WITH COMMA BELOW;Duplicate -0398;Theta;GREEK CAPITAL LETTER THETA -00DE;Thorn;LATIN CAPITAL LETTER THORN -F7FE;Thornsmall;LATIN SMALL CAPITAL LETTER THORN -F6FE;Tildesmall;SMALL CAPITAL SMALL TILDE -F774;Tsmall;LATIN SMALL CAPITAL LETTER T -0055;U;LATIN CAPITAL LETTER U -00DA;Uacute;LATIN CAPITAL LETTER U WITH ACUTE -F7FA;Uacutesmall;LATIN SMALL CAPITAL LETTER U WITH ACUTE -016C;Ubreve;LATIN CAPITAL LETTER U WITH BREVE -00DB;Ucircumflex;LATIN CAPITAL LETTER U WITH CIRCUMFLEX -F7FB;Ucircumflexsmall;LATIN SMALL CAPITAL LETTER U WITH CIRCUMFLEX -00DC;Udieresis;LATIN CAPITAL LETTER U WITH DIAERESIS -F7FC;Udieresissmall;LATIN SMALL CAPITAL LETTER U WITH DIAERESIS -00D9;Ugrave;LATIN CAPITAL LETTER U WITH GRAVE -F7F9;Ugravesmall;LATIN SMALL CAPITAL LETTER U WITH GRAVE -01AF;Uhorn;LATIN CAPITAL LETTER U WITH HORN -0170;Uhungarumlaut;LATIN CAPITAL LETTER U WITH DOUBLE ACUTE -016A;Umacron;LATIN CAPITAL LETTER U WITH MACRON -0172;Uogonek;LATIN CAPITAL LETTER U WITH OGONEK -03A5;Upsilon;GREEK CAPITAL LETTER UPSILON -03D2;Upsilon1;GREEK UPSILON WITH HOOK SYMBOL -03AB;Upsilondieresis;GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA -038E;Upsilontonos;GREEK CAPITAL LETTER UPSILON WITH TONOS -016E;Uring;LATIN CAPITAL LETTER U WITH RING ABOVE -F775;Usmall;LATIN SMALL CAPITAL LETTER U -0168;Utilde;LATIN CAPITAL LETTER U WITH TILDE -0056;V;LATIN CAPITAL LETTER V -F776;Vsmall;LATIN SMALL CAPITAL LETTER V -0057;W;LATIN CAPITAL LETTER W -1E82;Wacute;LATIN CAPITAL LETTER W WITH ACUTE -0174;Wcircumflex;LATIN CAPITAL LETTER W WITH CIRCUMFLEX -1E84;Wdieresis;LATIN CAPITAL LETTER W WITH DIAERESIS -1E80;Wgrave;LATIN CAPITAL LETTER W WITH GRAVE -F777;Wsmall;LATIN SMALL CAPITAL LETTER W -0058;X;LATIN CAPITAL LETTER X -039E;Xi;GREEK CAPITAL LETTER XI -F778;Xsmall;LATIN SMALL CAPITAL LETTER X -0059;Y;LATIN CAPITAL LETTER Y -00DD;Yacute;LATIN CAPITAL LETTER Y WITH ACUTE -F7FD;Yacutesmall;LATIN SMALL CAPITAL LETTER Y WITH ACUTE -0176;Ycircumflex;LATIN CAPITAL LETTER Y WITH CIRCUMFLEX -0178;Ydieresis;LATIN CAPITAL LETTER Y WITH DIAERESIS -F7FF;Ydieresissmall;LATIN SMALL CAPITAL LETTER Y WITH DIAERESIS -1EF2;Ygrave;LATIN CAPITAL LETTER Y WITH GRAVE -F779;Ysmall;LATIN SMALL CAPITAL LETTER Y -005A;Z;LATIN CAPITAL LETTER Z -0179;Zacute;LATIN CAPITAL LETTER Z WITH ACUTE -017D;Zcaron;LATIN CAPITAL LETTER Z WITH CARON -F6FF;Zcaronsmall;LATIN SMALL CAPITAL LETTER Z WITH CARON -017B;Zdotaccent;LATIN CAPITAL LETTER Z WITH DOT ABOVE -0396;Zeta;GREEK CAPITAL LETTER ZETA -F77A;Zsmall;LATIN SMALL CAPITAL LETTER Z -0061;a;LATIN SMALL LETTER A -00E1;aacute;LATIN SMALL LETTER A WITH ACUTE -0103;abreve;LATIN SMALL LETTER A WITH BREVE -00E2;acircumflex;LATIN SMALL LETTER A WITH CIRCUMFLEX -00B4;acute;ACUTE ACCENT -0301;acutecomb;COMBINING ACUTE ACCENT -00E4;adieresis;LATIN SMALL LETTER A WITH DIAERESIS -00E6;ae;LATIN SMALL LETTER AE -01FD;aeacute;LATIN SMALL LETTER AE WITH ACUTE -2015;afii00208;HORIZONTAL BAR -0410;afii10017;CYRILLIC CAPITAL LETTER A -0411;afii10018;CYRILLIC CAPITAL LETTER BE -0412;afii10019;CYRILLIC CAPITAL LETTER VE -0413;afii10020;CYRILLIC CAPITAL LETTER GHE -0414;afii10021;CYRILLIC CAPITAL LETTER DE -0415;afii10022;CYRILLIC CAPITAL LETTER IE -0401;afii10023;CYRILLIC CAPITAL LETTER IO -0416;afii10024;CYRILLIC CAPITAL LETTER ZHE -0417;afii10025;CYRILLIC CAPITAL LETTER ZE -0418;afii10026;CYRILLIC CAPITAL LETTER I -0419;afii10027;CYRILLIC CAPITAL LETTER SHORT I -041A;afii10028;CYRILLIC CAPITAL LETTER KA -041B;afii10029;CYRILLIC CAPITAL LETTER EL -041C;afii10030;CYRILLIC CAPITAL LETTER EM -041D;afii10031;CYRILLIC CAPITAL LETTER EN -041E;afii10032;CYRILLIC CAPITAL LETTER O -041F;afii10033;CYRILLIC CAPITAL LETTER PE -0420;afii10034;CYRILLIC CAPITAL LETTER ER -0421;afii10035;CYRILLIC CAPITAL LETTER ES -0422;afii10036;CYRILLIC CAPITAL LETTER TE -0423;afii10037;CYRILLIC CAPITAL LETTER U -0424;afii10038;CYRILLIC CAPITAL LETTER EF -0425;afii10039;CYRILLIC CAPITAL LETTER HA -0426;afii10040;CYRILLIC CAPITAL LETTER TSE -0427;afii10041;CYRILLIC CAPITAL LETTER CHE -0428;afii10042;CYRILLIC CAPITAL LETTER SHA -0429;afii10043;CYRILLIC CAPITAL LETTER SHCHA -042A;afii10044;CYRILLIC CAPITAL LETTER HARD SIGN -042B;afii10045;CYRILLIC CAPITAL LETTER YERU -042C;afii10046;CYRILLIC CAPITAL LETTER SOFT SIGN -042D;afii10047;CYRILLIC CAPITAL LETTER E -042E;afii10048;CYRILLIC CAPITAL LETTER YU -042F;afii10049;CYRILLIC CAPITAL LETTER YA -0490;afii10050;CYRILLIC CAPITAL LETTER GHE WITH UPTURN -0402;afii10051;CYRILLIC CAPITAL LETTER DJE -0403;afii10052;CYRILLIC CAPITAL LETTER GJE -0404;afii10053;CYRILLIC CAPITAL LETTER UKRAINIAN IE -0405;afii10054;CYRILLIC CAPITAL LETTER DZE -0406;afii10055;CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I -0407;afii10056;CYRILLIC CAPITAL LETTER YI -0408;afii10057;CYRILLIC CAPITAL LETTER JE -0409;afii10058;CYRILLIC CAPITAL LETTER LJE -040A;afii10059;CYRILLIC CAPITAL LETTER NJE -040B;afii10060;CYRILLIC CAPITAL LETTER TSHE -040C;afii10061;CYRILLIC CAPITAL LETTER KJE -040E;afii10062;CYRILLIC CAPITAL LETTER SHORT U -F6C4;afii10063;CYRILLIC SMALL LETTER GHE VARIANT -F6C5;afii10064;CYRILLIC SMALL LETTER BE VARIANT -0430;afii10065;CYRILLIC SMALL LETTER A -0431;afii10066;CYRILLIC SMALL LETTER BE -0432;afii10067;CYRILLIC SMALL LETTER VE -0433;afii10068;CYRILLIC SMALL LETTER GHE -0434;afii10069;CYRILLIC SMALL LETTER DE -0435;afii10070;CYRILLIC SMALL LETTER IE -0451;afii10071;CYRILLIC SMALL LETTER IO -0436;afii10072;CYRILLIC SMALL LETTER ZHE -0437;afii10073;CYRILLIC SMALL LETTER ZE -0438;afii10074;CYRILLIC SMALL LETTER I -0439;afii10075;CYRILLIC SMALL LETTER SHORT I -043A;afii10076;CYRILLIC SMALL LETTER KA -043B;afii10077;CYRILLIC SMALL LETTER EL -043C;afii10078;CYRILLIC SMALL LETTER EM -043D;afii10079;CYRILLIC SMALL LETTER EN -043E;afii10080;CYRILLIC SMALL LETTER O -043F;afii10081;CYRILLIC SMALL LETTER PE -0440;afii10082;CYRILLIC SMALL LETTER ER -0441;afii10083;CYRILLIC SMALL LETTER ES -0442;afii10084;CYRILLIC SMALL LETTER TE -0443;afii10085;CYRILLIC SMALL LETTER U -0444;afii10086;CYRILLIC SMALL LETTER EF -0445;afii10087;CYRILLIC SMALL LETTER HA -0446;afii10088;CYRILLIC SMALL LETTER TSE -0447;afii10089;CYRILLIC SMALL LETTER CHE -0448;afii10090;CYRILLIC SMALL LETTER SHA -0449;afii10091;CYRILLIC SMALL LETTER SHCHA -044A;afii10092;CYRILLIC SMALL LETTER HARD SIGN -044B;afii10093;CYRILLIC SMALL LETTER YERU -044C;afii10094;CYRILLIC SMALL LETTER SOFT SIGN -044D;afii10095;CYRILLIC SMALL LETTER E -044E;afii10096;CYRILLIC SMALL LETTER YU -044F;afii10097;CYRILLIC SMALL LETTER YA -0491;afii10098;CYRILLIC SMALL LETTER GHE WITH UPTURN -0452;afii10099;CYRILLIC SMALL LETTER DJE -0453;afii10100;CYRILLIC SMALL LETTER GJE -0454;afii10101;CYRILLIC SMALL LETTER UKRAINIAN IE -0455;afii10102;CYRILLIC SMALL LETTER DZE -0456;afii10103;CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I -0457;afii10104;CYRILLIC SMALL LETTER YI -0458;afii10105;CYRILLIC SMALL LETTER JE -0459;afii10106;CYRILLIC SMALL LETTER LJE -045A;afii10107;CYRILLIC SMALL LETTER NJE -045B;afii10108;CYRILLIC SMALL LETTER TSHE -045C;afii10109;CYRILLIC SMALL LETTER KJE -045E;afii10110;CYRILLIC SMALL LETTER SHORT U -040F;afii10145;CYRILLIC CAPITAL LETTER DZHE -0462;afii10146;CYRILLIC CAPITAL LETTER YAT -0472;afii10147;CYRILLIC CAPITAL LETTER FITA -0474;afii10148;CYRILLIC CAPITAL LETTER IZHITSA -F6C6;afii10192;CYRILLIC SMALL LETTER DE VARIANT -045F;afii10193;CYRILLIC SMALL LETTER DZHE -0463;afii10194;CYRILLIC SMALL LETTER YAT -0473;afii10195;CYRILLIC SMALL LETTER FITA -0475;afii10196;CYRILLIC SMALL LETTER IZHITSA -F6C7;afii10831;CYRILLIC SMALL LETTER PE VARIANT -F6C8;afii10832;CYRILLIC SMALL LETTER TE VARIANT -04D9;afii10846;CYRILLIC SMALL LETTER SCHWA -200E;afii299;LEFT-TO-RIGHT MARK -200F;afii300;RIGHT-TO-LEFT MARK -200D;afii301;ZERO WIDTH JOINER -066A;afii57381;ARABIC PERCENT SIGN -060C;afii57388;ARABIC COMMA -0660;afii57392;ARABIC-INDIC DIGIT ZERO -0661;afii57393;ARABIC-INDIC DIGIT ONE -0662;afii57394;ARABIC-INDIC DIGIT TWO -0663;afii57395;ARABIC-INDIC DIGIT THREE -0664;afii57396;ARABIC-INDIC DIGIT FOUR -0665;afii57397;ARABIC-INDIC DIGIT FIVE -0666;afii57398;ARABIC-INDIC DIGIT SIX -0667;afii57399;ARABIC-INDIC DIGIT SEVEN -0668;afii57400;ARABIC-INDIC DIGIT EIGHT -0669;afii57401;ARABIC-INDIC DIGIT NINE -061B;afii57403;ARABIC SEMICOLON -061F;afii57407;ARABIC QUESTION MARK -0621;afii57409;ARABIC LETTER HAMZA -0622;afii57410;ARABIC LETTER ALEF WITH MADDA ABOVE -0623;afii57411;ARABIC LETTER ALEF WITH HAMZA ABOVE -0624;afii57412;ARABIC LETTER WAW WITH HAMZA ABOVE -0625;afii57413;ARABIC LETTER ALEF WITH HAMZA BELOW -0626;afii57414;ARABIC LETTER YEH WITH HAMZA ABOVE -0627;afii57415;ARABIC LETTER ALEF -0628;afii57416;ARABIC LETTER BEH -0629;afii57417;ARABIC LETTER TEH MARBUTA -062A;afii57418;ARABIC LETTER TEH -062B;afii57419;ARABIC LETTER THEH -062C;afii57420;ARABIC LETTER JEEM -062D;afii57421;ARABIC LETTER HAH -062E;afii57422;ARABIC LETTER KHAH -062F;afii57423;ARABIC LETTER DAL -0630;afii57424;ARABIC LETTER THAL -0631;afii57425;ARABIC LETTER REH -0632;afii57426;ARABIC LETTER ZAIN -0633;afii57427;ARABIC LETTER SEEN -0634;afii57428;ARABIC LETTER SHEEN -0635;afii57429;ARABIC LETTER SAD -0636;afii57430;ARABIC LETTER DAD -0637;afii57431;ARABIC LETTER TAH -0638;afii57432;ARABIC LETTER ZAH -0639;afii57433;ARABIC LETTER AIN -063A;afii57434;ARABIC LETTER GHAIN -0640;afii57440;ARABIC TATWEEL -0641;afii57441;ARABIC LETTER FEH -0642;afii57442;ARABIC LETTER QAF -0643;afii57443;ARABIC LETTER KAF -0644;afii57444;ARABIC LETTER LAM -0645;afii57445;ARABIC LETTER MEEM -0646;afii57446;ARABIC LETTER NOON -0648;afii57448;ARABIC LETTER WAW -0649;afii57449;ARABIC LETTER ALEF MAKSURA -064A;afii57450;ARABIC LETTER YEH -064B;afii57451;ARABIC FATHATAN -064C;afii57452;ARABIC DAMMATAN -064D;afii57453;ARABIC KASRATAN -064E;afii57454;ARABIC FATHA -064F;afii57455;ARABIC DAMMA -0650;afii57456;ARABIC KASRA -0651;afii57457;ARABIC SHADDA -0652;afii57458;ARABIC SUKUN -0647;afii57470;ARABIC LETTER HEH -06A4;afii57505;ARABIC LETTER VEH -067E;afii57506;ARABIC LETTER PEH -0686;afii57507;ARABIC LETTER TCHEH -0698;afii57508;ARABIC LETTER JEH -06AF;afii57509;ARABIC LETTER GAF -0679;afii57511;ARABIC LETTER TTEH -0688;afii57512;ARABIC LETTER DDAL -0691;afii57513;ARABIC LETTER RREH -06BA;afii57514;ARABIC LETTER NOON GHUNNA -06D2;afii57519;ARABIC LETTER YEH BARREE -06D5;afii57534;ARABIC LETTER AE -20AA;afii57636;NEW SHEQEL SIGN -05BE;afii57645;HEBREW PUNCTUATION MAQAF -05C3;afii57658;HEBREW PUNCTUATION SOF PASUQ -05D0;afii57664;HEBREW LETTER ALEF -05D1;afii57665;HEBREW LETTER BET -05D2;afii57666;HEBREW LETTER GIMEL -05D3;afii57667;HEBREW LETTER DALET -05D4;afii57668;HEBREW LETTER HE -05D5;afii57669;HEBREW LETTER VAV -05D6;afii57670;HEBREW LETTER ZAYIN -05D7;afii57671;HEBREW LETTER HET -05D8;afii57672;HEBREW LETTER TET -05D9;afii57673;HEBREW LETTER YOD -05DA;afii57674;HEBREW LETTER FINAL KAF -05DB;afii57675;HEBREW LETTER KAF -05DC;afii57676;HEBREW LETTER LAMED -05DD;afii57677;HEBREW LETTER FINAL MEM -05DE;afii57678;HEBREW LETTER MEM -05DF;afii57679;HEBREW LETTER FINAL NUN -05E0;afii57680;HEBREW LETTER NUN -05E1;afii57681;HEBREW LETTER SAMEKH -05E2;afii57682;HEBREW LETTER AYIN -05E3;afii57683;HEBREW LETTER FINAL PE -05E4;afii57684;HEBREW LETTER PE -05E5;afii57685;HEBREW LETTER FINAL TSADI -05E6;afii57686;HEBREW LETTER TSADI -05E7;afii57687;HEBREW LETTER QOF -05E8;afii57688;HEBREW LETTER RESH -05E9;afii57689;HEBREW LETTER SHIN -05EA;afii57690;HEBREW LETTER TAV -FB2A;afii57694;HEBREW LETTER SHIN WITH SHIN DOT -FB2B;afii57695;HEBREW LETTER SHIN WITH SIN DOT -FB4B;afii57700;HEBREW LETTER VAV WITH HOLAM -FB1F;afii57705;HEBREW LIGATURE YIDDISH YOD YOD PATAH -05F0;afii57716;HEBREW LIGATURE YIDDISH DOUBLE VAV -05F1;afii57717;HEBREW LIGATURE YIDDISH VAV YOD -05F2;afii57718;HEBREW LIGATURE YIDDISH DOUBLE YOD -FB35;afii57723;HEBREW LETTER VAV WITH DAGESH -05B4;afii57793;HEBREW POINT HIRIQ -05B5;afii57794;HEBREW POINT TSERE -05B6;afii57795;HEBREW POINT SEGOL -05BB;afii57796;HEBREW POINT QUBUTS -05B8;afii57797;HEBREW POINT QAMATS -05B7;afii57798;HEBREW POINT PATAH -05B0;afii57799;HEBREW POINT SHEVA -05B2;afii57800;HEBREW POINT HATAF PATAH -05B1;afii57801;HEBREW POINT HATAF SEGOL -05B3;afii57802;HEBREW POINT HATAF QAMATS -05C2;afii57803;HEBREW POINT SIN DOT -05C1;afii57804;HEBREW POINT SHIN DOT -05B9;afii57806;HEBREW POINT HOLAM -05BC;afii57807;HEBREW POINT DAGESH OR MAPIQ -05BD;afii57839;HEBREW POINT METEG -05BF;afii57841;HEBREW POINT RAFE -05C0;afii57842;HEBREW PUNCTUATION PASEQ -02BC;afii57929;MODIFIER LETTER APOSTROPHE -2105;afii61248;CARE OF -2113;afii61289;SCRIPT SMALL L -2116;afii61352;NUMERO SIGN -202C;afii61573;POP DIRECTIONAL FORMATTING -202D;afii61574;LEFT-TO-RIGHT OVERRIDE -202E;afii61575;RIGHT-TO-LEFT OVERRIDE -200C;afii61664;ZERO WIDTH NON-JOINER -066D;afii63167;ARABIC FIVE POINTED STAR -02BD;afii64937;MODIFIER LETTER REVERSED COMMA -00E0;agrave;LATIN SMALL LETTER A WITH GRAVE -2135;aleph;ALEF SYMBOL -03B1;alpha;GREEK SMALL LETTER ALPHA -03AC;alphatonos;GREEK SMALL LETTER ALPHA WITH TONOS -0101;amacron;LATIN SMALL LETTER A WITH MACRON -0026;ampersand;AMPERSAND -F726;ampersandsmall;SMALL CAPITAL AMPERSAND -2220;angle;ANGLE -2329;angleleft;LEFT-POINTING ANGLE BRACKET -232A;angleright;RIGHT-POINTING ANGLE BRACKET -0387;anoteleia;GREEK ANO TELEIA -0105;aogonek;LATIN SMALL LETTER A WITH OGONEK -2248;approxequal;ALMOST EQUAL TO -00E5;aring;LATIN SMALL LETTER A WITH RING ABOVE -01FB;aringacute;LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE -2194;arrowboth;LEFT RIGHT ARROW -21D4;arrowdblboth;LEFT RIGHT DOUBLE ARROW -21D3;arrowdbldown;DOWNWARDS DOUBLE ARROW -21D0;arrowdblleft;LEFTWARDS DOUBLE ARROW -21D2;arrowdblright;RIGHTWARDS DOUBLE ARROW -21D1;arrowdblup;UPWARDS DOUBLE ARROW -2193;arrowdown;DOWNWARDS ARROW -F8E7;arrowhorizex;HORIZONTAL ARROW EXTENDER -2190;arrowleft;LEFTWARDS ARROW -2192;arrowright;RIGHTWARDS ARROW -2191;arrowup;UPWARDS ARROW -2195;arrowupdn;UP DOWN ARROW -21A8;arrowupdnbse;UP DOWN ARROW WITH BASE -F8E6;arrowvertex;VERTICAL ARROW EXTENDER -005E;asciicircum;CIRCUMFLEX ACCENT -007E;asciitilde;TILDE -002A;asterisk;ASTERISK -2217;asteriskmath;ASTERISK OPERATOR -F6E9;asuperior;SUPERSCRIPT LATIN SMALL LETTER A -0040;at;COMMERCIAL AT -00E3;atilde;LATIN SMALL LETTER A WITH TILDE -0062;b;LATIN SMALL LETTER B -005C;backslash;REVERSE SOLIDUS -007C;bar;VERTICAL LINE -03B2;beta;GREEK SMALL LETTER BETA -2588;block;FULL BLOCK -F8F4;braceex;CURLY BRACKET EXTENDER -007B;braceleft;LEFT CURLY BRACKET -F8F3;braceleftbt;LEFT CURLY BRACKET BOTTOM -F8F2;braceleftmid;LEFT CURLY BRACKET MID -F8F1;bracelefttp;LEFT CURLY BRACKET TOP -007D;braceright;RIGHT CURLY BRACKET -F8FE;bracerightbt;RIGHT CURLY BRACKET BOTTOM -F8FD;bracerightmid;RIGHT CURLY BRACKET MID -F8FC;bracerighttp;RIGHT CURLY BRACKET TOP -005B;bracketleft;LEFT SQUARE BRACKET -F8F0;bracketleftbt;LEFT SQUARE BRACKET BOTTOM -F8EF;bracketleftex;LEFT SQUARE BRACKET EXTENDER -F8EE;bracketlefttp;LEFT SQUARE BRACKET TOP -005D;bracketright;RIGHT SQUARE BRACKET -F8FB;bracketrightbt;RIGHT SQUARE BRACKET BOTTOM -F8FA;bracketrightex;RIGHT SQUARE BRACKET EXTENDER -F8F9;bracketrighttp;RIGHT SQUARE BRACKET TOP -02D8;breve;BREVE -00A6;brokenbar;BROKEN BAR -F6EA;bsuperior;SUPERSCRIPT LATIN SMALL LETTER B -2022;bullet;BULLET -0063;c;LATIN SMALL LETTER C -0107;cacute;LATIN SMALL LETTER C WITH ACUTE -02C7;caron;CARON -21B5;carriagereturn;DOWNWARDS ARROW WITH CORNER LEFTWARDS -010D;ccaron;LATIN SMALL LETTER C WITH CARON -00E7;ccedilla;LATIN SMALL LETTER C WITH CEDILLA -0109;ccircumflex;LATIN SMALL LETTER C WITH CIRCUMFLEX -010B;cdotaccent;LATIN SMALL LETTER C WITH DOT ABOVE -00B8;cedilla;CEDILLA -00A2;cent;CENT SIGN -F6DF;centinferior;SUBSCRIPT CENT SIGN -F7A2;centoldstyle;OLDSTYLE CENT SIGN -F6E0;centsuperior;SUPERSCRIPT CENT SIGN -03C7;chi;GREEK SMALL LETTER CHI -25CB;circle;WHITE CIRCLE -2297;circlemultiply;CIRCLED TIMES -2295;circleplus;CIRCLED PLUS -02C6;circumflex;MODIFIER LETTER CIRCUMFLEX ACCENT -2663;club;BLACK CLUB SUIT -003A;colon;COLON -20A1;colonmonetary;COLON SIGN -002C;comma;COMMA -F6C3;commaaccent;COMMA BELOW -F6E1;commainferior;SUBSCRIPT COMMA -F6E2;commasuperior;SUPERSCRIPT COMMA -2245;congruent;APPROXIMATELY EQUAL TO -00A9;copyright;COPYRIGHT SIGN -F8E9;copyrightsans;COPYRIGHT SIGN SANS SERIF -F6D9;copyrightserif;COPYRIGHT SIGN SERIF -00A4;currency;CURRENCY SIGN -F6D1;cyrBreve;CAPITAL CYRILLIC BREVE -F6D2;cyrFlex;CAPITAL CYRILLIC CIRCUMFLEX -F6D4;cyrbreve;CYRILLIC BREVE -F6D5;cyrflex;CYRILLIC CIRCUMFLEX -0064;d;LATIN SMALL LETTER D -2020;dagger;DAGGER -2021;daggerdbl;DOUBLE DAGGER -F6D3;dblGrave;CAPITAL DOUBLE GRAVE ACCENT -F6D6;dblgrave;DOUBLE GRAVE ACCENT -010F;dcaron;LATIN SMALL LETTER D WITH CARON -0111;dcroat;LATIN SMALL LETTER D WITH STROKE -00B0;degree;DEGREE SIGN -03B4;delta;GREEK SMALL LETTER DELTA -2666;diamond;BLACK DIAMOND SUIT -00A8;dieresis;DIAERESIS -F6D7;dieresisacute;DIAERESIS ACUTE ACCENT -F6D8;dieresisgrave;DIAERESIS GRAVE ACCENT -0385;dieresistonos;GREEK DIALYTIKA TONOS -00F7;divide;DIVISION SIGN -2593;dkshade;DARK SHADE -2584;dnblock;LOWER HALF BLOCK -0024;dollar;DOLLAR SIGN -F6E3;dollarinferior;SUBSCRIPT DOLLAR SIGN -F724;dollaroldstyle;OLDSTYLE DOLLAR SIGN -F6E4;dollarsuperior;SUPERSCRIPT DOLLAR SIGN -20AB;dong;DONG SIGN -02D9;dotaccent;DOT ABOVE -0323;dotbelowcomb;COMBINING DOT BELOW -0131;dotlessi;LATIN SMALL LETTER DOTLESS I -F6BE;dotlessj;LATIN SMALL LETTER DOTLESS J -22C5;dotmath;DOT OPERATOR -F6EB;dsuperior;SUPERSCRIPT LATIN SMALL LETTER D -0065;e;LATIN SMALL LETTER E -00E9;eacute;LATIN SMALL LETTER E WITH ACUTE -0115;ebreve;LATIN SMALL LETTER E WITH BREVE -011B;ecaron;LATIN SMALL LETTER E WITH CARON -00EA;ecircumflex;LATIN SMALL LETTER E WITH CIRCUMFLEX -00EB;edieresis;LATIN SMALL LETTER E WITH DIAERESIS -0117;edotaccent;LATIN SMALL LETTER E WITH DOT ABOVE -00E8;egrave;LATIN SMALL LETTER E WITH GRAVE -0038;eight;DIGIT EIGHT -2088;eightinferior;SUBSCRIPT EIGHT -F738;eightoldstyle;OLDSTYLE DIGIT EIGHT -2078;eightsuperior;SUPERSCRIPT EIGHT -2208;element;ELEMENT OF -2026;ellipsis;HORIZONTAL ELLIPSIS -0113;emacron;LATIN SMALL LETTER E WITH MACRON -2014;emdash;EM DASH -2205;emptyset;EMPTY SET -2013;endash;EN DASH -014B;eng;LATIN SMALL LETTER ENG -0119;eogonek;LATIN SMALL LETTER E WITH OGONEK -03B5;epsilon;GREEK SMALL LETTER EPSILON -03AD;epsilontonos;GREEK SMALL LETTER EPSILON WITH TONOS -003D;equal;EQUALS SIGN -2261;equivalence;IDENTICAL TO -212E;estimated;ESTIMATED SYMBOL -F6EC;esuperior;SUPERSCRIPT LATIN SMALL LETTER E -03B7;eta;GREEK SMALL LETTER ETA -03AE;etatonos;GREEK SMALL LETTER ETA WITH TONOS -00F0;eth;LATIN SMALL LETTER ETH -0021;exclam;EXCLAMATION MARK -203C;exclamdbl;DOUBLE EXCLAMATION MARK -00A1;exclamdown;INVERTED EXCLAMATION MARK -F7A1;exclamdownsmall;SMALL CAPITAL INVERTED EXCLAMATION MARK -F721;exclamsmall;SMALL CAPITAL EXCLAMATION MARK -2203;existential;THERE EXISTS -0066;f;LATIN SMALL LETTER F -2640;female;FEMALE SIGN -FB00;ff;LATIN SMALL LIGATURE FF -FB03;ffi;LATIN SMALL LIGATURE FFI -FB04;ffl;LATIN SMALL LIGATURE FFL -FB01;fi;LATIN SMALL LIGATURE FI -2012;figuredash;FIGURE DASH -25A0;filledbox;BLACK SQUARE -25AC;filledrect;BLACK RECTANGLE -0035;five;DIGIT FIVE -215D;fiveeighths;VULGAR FRACTION FIVE EIGHTHS -2085;fiveinferior;SUBSCRIPT FIVE -F735;fiveoldstyle;OLDSTYLE DIGIT FIVE -2075;fivesuperior;SUPERSCRIPT FIVE -FB02;fl;LATIN SMALL LIGATURE FL -0192;florin;LATIN SMALL LETTER F WITH HOOK -0034;four;DIGIT FOUR -2084;fourinferior;SUBSCRIPT FOUR -F734;fouroldstyle;OLDSTYLE DIGIT FOUR -2074;foursuperior;SUPERSCRIPT FOUR -2044;fraction;FRACTION SLASH -2215;fraction;DIVISION SLASH;Duplicate -20A3;franc;FRENCH FRANC SIGN -0067;g;LATIN SMALL LETTER G -03B3;gamma;GREEK SMALL LETTER GAMMA -011F;gbreve;LATIN SMALL LETTER G WITH BREVE -01E7;gcaron;LATIN SMALL LETTER G WITH CARON -011D;gcircumflex;LATIN SMALL LETTER G WITH CIRCUMFLEX -0123;gcommaaccent;LATIN SMALL LETTER G WITH CEDILLA -0121;gdotaccent;LATIN SMALL LETTER G WITH DOT ABOVE -00DF;germandbls;LATIN SMALL LETTER SHARP S -2207;gradient;NABLA -0060;grave;GRAVE ACCENT -0300;gravecomb;COMBINING GRAVE ACCENT -003E;greater;GREATER-THAN SIGN -2265;greaterequal;GREATER-THAN OR EQUAL TO -00AB;guillemotleft;LEFT-POINTING DOUBLE ANGLE QUOTATION MARK -00BB;guillemotright;RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK -2039;guilsinglleft;SINGLE LEFT-POINTING ANGLE QUOTATION MARK -203A;guilsinglright;SINGLE RIGHT-POINTING ANGLE QUOTATION MARK -0068;h;LATIN SMALL LETTER H -0127;hbar;LATIN SMALL LETTER H WITH STROKE -0125;hcircumflex;LATIN SMALL LETTER H WITH CIRCUMFLEX -2665;heart;BLACK HEART SUIT -0309;hookabovecomb;COMBINING HOOK ABOVE -2302;house;HOUSE -02DD;hungarumlaut;DOUBLE ACUTE ACCENT -002D;hyphen;HYPHEN-MINUS -00AD;hyphen;SOFT HYPHEN;Duplicate -F6E5;hypheninferior;SUBSCRIPT HYPHEN-MINUS -F6E6;hyphensuperior;SUPERSCRIPT HYPHEN-MINUS -0069;i;LATIN SMALL LETTER I -00ED;iacute;LATIN SMALL LETTER I WITH ACUTE -012D;ibreve;LATIN SMALL LETTER I WITH BREVE -00EE;icircumflex;LATIN SMALL LETTER I WITH CIRCUMFLEX -00EF;idieresis;LATIN SMALL LETTER I WITH DIAERESIS -00EC;igrave;LATIN SMALL LETTER I WITH GRAVE -0133;ij;LATIN SMALL LIGATURE IJ -012B;imacron;LATIN SMALL LETTER I WITH MACRON -221E;infinity;INFINITY -222B;integral;INTEGRAL -2321;integralbt;BOTTOM HALF INTEGRAL -F8F5;integralex;INTEGRAL EXTENDER -2320;integraltp;TOP HALF INTEGRAL -2229;intersection;INTERSECTION -25D8;invbullet;INVERSE BULLET -25D9;invcircle;INVERSE WHITE CIRCLE -263B;invsmileface;BLACK SMILING FACE -012F;iogonek;LATIN SMALL LETTER I WITH OGONEK -03B9;iota;GREEK SMALL LETTER IOTA -03CA;iotadieresis;GREEK SMALL LETTER IOTA WITH DIALYTIKA -0390;iotadieresistonos;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS -03AF;iotatonos;GREEK SMALL LETTER IOTA WITH TONOS -F6ED;isuperior;SUPERSCRIPT LATIN SMALL LETTER I -0129;itilde;LATIN SMALL LETTER I WITH TILDE -006A;j;LATIN SMALL LETTER J -0135;jcircumflex;LATIN SMALL LETTER J WITH CIRCUMFLEX -006B;k;LATIN SMALL LETTER K -03BA;kappa;GREEK SMALL LETTER KAPPA -0137;kcommaaccent;LATIN SMALL LETTER K WITH CEDILLA -0138;kgreenlandic;LATIN SMALL LETTER KRA -006C;l;LATIN SMALL LETTER L -013A;lacute;LATIN SMALL LETTER L WITH ACUTE -03BB;lambda;GREEK SMALL LETTER LAMDA -013E;lcaron;LATIN SMALL LETTER L WITH CARON -013C;lcommaaccent;LATIN SMALL LETTER L WITH CEDILLA -0140;ldot;LATIN SMALL LETTER L WITH MIDDLE DOT -003C;less;LESS-THAN SIGN -2264;lessequal;LESS-THAN OR EQUAL TO -258C;lfblock;LEFT HALF BLOCK -20A4;lira;LIRA SIGN -F6C0;ll;LATIN SMALL LETTER LL -2227;logicaland;LOGICAL AND -00AC;logicalnot;NOT SIGN -2228;logicalor;LOGICAL OR -017F;longs;LATIN SMALL LETTER LONG S -25CA;lozenge;LOZENGE -0142;lslash;LATIN SMALL LETTER L WITH STROKE -F6EE;lsuperior;SUPERSCRIPT LATIN SMALL LETTER L -2591;ltshade;LIGHT SHADE -006D;m;LATIN SMALL LETTER M -00AF;macron;MACRON -02C9;macron;MODIFIER LETTER MACRON;Duplicate -2642;male;MALE SIGN -2212;minus;MINUS SIGN -2032;minute;PRIME -F6EF;msuperior;SUPERSCRIPT LATIN SMALL LETTER M -00B5;mu;MICRO SIGN -03BC;mu;GREEK SMALL LETTER MU;Duplicate -00D7;multiply;MULTIPLICATION SIGN -266A;musicalnote;EIGHTH NOTE -266B;musicalnotedbl;BEAMED EIGHTH NOTES -006E;n;LATIN SMALL LETTER N -0144;nacute;LATIN SMALL LETTER N WITH ACUTE -0149;napostrophe;LATIN SMALL LETTER N PRECEDED BY APOSTROPHE -0148;ncaron;LATIN SMALL LETTER N WITH CARON -0146;ncommaaccent;LATIN SMALL LETTER N WITH CEDILLA -0039;nine;DIGIT NINE -2089;nineinferior;SUBSCRIPT NINE -F739;nineoldstyle;OLDSTYLE DIGIT NINE -2079;ninesuperior;SUPERSCRIPT NINE -2209;notelement;NOT AN ELEMENT OF -2260;notequal;NOT EQUAL TO -2284;notsubset;NOT A SUBSET OF -207F;nsuperior;SUPERSCRIPT LATIN SMALL LETTER N -00F1;ntilde;LATIN SMALL LETTER N WITH TILDE -03BD;nu;GREEK SMALL LETTER NU -0023;numbersign;NUMBER SIGN -006F;o;LATIN SMALL LETTER O -00F3;oacute;LATIN SMALL LETTER O WITH ACUTE -014F;obreve;LATIN SMALL LETTER O WITH BREVE -00F4;ocircumflex;LATIN SMALL LETTER O WITH CIRCUMFLEX -00F6;odieresis;LATIN SMALL LETTER O WITH DIAERESIS -0153;oe;LATIN SMALL LIGATURE OE -02DB;ogonek;OGONEK -00F2;ograve;LATIN SMALL LETTER O WITH GRAVE -01A1;ohorn;LATIN SMALL LETTER O WITH HORN -0151;ohungarumlaut;LATIN SMALL LETTER O WITH DOUBLE ACUTE -014D;omacron;LATIN SMALL LETTER O WITH MACRON -03C9;omega;GREEK SMALL LETTER OMEGA -03D6;omega1;GREEK PI SYMBOL -03CE;omegatonos;GREEK SMALL LETTER OMEGA WITH TONOS -03BF;omicron;GREEK SMALL LETTER OMICRON -03CC;omicrontonos;GREEK SMALL LETTER OMICRON WITH TONOS -0031;one;DIGIT ONE -2024;onedotenleader;ONE DOT LEADER -215B;oneeighth;VULGAR FRACTION ONE EIGHTH -F6DC;onefitted;PROPORTIONAL DIGIT ONE -00BD;onehalf;VULGAR FRACTION ONE HALF -2081;oneinferior;SUBSCRIPT ONE -F731;oneoldstyle;OLDSTYLE DIGIT ONE -00BC;onequarter;VULGAR FRACTION ONE QUARTER -00B9;onesuperior;SUPERSCRIPT ONE -2153;onethird;VULGAR FRACTION ONE THIRD -25E6;openbullet;WHITE BULLET -00AA;ordfeminine;FEMININE ORDINAL INDICATOR -00BA;ordmasculine;MASCULINE ORDINAL INDICATOR -221F;orthogonal;RIGHT ANGLE -00F8;oslash;LATIN SMALL LETTER O WITH STROKE -01FF;oslashacute;LATIN SMALL LETTER O WITH STROKE AND ACUTE -F6F0;osuperior;SUPERSCRIPT LATIN SMALL LETTER O -00F5;otilde;LATIN SMALL LETTER O WITH TILDE -0070;p;LATIN SMALL LETTER P -00B6;paragraph;PILCROW SIGN -0028;parenleft;LEFT PARENTHESIS -F8ED;parenleftbt;LEFT PAREN BOTTOM -F8EC;parenleftex;LEFT PAREN EXTENDER -208D;parenleftinferior;SUBSCRIPT LEFT PARENTHESIS -207D;parenleftsuperior;SUPERSCRIPT LEFT PARENTHESIS -F8EB;parenlefttp;LEFT PAREN TOP -0029;parenright;RIGHT PARENTHESIS -F8F8;parenrightbt;RIGHT PAREN BOTTOM -F8F7;parenrightex;RIGHT PAREN EXTENDER -208E;parenrightinferior;SUBSCRIPT RIGHT PARENTHESIS -207E;parenrightsuperior;SUPERSCRIPT RIGHT PARENTHESIS -F8F6;parenrighttp;RIGHT PAREN TOP -2202;partialdiff;PARTIAL DIFFERENTIAL -0025;percent;PERCENT SIGN -002E;period;FULL STOP -00B7;periodcentered;MIDDLE DOT -2219;periodcentered;BULLET OPERATOR;Duplicate -F6E7;periodinferior;SUBSCRIPT FULL STOP -F6E8;periodsuperior;SUPERSCRIPT FULL STOP -22A5;perpendicular;UP TACK -2030;perthousand;PER MILLE SIGN -20A7;peseta;PESETA SIGN -03C6;phi;GREEK SMALL LETTER PHI -03D5;phi1;GREEK PHI SYMBOL -03C0;pi;GREEK SMALL LETTER PI -002B;plus;PLUS SIGN -00B1;plusminus;PLUS-MINUS SIGN -211E;prescription;PRESCRIPTION TAKE -220F;product;N-ARY PRODUCT -2282;propersubset;SUBSET OF -2283;propersuperset;SUPERSET OF -221D;proportional;PROPORTIONAL TO -03C8;psi;GREEK SMALL LETTER PSI -0071;q;LATIN SMALL LETTER Q -003F;question;QUESTION MARK -00BF;questiondown;INVERTED QUESTION MARK -F7BF;questiondownsmall;SMALL CAPITAL INVERTED QUESTION MARK -F73F;questionsmall;SMALL CAPITAL QUESTION MARK -0022;quotedbl;QUOTATION MARK -201E;quotedblbase;DOUBLE LOW-9 QUOTATION MARK -201C;quotedblleft;LEFT DOUBLE QUOTATION MARK -201D;quotedblright;RIGHT DOUBLE QUOTATION MARK -2018;quoteleft;LEFT SINGLE QUOTATION MARK -201B;quotereversed;SINGLE HIGH-REVERSED-9 QUOTATION MARK -2019;quoteright;RIGHT SINGLE QUOTATION MARK -201A;quotesinglbase;SINGLE LOW-9 QUOTATION MARK -0027;quotesingle;APOSTROPHE -0072;r;LATIN SMALL LETTER R -0155;racute;LATIN SMALL LETTER R WITH ACUTE -221A;radical;SQUARE ROOT -F8E5;radicalex;RADICAL EXTENDER -0159;rcaron;LATIN SMALL LETTER R WITH CARON -0157;rcommaaccent;LATIN SMALL LETTER R WITH CEDILLA -2286;reflexsubset;SUBSET OF OR EQUAL TO -2287;reflexsuperset;SUPERSET OF OR EQUAL TO -00AE;registered;REGISTERED SIGN -F8E8;registersans;REGISTERED SIGN SANS SERIF -F6DA;registerserif;REGISTERED SIGN SERIF -2310;revlogicalnot;REVERSED NOT SIGN -03C1;rho;GREEK SMALL LETTER RHO -02DA;ring;RING ABOVE -F6F1;rsuperior;SUPERSCRIPT LATIN SMALL LETTER R -2590;rtblock;RIGHT HALF BLOCK -F6DD;rupiah;RUPIAH SIGN -0073;s;LATIN SMALL LETTER S -015B;sacute;LATIN SMALL LETTER S WITH ACUTE -0161;scaron;LATIN SMALL LETTER S WITH CARON -015F;scedilla;LATIN SMALL LETTER S WITH CEDILLA -F6C2;scedilla;LATIN SMALL LETTER S WITH CEDILLA;Duplicate -015D;scircumflex;LATIN SMALL LETTER S WITH CIRCUMFLEX -0219;scommaaccent;LATIN SMALL LETTER S WITH COMMA BELOW -2033;second;DOUBLE PRIME -00A7;section;SECTION SIGN -003B;semicolon;SEMICOLON -0037;seven;DIGIT SEVEN -215E;seveneighths;VULGAR FRACTION SEVEN EIGHTHS -2087;seveninferior;SUBSCRIPT SEVEN -F737;sevenoldstyle;OLDSTYLE DIGIT SEVEN -2077;sevensuperior;SUPERSCRIPT SEVEN -2592;shade;MEDIUM SHADE -03C3;sigma;GREEK SMALL LETTER SIGMA -03C2;sigma1;GREEK SMALL LETTER FINAL SIGMA -223C;similar;TILDE OPERATOR -0036;six;DIGIT SIX -2086;sixinferior;SUBSCRIPT SIX -F736;sixoldstyle;OLDSTYLE DIGIT SIX -2076;sixsuperior;SUPERSCRIPT SIX -002F;slash;SOLIDUS -263A;smileface;WHITE SMILING FACE -0020;space;SPACE -00A0;space;NO-BREAK SPACE;Duplicate -2660;spade;BLACK SPADE SUIT -F6F2;ssuperior;SUPERSCRIPT LATIN SMALL LETTER S -00A3;sterling;POUND SIGN -220B;suchthat;CONTAINS AS MEMBER -2211;summation;N-ARY SUMMATION -263C;sun;WHITE SUN WITH RAYS -0074;t;LATIN SMALL LETTER T -03C4;tau;GREEK SMALL LETTER TAU -0167;tbar;LATIN SMALL LETTER T WITH STROKE -0165;tcaron;LATIN SMALL LETTER T WITH CARON -0163;tcommaaccent;LATIN SMALL LETTER T WITH CEDILLA -021B;tcommaaccent;LATIN SMALL LETTER T WITH COMMA BELOW;Duplicate -2234;therefore;THEREFORE -03B8;theta;GREEK SMALL LETTER THETA -03D1;theta1;GREEK THETA SYMBOL -00FE;thorn;LATIN SMALL LETTER THORN -0033;three;DIGIT THREE -215C;threeeighths;VULGAR FRACTION THREE EIGHTHS -2083;threeinferior;SUBSCRIPT THREE -F733;threeoldstyle;OLDSTYLE DIGIT THREE -00BE;threequarters;VULGAR FRACTION THREE QUARTERS -F6DE;threequartersemdash;THREE QUARTERS EM DASH -00B3;threesuperior;SUPERSCRIPT THREE -02DC;tilde;SMALL TILDE -0303;tildecomb;COMBINING TILDE -0384;tonos;GREEK TONOS -2122;trademark;TRADE MARK SIGN -F8EA;trademarksans;TRADE MARK SIGN SANS SERIF -F6DB;trademarkserif;TRADE MARK SIGN SERIF -25BC;triagdn;BLACK DOWN-POINTING TRIANGLE -25C4;triaglf;BLACK LEFT-POINTING POINTER -25BA;triagrt;BLACK RIGHT-POINTING POINTER -25B2;triagup;BLACK UP-POINTING TRIANGLE -F6F3;tsuperior;SUPERSCRIPT LATIN SMALL LETTER T -0032;two;DIGIT TWO -2025;twodotenleader;TWO DOT LEADER -2082;twoinferior;SUBSCRIPT TWO -F732;twooldstyle;OLDSTYLE DIGIT TWO -00B2;twosuperior;SUPERSCRIPT TWO -2154;twothirds;VULGAR FRACTION TWO THIRDS -0075;u;LATIN SMALL LETTER U -00FA;uacute;LATIN SMALL LETTER U WITH ACUTE -016D;ubreve;LATIN SMALL LETTER U WITH BREVE -00FB;ucircumflex;LATIN SMALL LETTER U WITH CIRCUMFLEX -00FC;udieresis;LATIN SMALL LETTER U WITH DIAERESIS -00F9;ugrave;LATIN SMALL LETTER U WITH GRAVE -01B0;uhorn;LATIN SMALL LETTER U WITH HORN -0171;uhungarumlaut;LATIN SMALL LETTER U WITH DOUBLE ACUTE -016B;umacron;LATIN SMALL LETTER U WITH MACRON -005F;underscore;LOW LINE -2017;underscoredbl;DOUBLE LOW LINE -222A;union;UNION -2200;universal;FOR ALL -0173;uogonek;LATIN SMALL LETTER U WITH OGONEK -2580;upblock;UPPER HALF BLOCK -03C5;upsilon;GREEK SMALL LETTER UPSILON -03CB;upsilondieresis;GREEK SMALL LETTER UPSILON WITH DIALYTIKA -03B0;upsilondieresistonos;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS -03CD;upsilontonos;GREEK SMALL LETTER UPSILON WITH TONOS -016F;uring;LATIN SMALL LETTER U WITH RING ABOVE -0169;utilde;LATIN SMALL LETTER U WITH TILDE -0076;v;LATIN SMALL LETTER V -0077;w;LATIN SMALL LETTER W -1E83;wacute;LATIN SMALL LETTER W WITH ACUTE -0175;wcircumflex;LATIN SMALL LETTER W WITH CIRCUMFLEX -1E85;wdieresis;LATIN SMALL LETTER W WITH DIAERESIS -2118;weierstrass;SCRIPT CAPITAL P -1E81;wgrave;LATIN SMALL LETTER W WITH GRAVE -0078;x;LATIN SMALL LETTER X -03BE;xi;GREEK SMALL LETTER XI -0079;y;LATIN SMALL LETTER Y -00FD;yacute;LATIN SMALL LETTER Y WITH ACUTE -0177;ycircumflex;LATIN SMALL LETTER Y WITH CIRCUMFLEX -00FF;ydieresis;LATIN SMALL LETTER Y WITH DIAERESIS -00A5;yen;YEN SIGN -1EF3;ygrave;LATIN SMALL LETTER Y WITH GRAVE -007A;z;LATIN SMALL LETTER Z -017A;zacute;LATIN SMALL LETTER Z WITH ACUTE -017E;zcaron;LATIN SMALL LETTER Z WITH CARON -017C;zdotaccent;LATIN SMALL LETTER Z WITH DOT ABOVE -0030;zero;DIGIT ZERO -2080;zeroinferior;SUBSCRIPT ZERO -F730;zerooldstyle;OLDSTYLE DIGIT ZERO -2070;zerosuperior;SUPERSCRIPT ZERO -03B6;zeta;GREEK SMALL LETTER ZETA -""" - - -t1_bias = 0 -glyph_list = [] - - -def adobe_glyph_names(): - """return the list of glyph names from the adobe list""" - - lines = string.split( adobe_glyph_list, '\n' ) - glyphs = [] - - for line in lines: - if line: - fields = string.split( line, ';' ) -# print fields[0] + ' - ' + fields[1] - glyphs.append( fields[1] ) - - return glyphs - - -def adobe_glyph_values(): - """return the list of glyph names and their unicode values""" - - lines = string.split( adobe_glyph_list, '\n' ) - glyphs = [] - values = [] - - for line in lines: - if line: - fields = string.split( line, ';' ) -# print fields[0] + ' - ' + fields[1] - glyphs.append( fields[1] ) - values.append( fields[0] ) - - return glyphs, values - - -def filter_glyph_names( alist, filter ): - """filter 'alist' by taking _out_ all glyph names that are in 'filter'""" - - count = 0 - extras = [] - - for name in alist: - try: - filtered_index = filter.index( name ) - except: - extras.append( name ) - - return extras - - -def dump_mac_indices( file, all_glyphs ): - write = file.write - - write( " static const unsigned short mac_standard_names[" + \ - repr( len( mac_standard_names ) + 1 ) + "] =\n" ) - write( " {\n" ) - - for name in mac_standard_names: - write( " " + repr( all_glyphs.index( name ) ) + ",\n" ) - - write( " 0\n" ) - write( " };\n" ) - write( "\n" ) - write( "\n" ) - - -def dump_glyph_list( file, base_list, adobe_list ): - write = file.write - - name_list = [] - - write( " static const char* const ps_glyph_names[] =\n" ) - write( " {\n" ) - - for name in base_list: - write( ' "' + name + '",\n' ) - name_list.append( name ) - - write( "\n" ) - write( "#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST\n" ) - write( "\n" ) - - for name in adobe_list: - write( ' "' + name + '",\n' ) - name_list.append( name ) - - write( "\n" ) - write( "#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */\n" ) - write( "\n" ) - write( " NULL\n" ) - write( " };\n" ) - write( "\n" ) - write( "\n" ) - - return name_list - - -def dump_unicode_values( file, sid_list, adobe_list ): - """build the glyph names to unicode values table""" - - write = file.write - - agl_names, agl_unicodes = adobe_glyph_values() - - write( "\n" ) - write( " static const unsigned short ps_names_to_unicode[" + \ - repr( len( sid_list ) + len( adobe_list ) + 1 ) + "] =\n" ) - write( " {\n" ) - - for name in sid_list: - try: - index = agl_names.index( name ) - write( " 0x" + agl_unicodes[index] + ",\n" ) - except: - write( " 0,\n" ) - - write( "\n" ) - write( "#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST\n" ) - write( "\n" ) - - for name in adobe_list: - try: - index = agl_names.index( name ) - write( " 0x" + agl_unicodes[index] + ",\n" ) - except: - write( " 0,\n" ) - - write( "\n" ) - write( "#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */\n" ) - write( " 0\n" ) - write( " };\n" ) - write( "\n" ) - write( "\n" ) - write( "\n" ) - - -def dump_encoding( file, encoding_name, encoding_list ): - """dumps a given encoding""" - - write = file.write - - write( " static const unsigned short " + encoding_name + "[" + \ - repr( len( encoding_list ) + 1 ) + "] =\n" ) - write( " {\n" ) - - for value in encoding_list: - write( " " + repr( value ) + ",\n" ) - write( " 0\n" ) - write( " };\n" ) - write( "\n" ) - write( "\n" ) - - -def main(): - """main program body""" - - if len( sys.argv ) != 2: - print __doc__ % sys.argv[0] - sys.exit( 1 ) - - file = open( sys.argv[1], "w\n" ) - write = file.write - - count_sid = len( sid_standard_names ) - - # 'mac_extras' contains the list of glyph names in the Macintosh standard - # encoding which are not in either the Adobe Glyph List or the SID - # Standard Names. - # - mac_extras = filter_glyph_names( mac_standard_names, adobe_glyph_names() ) - mac_extras = filter_glyph_names( mac_extras, sid_standard_names ) - - # 'base_list' contains the first names of our final glyph names table. - # It consists of the 'mac_extras' glyph names, followed by the SID - # Standard names. - # - mac_extras_count = len( mac_extras ) - t1_bias = mac_extras_count - base_list = mac_extras + sid_standard_names - - # 'adobe_list' contains the glyph names that are in the AGL, but not in - # the base_list; they will be placed after base_list glyph names in - # our final table. - # - adobe_list = filter_glyph_names( adobe_glyph_names(), base_list ) - adobe_count = len( adobe_list ) - - write( "/***************************************************************************/\n" ) - write( "/* */\n" ) - - write( "/* %-71s*/\n" % sys.argv[1] ) - - write( "/* */\n" ) - write( "/* PostScript glyph names (specification only). */\n" ) - write( "/* */\n" ) - write( "/* Copyright 2000-2001 by */\n" ) - write( "/* David Turner, Robert Wilhelm, and Werner Lemberg. */\n" ) - write( "/* */\n" ) - write( "/* This file is part of the FreeType project, and may only be used, */\n" ) - write( "/* modified, and distributed under the terms of the FreeType project */\n" ) - write( "/* license, LICENSE.TXT. By continuing to use, modify, or distribute */\n" ) - write( "/* this file you indicate that you have read the license and */\n" ) - write( "/* understand and accept it fully. */\n" ) - write( "/* */\n" ) - write( "/***************************************************************************/\n" ) - write( "\n" ) - write( "\n" ) - write( " /* this file has been generated automatically -- do not edit! */\n" ) - write( "\n" ) - write( "\n" ) - - # dump final glyph list (mac extras + sid standard names + AGL glyph names) - # - name_list = dump_glyph_list( file, base_list, adobe_list ) - - # dump t1_standard_list - write( " static const char* const * const sid_standard_names = " \ - + "ps_glyph_names + " + repr( t1_bias ) + ";\n" ) - write( "\n" ) - write( "\n" ) - - write( "#define NUM_SID_GLYPHS " + repr( len( sid_standard_names ) ) + "\n" ) - write( "\n" ) - write( "#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST\n" ) - write( "#define NUM_ADOBE_GLYPHS " + \ - repr( len( base_list ) + len( adobe_list ) - t1_bias ) + "\n" ) - write( "#else\n" ) - write( "#define NUM_ADOBE_GLYPHS " + \ - repr( len( base_list ) - t1_bias ) + "\n" ) - write( "#endif\n" ) - write( "\n" ) - write( "\n" ) - - # dump mac indices table - dump_mac_indices( file, name_list ) - - # dump unicode values table - dump_unicode_values( file, sid_standard_names, adobe_list ) - - dump_encoding( file, "t1_standard_encoding", t1_standard_encoding ) - dump_encoding( file, "t1_expert_encoding", t1_expert_encoding ) - - write( "/* END */\n" ) - - -# Now run the main routine -# -main() - - -# END +#!/usr/bin/env python +# + +# +# FreeType 2 glyph name builder +# + + +# Copyright 1996-2000, 2003 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. + + +"""\ + +usage: %s + + This very simple python script is used to generate the glyph names + tables defined in the PSNames module. + + Its single argument is the name of the header file to be created. +""" + + +import sys, string + + +# This table is used to name the glyphs according to the Macintosh +# specification. It is used by the TrueType Postscript names table. +# +# See http://fonts.apple.com/TTRefMan/RM06/Chap6post.html +# for the official list. +# +mac_standard_names = \ +[ + # 0 + ".notdef", ".null", "nonmarkingreturn", "space", "exclam", + "quotedbl", "numbersign", "dollar", "percent", "ampersand", + + # 10 + "quotesingle", "parenleft", "parenright", "asterisk", "plus", + "comma", "hyphen", "period", "slash", "zero", + + # 20 + "one", "two", "three", "four", "five", + "six", "seven", "eight", "nine", "colon", + + # 30 + "semicolon", "less", "equal", "greater", "question", + "at", "A", "B", "C", "D", + + # 40 + "E", "F", "G", "H", "I", + "J", "K", "L", "M", "N", + + # 50 + "O", "P", "Q", "R", "S", + "T", "U", "V", "W", "X", + + # 60 + "Y", "Z", "bracketleft", "backslash", "bracketright", + "asciicircum", "underscore", "grave", "a", "b", + + # 70 + "c", "d", "e", "f", "g", + "h", "i", "j", "k", "l", + + # 80 + "m", "n", "o", "p", "q", + "r", "s", "t", "u", "v", + + # 90 + "w", "x", "y", "z", "braceleft", + "bar", "braceright", "asciitilde", "Adieresis", "Aring", + + # 100 + "Ccedilla", "Eacute", "Ntilde", "Odieresis", "Udieresis", + "aacute", "agrave", "acircumflex", "adieresis", "atilde", + + # 110 + "aring", "ccedilla", "eacute", "egrave", "ecircumflex", + "edieresis", "iacute", "igrave", "icircumflex", "idieresis", + + # 120 + "ntilde", "oacute", "ograve", "ocircumflex", "odieresis", + "otilde", "uacute", "ugrave", "ucircumflex", "udieresis", + + # 130 + "dagger", "degree", "cent", "sterling", "section", + "bullet", "paragraph", "germandbls", "registered", "copyright", + + # 140 + "trademark", "acute", "dieresis", "notequal", "AE", + "Oslash", "infinity", "plusminus", "lessequal", "greaterequal", + + # 150 + "yen", "mu", "partialdiff", "summation", "product", + "pi", "integral", "ordfeminine", "ordmasculine", "Omega", + + # 160 + "ae", "oslash", "questiondown", "exclamdown", "logicalnot", + "radical", "florin", "approxequal", "Delta", "guillemotleft", + + # 170 + "guillemotright", "ellipsis", "nonbreakingspace", "Agrave", "Atilde", + "Otilde", "OE", "oe", "endash", "emdash", + + # 180 + "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide", + "lozenge", "ydieresis", "Ydieresis", "fraction", "currency", + + # 190 + "guilsinglleft", "guilsinglright", "fi", "fl", "daggerdbl", + "periodcentered", "quotesinglbase", "quotedblbase", "perthousand", + "Acircumflex", + + # 200 + "Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute", + "Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex", + + # 210 + "apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave", + "dotlessi", "circumflex", "tilde", "macron", "breve", + + # 220 + "dotaccent", "ring", "cedilla", "hungarumlaut", "ogonek", + "caron", "Lslash", "lslash", "Scaron", "scaron", + + # 230 + "Zcaron", "zcaron", "brokenbar", "Eth", "eth", + "Yacute", "yacute", "Thorn", "thorn", "minus", + + # 240 + "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf", + "onequarter", "threequarters", "franc", "Gbreve", "gbreve", + + # 250 + "Idotaccent", "Scedilla", "scedilla", "Cacute", "cacute", + "Ccaron", "ccaron", "dcroat" +] + + +# The list of standard "SID" glyph names. For the official list, +# see Annex A of document at +# http://partners.adobe.com/asn/developer/pdfs/tn/5176.CFF.pdf. +# +sid_standard_names = \ +[ + # 0 + ".notdef", "space", "exclam", "quotedbl", "numbersign", + "dollar", "percent", "ampersand", "quoteright", "parenleft", + + # 10 + "parenright", "asterisk", "plus", "comma", "hyphen", + "period", "slash", "zero", "one", "two", + + # 20 + "three", "four", "five", "six", "seven", + "eight", "nine", "colon", "semicolon", "less", + + # 30 + "equal", "greater", "question", "at", "A", + "B", "C", "D", "E", "F", + + # 40 + "G", "H", "I", "J", "K", + "L", "M", "N", "O", "P", + + # 50 + "Q", "R", "S", "T", "U", + "V", "W", "X", "Y", "Z", + + # 60 + "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", + "quoteleft", "a", "b", "c", "d", + + # 70 + "e", "f", "g", "h", "i", + "j", "k", "l", "m", "n", + + # 80 + "o", "p", "q", "r", "s", + "t", "u", "v", "w", "x", + + # 90 + "y", "z", "braceleft", "bar", "braceright", + "asciitilde", "exclamdown", "cent", "sterling", "fraction", + + # 100 + "yen", "florin", "section", "currency", "quotesingle", + "quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi", + + # 110 + "fl", "endash", "dagger", "daggerdbl", "periodcentered", + "paragraph", "bullet", "quotesinglbase", "quotedblbase", "quotedblright", + + # 120 + "guillemotright", "ellipsis", "perthousand", "questiondown", "grave", + "acute", "circumflex", "tilde", "macron", "breve", + + # 130 + "dotaccent", "dieresis", "ring", "cedilla", "hungarumlaut", + "ogonek", "caron", "emdash", "AE", "ordfeminine", + + # 140 + "Lslash", "Oslash", "OE", "ordmasculine", "ae", + "dotlessi", "lslash", "oslash", "oe", "germandbls", + + # 150 + "onesuperior", "logicalnot", "mu", "trademark", "Eth", + "onehalf", "plusminus", "Thorn", "onequarter", "divide", + + # 160 + "brokenbar", "degree", "thorn", "threequarters", "twosuperior", + "registered", "minus", "eth", "multiply", "threesuperior", + + # 170 + "copyright", "Aacute", "Acircumflex", "Adieresis", "Agrave", + "Aring", "Atilde", "Ccedilla", "Eacute", "Ecircumflex", + + # 180 + "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", + "Igrave", "Ntilde", "Oacute", "Ocircumflex", "Odieresis", + + # 190 + "Ograve", "Otilde", "Scaron", "Uacute", "Ucircumflex", + "Udieresis", "Ugrave", "Yacute", "Ydieresis", "Zcaron", + + # 200 + "aacute", "acircumflex", "adieresis", "agrave", "aring", + "atilde", "ccedilla", "eacute", "ecircumflex", "edieresis", + + # 210 + "egrave", "iacute", "icircumflex", "idieresis", "igrave", + "ntilde", "oacute", "ocircumflex", "odieresis", "ograve", + + # 220 + "otilde", "scaron", "uacute", "ucircumflex", "udieresis", + "ugrave", "yacute", "ydieresis", "zcaron", "exclamsmall", + + # 230 + "Hungarumlautsmall", "dollaroldstyle", "dollarsuperior", "ampersandsmall", + "Acutesmall", + "parenleftsuperior", "parenrightsuperior", "twodotenleader", + "onedotenleader", "zerooldstyle", + + # 240 + "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle", + "fiveoldstyle", + "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", + "commasuperior", + + # 250 + "threequartersemdash", "periodsuperior", "questionsmall", "asuperior", + "bsuperior", + "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior", + + # 260 + "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior", + "tsuperior", "ff", "ffi", "ffl", "parenleftinferior", + + # 270 + "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall", + "Asmall", + "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", + + # 280 + "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall", + "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall", + + # 290 + "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", + "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", + + # 300 + "colonmonetary", "onefitted", "rupiah", "Tildesmall", "exclamdownsmall", + "centoldstyle", "Lslashsmall", "Scaronsmall", "Zcaronsmall", + "Dieresissmall", + + # 310 + "Brevesmall", "Caronsmall", "Dotaccentsmall", "Macronsmall", "figuredash", + "hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall", + "questiondownsmall", + + # 320 + "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird", + "twothirds", "zerosuperior", "foursuperior", "fivesuperior", + "sixsuperior", + + # 330 + "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior", + "oneinferior", + "twoinferior", "threeinferior", "fourinferior", "fiveinferior", + "sixinferior", + + # 340 + "seveninferior", "eightinferior", "nineinferior", "centinferior", + "dollarinferior", + "periodinferior", "commainferior", "Agravesmall", "Aacutesmall", + "Acircumflexsmall", + + # 350 + "Atildesmall", "Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall", + "Egravesmall", "Eacutesmall", "Ecircumflexsmall", "Edieresissmall", + "Igravesmall", + + # 360 + "Iacutesmall", "Icircumflexsmall", "Idieresissmall", "Ethsmall", + "Ntildesmall", + "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall", + "Odieresissmall", + + # 370 + "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall", + "Ucircumflexsmall", + "Udieresissmall", "Yacutesmall", "Thornsmall", "Ydieresissmall", + "001.000", + + # 380 + "001.001", "001.002", "001.003", "Black", "Bold", + "Book", "Light", "Medium", "Regular", "Roman", + + # 390 + "Semibold" +] + + +# This table maps character codes of the Adobe Standard Type 1 +# encoding to glyph indices in the sid_standard_names table. +# +t1_standard_encoding = \ +[ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 0, 111, 112, 113, + 114, 0, 115, 116, 117, 118, 119, 120, 121, 122, + 0, 123, 0, 124, 125, 126, 127, 128, 129, 130, + + 131, 0, 132, 133, 0, 134, 135, 136, 137, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 138, 0, 139, 0, 0, + 0, 0, 140, 141, 142, 143, 0, 0, 0, 0, + 0, 144, 0, 0, 0, 145, 0, 0, 146, 147, + + 148, 149, 0, 0, 0, 0 +] + + +# This table maps character codes of the Adobe Expert Type 1 +# encoding to glyph indices in the sid_standard_names table. +# +t1_expert_encoding = \ +[ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 229, 230, 0, 231, 232, 233, 234, + 235, 236, 237, 238, 13, 14, 15, 99, 239, 240, + + 241, 242, 243, 244, 245, 246, 247, 248, 27, 28, + 249, 250, 251, 252, 0, 253, 254, 255, 256, 257, + 0, 0, 0, 258, 0, 0, 259, 260, 261, 262, + 0, 0, 263, 264, 265, 0, 266, 109, 110, 267, + 268, 269, 0, 270, 271, 272, 273, 274, 275, 276, + + 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 304, 305, 306, 0, 0, 307, 308, 309, 310, + 311, 0, 312, 0, 0, 313, 0, 0, 314, 315, + 0, 0, 316, 317, 318, 0, 0, 0, 158, 155, + 163, 319, 320, 321, 322, 323, 324, 325, 0, 0, + + 326, 150, 164, 169, 327, 328, 329, 330, 331, 332, + 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, + + 373, 374, 375, 376, 377, 378 +] + + +# This data has been taken literally from the file `glyphlist.txt', +# version 2.0, 22 Sept 2002. It is available from +# +# http://partners.adobe.com/asn/developer/typeforum/unicodegn.html +# +adobe_glyph_list = """\ +A;0041 +AE;00C6 +AEacute;01FC +AEmacron;01E2 +AEsmall;F7E6 +Aacute;00C1 +Aacutesmall;F7E1 +Abreve;0102 +Abreveacute;1EAE +Abrevecyrillic;04D0 +Abrevedotbelow;1EB6 +Abrevegrave;1EB0 +Abrevehookabove;1EB2 +Abrevetilde;1EB4 +Acaron;01CD +Acircle;24B6 +Acircumflex;00C2 +Acircumflexacute;1EA4 +Acircumflexdotbelow;1EAC +Acircumflexgrave;1EA6 +Acircumflexhookabove;1EA8 +Acircumflexsmall;F7E2 +Acircumflextilde;1EAA +Acute;F6C9 +Acutesmall;F7B4 +Acyrillic;0410 +Adblgrave;0200 +Adieresis;00C4 +Adieresiscyrillic;04D2 +Adieresismacron;01DE +Adieresissmall;F7E4 +Adotbelow;1EA0 +Adotmacron;01E0 +Agrave;00C0 +Agravesmall;F7E0 +Ahookabove;1EA2 +Aiecyrillic;04D4 +Ainvertedbreve;0202 +Alpha;0391 +Alphatonos;0386 +Amacron;0100 +Amonospace;FF21 +Aogonek;0104 +Aring;00C5 +Aringacute;01FA +Aringbelow;1E00 +Aringsmall;F7E5 +Asmall;F761 +Atilde;00C3 +Atildesmall;F7E3 +Aybarmenian;0531 +B;0042 +Bcircle;24B7 +Bdotaccent;1E02 +Bdotbelow;1E04 +Becyrillic;0411 +Benarmenian;0532 +Beta;0392 +Bhook;0181 +Blinebelow;1E06 +Bmonospace;FF22 +Brevesmall;F6F4 +Bsmall;F762 +Btopbar;0182 +C;0043 +Caarmenian;053E +Cacute;0106 +Caron;F6CA +Caronsmall;F6F5 +Ccaron;010C +Ccedilla;00C7 +Ccedillaacute;1E08 +Ccedillasmall;F7E7 +Ccircle;24B8 +Ccircumflex;0108 +Cdot;010A +Cdotaccent;010A +Cedillasmall;F7B8 +Chaarmenian;0549 +Cheabkhasiancyrillic;04BC +Checyrillic;0427 +Chedescenderabkhasiancyrillic;04BE +Chedescendercyrillic;04B6 +Chedieresiscyrillic;04F4 +Cheharmenian;0543 +Chekhakassiancyrillic;04CB +Cheverticalstrokecyrillic;04B8 +Chi;03A7 +Chook;0187 +Circumflexsmall;F6F6 +Cmonospace;FF23 +Coarmenian;0551 +Csmall;F763 +D;0044 +DZ;01F1 +DZcaron;01C4 +Daarmenian;0534 +Dafrican;0189 +Dcaron;010E +Dcedilla;1E10 +Dcircle;24B9 +Dcircumflexbelow;1E12 +Dcroat;0110 +Ddotaccent;1E0A +Ddotbelow;1E0C +Decyrillic;0414 +Deicoptic;03EE +Delta;2206 +Deltagreek;0394 +Dhook;018A +Dieresis;F6CB +DieresisAcute;F6CC +DieresisGrave;F6CD +Dieresissmall;F7A8 +Digammagreek;03DC +Djecyrillic;0402 +Dlinebelow;1E0E +Dmonospace;FF24 +Dotaccentsmall;F6F7 +Dslash;0110 +Dsmall;F764 +Dtopbar;018B +Dz;01F2 +Dzcaron;01C5 +Dzeabkhasiancyrillic;04E0 +Dzecyrillic;0405 +Dzhecyrillic;040F +E;0045 +Eacute;00C9 +Eacutesmall;F7E9 +Ebreve;0114 +Ecaron;011A +Ecedillabreve;1E1C +Echarmenian;0535 +Ecircle;24BA +Ecircumflex;00CA +Ecircumflexacute;1EBE +Ecircumflexbelow;1E18 +Ecircumflexdotbelow;1EC6 +Ecircumflexgrave;1EC0 +Ecircumflexhookabove;1EC2 +Ecircumflexsmall;F7EA +Ecircumflextilde;1EC4 +Ecyrillic;0404 +Edblgrave;0204 +Edieresis;00CB +Edieresissmall;F7EB +Edot;0116 +Edotaccent;0116 +Edotbelow;1EB8 +Efcyrillic;0424 +Egrave;00C8 +Egravesmall;F7E8 +Eharmenian;0537 +Ehookabove;1EBA +Eightroman;2167 +Einvertedbreve;0206 +Eiotifiedcyrillic;0464 +Elcyrillic;041B +Elevenroman;216A +Emacron;0112 +Emacronacute;1E16 +Emacrongrave;1E14 +Emcyrillic;041C +Emonospace;FF25 +Encyrillic;041D +Endescendercyrillic;04A2 +Eng;014A +Enghecyrillic;04A4 +Enhookcyrillic;04C7 +Eogonek;0118 +Eopen;0190 +Epsilon;0395 +Epsilontonos;0388 +Ercyrillic;0420 +Ereversed;018E +Ereversedcyrillic;042D +Escyrillic;0421 +Esdescendercyrillic;04AA +Esh;01A9 +Esmall;F765 +Eta;0397 +Etarmenian;0538 +Etatonos;0389 +Eth;00D0 +Ethsmall;F7F0 +Etilde;1EBC +Etildebelow;1E1A +Euro;20AC +Ezh;01B7 +Ezhcaron;01EE +Ezhreversed;01B8 +F;0046 +Fcircle;24BB +Fdotaccent;1E1E +Feharmenian;0556 +Feicoptic;03E4 +Fhook;0191 +Fitacyrillic;0472 +Fiveroman;2164 +Fmonospace;FF26 +Fourroman;2163 +Fsmall;F766 +G;0047 +GBsquare;3387 +Gacute;01F4 +Gamma;0393 +Gammaafrican;0194 +Gangiacoptic;03EA +Gbreve;011E +Gcaron;01E6 +Gcedilla;0122 +Gcircle;24BC +Gcircumflex;011C +Gcommaaccent;0122 +Gdot;0120 +Gdotaccent;0120 +Gecyrillic;0413 +Ghadarmenian;0542 +Ghemiddlehookcyrillic;0494 +Ghestrokecyrillic;0492 +Gheupturncyrillic;0490 +Ghook;0193 +Gimarmenian;0533 +Gjecyrillic;0403 +Gmacron;1E20 +Gmonospace;FF27 +Grave;F6CE +Gravesmall;F760 +Gsmall;F767 +Gsmallhook;029B +Gstroke;01E4 +H;0048 +H18533;25CF +H18543;25AA +H18551;25AB +H22073;25A1 +HPsquare;33CB +Haabkhasiancyrillic;04A8 +Hadescendercyrillic;04B2 +Hardsigncyrillic;042A +Hbar;0126 +Hbrevebelow;1E2A +Hcedilla;1E28 +Hcircle;24BD +Hcircumflex;0124 +Hdieresis;1E26 +Hdotaccent;1E22 +Hdotbelow;1E24 +Hmonospace;FF28 +Hoarmenian;0540 +Horicoptic;03E8 +Hsmall;F768 +Hungarumlaut;F6CF +Hungarumlautsmall;F6F8 +Hzsquare;3390 +I;0049 +IAcyrillic;042F +IJ;0132 +IUcyrillic;042E +Iacute;00CD +Iacutesmall;F7ED +Ibreve;012C +Icaron;01CF +Icircle;24BE +Icircumflex;00CE +Icircumflexsmall;F7EE +Icyrillic;0406 +Idblgrave;0208 +Idieresis;00CF +Idieresisacute;1E2E +Idieresiscyrillic;04E4 +Idieresissmall;F7EF +Idot;0130 +Idotaccent;0130 +Idotbelow;1ECA +Iebrevecyrillic;04D6 +Iecyrillic;0415 +Ifraktur;2111 +Igrave;00CC +Igravesmall;F7EC +Ihookabove;1EC8 +Iicyrillic;0418 +Iinvertedbreve;020A +Iishortcyrillic;0419 +Imacron;012A +Imacroncyrillic;04E2 +Imonospace;FF29 +Iniarmenian;053B +Iocyrillic;0401 +Iogonek;012E +Iota;0399 +Iotaafrican;0196 +Iotadieresis;03AA +Iotatonos;038A +Ismall;F769 +Istroke;0197 +Itilde;0128 +Itildebelow;1E2C +Izhitsacyrillic;0474 +Izhitsadblgravecyrillic;0476 +J;004A +Jaarmenian;0541 +Jcircle;24BF +Jcircumflex;0134 +Jecyrillic;0408 +Jheharmenian;054B +Jmonospace;FF2A +Jsmall;F76A +K;004B +KBsquare;3385 +KKsquare;33CD +Kabashkircyrillic;04A0 +Kacute;1E30 +Kacyrillic;041A +Kadescendercyrillic;049A +Kahookcyrillic;04C3 +Kappa;039A +Kastrokecyrillic;049E +Kaverticalstrokecyrillic;049C +Kcaron;01E8 +Kcedilla;0136 +Kcircle;24C0 +Kcommaaccent;0136 +Kdotbelow;1E32 +Keharmenian;0554 +Kenarmenian;053F +Khacyrillic;0425 +Kheicoptic;03E6 +Khook;0198 +Kjecyrillic;040C +Klinebelow;1E34 +Kmonospace;FF2B +Koppacyrillic;0480 +Koppagreek;03DE +Ksicyrillic;046E +Ksmall;F76B +L;004C +LJ;01C7 +LL;F6BF +Lacute;0139 +Lambda;039B +Lcaron;013D +Lcedilla;013B +Lcircle;24C1 +Lcircumflexbelow;1E3C +Lcommaaccent;013B +Ldot;013F +Ldotaccent;013F +Ldotbelow;1E36 +Ldotbelowmacron;1E38 +Liwnarmenian;053C +Lj;01C8 +Ljecyrillic;0409 +Llinebelow;1E3A +Lmonospace;FF2C +Lslash;0141 +Lslashsmall;F6F9 +Lsmall;F76C +M;004D +MBsquare;3386 +Macron;F6D0 +Macronsmall;F7AF +Macute;1E3E +Mcircle;24C2 +Mdotaccent;1E40 +Mdotbelow;1E42 +Menarmenian;0544 +Mmonospace;FF2D +Msmall;F76D +Mturned;019C +Mu;039C +N;004E +NJ;01CA +Nacute;0143 +Ncaron;0147 +Ncedilla;0145 +Ncircle;24C3 +Ncircumflexbelow;1E4A +Ncommaaccent;0145 +Ndotaccent;1E44 +Ndotbelow;1E46 +Nhookleft;019D +Nineroman;2168 +Nj;01CB +Njecyrillic;040A +Nlinebelow;1E48 +Nmonospace;FF2E +Nowarmenian;0546 +Nsmall;F76E +Ntilde;00D1 +Ntildesmall;F7F1 +Nu;039D +O;004F +OE;0152 +OEsmall;F6FA +Oacute;00D3 +Oacutesmall;F7F3 +Obarredcyrillic;04E8 +Obarreddieresiscyrillic;04EA +Obreve;014E +Ocaron;01D1 +Ocenteredtilde;019F +Ocircle;24C4 +Ocircumflex;00D4 +Ocircumflexacute;1ED0 +Ocircumflexdotbelow;1ED8 +Ocircumflexgrave;1ED2 +Ocircumflexhookabove;1ED4 +Ocircumflexsmall;F7F4 +Ocircumflextilde;1ED6 +Ocyrillic;041E +Odblacute;0150 +Odblgrave;020C +Odieresis;00D6 +Odieresiscyrillic;04E6 +Odieresissmall;F7F6 +Odotbelow;1ECC +Ogoneksmall;F6FB +Ograve;00D2 +Ogravesmall;F7F2 +Oharmenian;0555 +Ohm;2126 +Ohookabove;1ECE +Ohorn;01A0 +Ohornacute;1EDA +Ohorndotbelow;1EE2 +Ohorngrave;1EDC +Ohornhookabove;1EDE +Ohorntilde;1EE0 +Ohungarumlaut;0150 +Oi;01A2 +Oinvertedbreve;020E +Omacron;014C +Omacronacute;1E52 +Omacrongrave;1E50 +Omega;2126 +Omegacyrillic;0460 +Omegagreek;03A9 +Omegaroundcyrillic;047A +Omegatitlocyrillic;047C +Omegatonos;038F +Omicron;039F +Omicrontonos;038C +Omonospace;FF2F +Oneroman;2160 +Oogonek;01EA +Oogonekmacron;01EC +Oopen;0186 +Oslash;00D8 +Oslashacute;01FE +Oslashsmall;F7F8 +Osmall;F76F +Ostrokeacute;01FE +Otcyrillic;047E +Otilde;00D5 +Otildeacute;1E4C +Otildedieresis;1E4E +Otildesmall;F7F5 +P;0050 +Pacute;1E54 +Pcircle;24C5 +Pdotaccent;1E56 +Pecyrillic;041F +Peharmenian;054A +Pemiddlehookcyrillic;04A6 +Phi;03A6 +Phook;01A4 +Pi;03A0 +Piwrarmenian;0553 +Pmonospace;FF30 +Psi;03A8 +Psicyrillic;0470 +Psmall;F770 +Q;0051 +Qcircle;24C6 +Qmonospace;FF31 +Qsmall;F771 +R;0052 +Raarmenian;054C +Racute;0154 +Rcaron;0158 +Rcedilla;0156 +Rcircle;24C7 +Rcommaaccent;0156 +Rdblgrave;0210 +Rdotaccent;1E58 +Rdotbelow;1E5A +Rdotbelowmacron;1E5C +Reharmenian;0550 +Rfraktur;211C +Rho;03A1 +Ringsmall;F6FC +Rinvertedbreve;0212 +Rlinebelow;1E5E +Rmonospace;FF32 +Rsmall;F772 +Rsmallinverted;0281 +Rsmallinvertedsuperior;02B6 +S;0053 +SF010000;250C +SF020000;2514 +SF030000;2510 +SF040000;2518 +SF050000;253C +SF060000;252C +SF070000;2534 +SF080000;251C +SF090000;2524 +SF100000;2500 +SF110000;2502 +SF190000;2561 +SF200000;2562 +SF210000;2556 +SF220000;2555 +SF230000;2563 +SF240000;2551 +SF250000;2557 +SF260000;255D +SF270000;255C +SF280000;255B +SF360000;255E +SF370000;255F +SF380000;255A +SF390000;2554 +SF400000;2569 +SF410000;2566 +SF420000;2560 +SF430000;2550 +SF440000;256C +SF450000;2567 +SF460000;2568 +SF470000;2564 +SF480000;2565 +SF490000;2559 +SF500000;2558 +SF510000;2552 +SF520000;2553 +SF530000;256B +SF540000;256A +Sacute;015A +Sacutedotaccent;1E64 +Sampigreek;03E0 +Scaron;0160 +Scarondotaccent;1E66 +Scaronsmall;F6FD +Scedilla;015E +Schwa;018F +Schwacyrillic;04D8 +Schwadieresiscyrillic;04DA +Scircle;24C8 +Scircumflex;015C +Scommaaccent;0218 +Sdotaccent;1E60 +Sdotbelow;1E62 +Sdotbelowdotaccent;1E68 +Seharmenian;054D +Sevenroman;2166 +Shaarmenian;0547 +Shacyrillic;0428 +Shchacyrillic;0429 +Sheicoptic;03E2 +Shhacyrillic;04BA +Shimacoptic;03EC +Sigma;03A3 +Sixroman;2165 +Smonospace;FF33 +Softsigncyrillic;042C +Ssmall;F773 +Stigmagreek;03DA +T;0054 +Tau;03A4 +Tbar;0166 +Tcaron;0164 +Tcedilla;0162 +Tcircle;24C9 +Tcircumflexbelow;1E70 +Tcommaaccent;0162 +Tdotaccent;1E6A +Tdotbelow;1E6C +Tecyrillic;0422 +Tedescendercyrillic;04AC +Tenroman;2169 +Tetsecyrillic;04B4 +Theta;0398 +Thook;01AC +Thorn;00DE +Thornsmall;F7FE +Threeroman;2162 +Tildesmall;F6FE +Tiwnarmenian;054F +Tlinebelow;1E6E +Tmonospace;FF34 +Toarmenian;0539 +Tonefive;01BC +Tonesix;0184 +Tonetwo;01A7 +Tretroflexhook;01AE +Tsecyrillic;0426 +Tshecyrillic;040B +Tsmall;F774 +Twelveroman;216B +Tworoman;2161 +U;0055 +Uacute;00DA +Uacutesmall;F7FA +Ubreve;016C +Ucaron;01D3 +Ucircle;24CA +Ucircumflex;00DB +Ucircumflexbelow;1E76 +Ucircumflexsmall;F7FB +Ucyrillic;0423 +Udblacute;0170 +Udblgrave;0214 +Udieresis;00DC +Udieresisacute;01D7 +Udieresisbelow;1E72 +Udieresiscaron;01D9 +Udieresiscyrillic;04F0 +Udieresisgrave;01DB +Udieresismacron;01D5 +Udieresissmall;F7FC +Udotbelow;1EE4 +Ugrave;00D9 +Ugravesmall;F7F9 +Uhookabove;1EE6 +Uhorn;01AF +Uhornacute;1EE8 +Uhorndotbelow;1EF0 +Uhorngrave;1EEA +Uhornhookabove;1EEC +Uhorntilde;1EEE +Uhungarumlaut;0170 +Uhungarumlautcyrillic;04F2 +Uinvertedbreve;0216 +Ukcyrillic;0478 +Umacron;016A +Umacroncyrillic;04EE +Umacrondieresis;1E7A +Umonospace;FF35 +Uogonek;0172 +Upsilon;03A5 +Upsilon1;03D2 +Upsilonacutehooksymbolgreek;03D3 +Upsilonafrican;01B1 +Upsilondieresis;03AB +Upsilondieresishooksymbolgreek;03D4 +Upsilonhooksymbol;03D2 +Upsilontonos;038E +Uring;016E +Ushortcyrillic;040E +Usmall;F775 +Ustraightcyrillic;04AE +Ustraightstrokecyrillic;04B0 +Utilde;0168 +Utildeacute;1E78 +Utildebelow;1E74 +V;0056 +Vcircle;24CB +Vdotbelow;1E7E +Vecyrillic;0412 +Vewarmenian;054E +Vhook;01B2 +Vmonospace;FF36 +Voarmenian;0548 +Vsmall;F776 +Vtilde;1E7C +W;0057 +Wacute;1E82 +Wcircle;24CC +Wcircumflex;0174 +Wdieresis;1E84 +Wdotaccent;1E86 +Wdotbelow;1E88 +Wgrave;1E80 +Wmonospace;FF37 +Wsmall;F777 +X;0058 +Xcircle;24CD +Xdieresis;1E8C +Xdotaccent;1E8A +Xeharmenian;053D +Xi;039E +Xmonospace;FF38 +Xsmall;F778 +Y;0059 +Yacute;00DD +Yacutesmall;F7FD +Yatcyrillic;0462 +Ycircle;24CE +Ycircumflex;0176 +Ydieresis;0178 +Ydieresissmall;F7FF +Ydotaccent;1E8E +Ydotbelow;1EF4 +Yericyrillic;042B +Yerudieresiscyrillic;04F8 +Ygrave;1EF2 +Yhook;01B3 +Yhookabove;1EF6 +Yiarmenian;0545 +Yicyrillic;0407 +Yiwnarmenian;0552 +Ymonospace;FF39 +Ysmall;F779 +Ytilde;1EF8 +Yusbigcyrillic;046A +Yusbigiotifiedcyrillic;046C +Yuslittlecyrillic;0466 +Yuslittleiotifiedcyrillic;0468 +Z;005A +Zaarmenian;0536 +Zacute;0179 +Zcaron;017D +Zcaronsmall;F6FF +Zcircle;24CF +Zcircumflex;1E90 +Zdot;017B +Zdotaccent;017B +Zdotbelow;1E92 +Zecyrillic;0417 +Zedescendercyrillic;0498 +Zedieresiscyrillic;04DE +Zeta;0396 +Zhearmenian;053A +Zhebrevecyrillic;04C1 +Zhecyrillic;0416 +Zhedescendercyrillic;0496 +Zhedieresiscyrillic;04DC +Zlinebelow;1E94 +Zmonospace;FF3A +Zsmall;F77A +Zstroke;01B5 +a;0061 +aabengali;0986 +aacute;00E1 +aadeva;0906 +aagujarati;0A86 +aagurmukhi;0A06 +aamatragurmukhi;0A3E +aarusquare;3303 +aavowelsignbengali;09BE +aavowelsigndeva;093E +aavowelsigngujarati;0ABE +abbreviationmarkarmenian;055F +abbreviationsigndeva;0970 +abengali;0985 +abopomofo;311A +abreve;0103 +abreveacute;1EAF +abrevecyrillic;04D1 +abrevedotbelow;1EB7 +abrevegrave;1EB1 +abrevehookabove;1EB3 +abrevetilde;1EB5 +acaron;01CE +acircle;24D0 +acircumflex;00E2 +acircumflexacute;1EA5 +acircumflexdotbelow;1EAD +acircumflexgrave;1EA7 +acircumflexhookabove;1EA9 +acircumflextilde;1EAB +acute;00B4 +acutebelowcmb;0317 +acutecmb;0301 +acutecomb;0301 +acutedeva;0954 +acutelowmod;02CF +acutetonecmb;0341 +acyrillic;0430 +adblgrave;0201 +addakgurmukhi;0A71 +adeva;0905 +adieresis;00E4 +adieresiscyrillic;04D3 +adieresismacron;01DF +adotbelow;1EA1 +adotmacron;01E1 +ae;00E6 +aeacute;01FD +aekorean;3150 +aemacron;01E3 +afii00208;2015 +afii08941;20A4 +afii10017;0410 +afii10018;0411 +afii10019;0412 +afii10020;0413 +afii10021;0414 +afii10022;0415 +afii10023;0401 +afii10024;0416 +afii10025;0417 +afii10026;0418 +afii10027;0419 +afii10028;041A +afii10029;041B +afii10030;041C +afii10031;041D +afii10032;041E +afii10033;041F +afii10034;0420 +afii10035;0421 +afii10036;0422 +afii10037;0423 +afii10038;0424 +afii10039;0425 +afii10040;0426 +afii10041;0427 +afii10042;0428 +afii10043;0429 +afii10044;042A +afii10045;042B +afii10046;042C +afii10047;042D +afii10048;042E +afii10049;042F +afii10050;0490 +afii10051;0402 +afii10052;0403 +afii10053;0404 +afii10054;0405 +afii10055;0406 +afii10056;0407 +afii10057;0408 +afii10058;0409 +afii10059;040A +afii10060;040B +afii10061;040C +afii10062;040E +afii10063;F6C4 +afii10064;F6C5 +afii10065;0430 +afii10066;0431 +afii10067;0432 +afii10068;0433 +afii10069;0434 +afii10070;0435 +afii10071;0451 +afii10072;0436 +afii10073;0437 +afii10074;0438 +afii10075;0439 +afii10076;043A +afii10077;043B +afii10078;043C +afii10079;043D +afii10080;043E +afii10081;043F +afii10082;0440 +afii10083;0441 +afii10084;0442 +afii10085;0443 +afii10086;0444 +afii10087;0445 +afii10088;0446 +afii10089;0447 +afii10090;0448 +afii10091;0449 +afii10092;044A +afii10093;044B +afii10094;044C +afii10095;044D +afii10096;044E +afii10097;044F +afii10098;0491 +afii10099;0452 +afii10100;0453 +afii10101;0454 +afii10102;0455 +afii10103;0456 +afii10104;0457 +afii10105;0458 +afii10106;0459 +afii10107;045A +afii10108;045B +afii10109;045C +afii10110;045E +afii10145;040F +afii10146;0462 +afii10147;0472 +afii10148;0474 +afii10192;F6C6 +afii10193;045F +afii10194;0463 +afii10195;0473 +afii10196;0475 +afii10831;F6C7 +afii10832;F6C8 +afii10846;04D9 +afii299;200E +afii300;200F +afii301;200D +afii57381;066A +afii57388;060C +afii57392;0660 +afii57393;0661 +afii57394;0662 +afii57395;0663 +afii57396;0664 +afii57397;0665 +afii57398;0666 +afii57399;0667 +afii57400;0668 +afii57401;0669 +afii57403;061B +afii57407;061F +afii57409;0621 +afii57410;0622 +afii57411;0623 +afii57412;0624 +afii57413;0625 +afii57414;0626 +afii57415;0627 +afii57416;0628 +afii57417;0629 +afii57418;062A +afii57419;062B +afii57420;062C +afii57421;062D +afii57422;062E +afii57423;062F +afii57424;0630 +afii57425;0631 +afii57426;0632 +afii57427;0633 +afii57428;0634 +afii57429;0635 +afii57430;0636 +afii57431;0637 +afii57432;0638 +afii57433;0639 +afii57434;063A +afii57440;0640 +afii57441;0641 +afii57442;0642 +afii57443;0643 +afii57444;0644 +afii57445;0645 +afii57446;0646 +afii57448;0648 +afii57449;0649 +afii57450;064A +afii57451;064B +afii57452;064C +afii57453;064D +afii57454;064E +afii57455;064F +afii57456;0650 +afii57457;0651 +afii57458;0652 +afii57470;0647 +afii57505;06A4 +afii57506;067E +afii57507;0686 +afii57508;0698 +afii57509;06AF +afii57511;0679 +afii57512;0688 +afii57513;0691 +afii57514;06BA +afii57519;06D2 +afii57534;06D5 +afii57636;20AA +afii57645;05BE +afii57658;05C3 +afii57664;05D0 +afii57665;05D1 +afii57666;05D2 +afii57667;05D3 +afii57668;05D4 +afii57669;05D5 +afii57670;05D6 +afii57671;05D7 +afii57672;05D8 +afii57673;05D9 +afii57674;05DA +afii57675;05DB +afii57676;05DC +afii57677;05DD +afii57678;05DE +afii57679;05DF +afii57680;05E0 +afii57681;05E1 +afii57682;05E2 +afii57683;05E3 +afii57684;05E4 +afii57685;05E5 +afii57686;05E6 +afii57687;05E7 +afii57688;05E8 +afii57689;05E9 +afii57690;05EA +afii57694;FB2A +afii57695;FB2B +afii57700;FB4B +afii57705;FB1F +afii57716;05F0 +afii57717;05F1 +afii57718;05F2 +afii57723;FB35 +afii57793;05B4 +afii57794;05B5 +afii57795;05B6 +afii57796;05BB +afii57797;05B8 +afii57798;05B7 +afii57799;05B0 +afii57800;05B2 +afii57801;05B1 +afii57802;05B3 +afii57803;05C2 +afii57804;05C1 +afii57806;05B9 +afii57807;05BC +afii57839;05BD +afii57841;05BF +afii57842;05C0 +afii57929;02BC +afii61248;2105 +afii61289;2113 +afii61352;2116 +afii61573;202C +afii61574;202D +afii61575;202E +afii61664;200C +afii63167;066D +afii64937;02BD +agrave;00E0 +agujarati;0A85 +agurmukhi;0A05 +ahiragana;3042 +ahookabove;1EA3 +aibengali;0990 +aibopomofo;311E +aideva;0910 +aiecyrillic;04D5 +aigujarati;0A90 +aigurmukhi;0A10 +aimatragurmukhi;0A48 +ainarabic;0639 +ainfinalarabic;FECA +aininitialarabic;FECB +ainmedialarabic;FECC +ainvertedbreve;0203 +aivowelsignbengali;09C8 +aivowelsigndeva;0948 +aivowelsigngujarati;0AC8 +akatakana;30A2 +akatakanahalfwidth;FF71 +akorean;314F +alef;05D0 +alefarabic;0627 +alefdageshhebrew;FB30 +aleffinalarabic;FE8E +alefhamzaabovearabic;0623 +alefhamzaabovefinalarabic;FE84 +alefhamzabelowarabic;0625 +alefhamzabelowfinalarabic;FE88 +alefhebrew;05D0 +aleflamedhebrew;FB4F +alefmaddaabovearabic;0622 +alefmaddaabovefinalarabic;FE82 +alefmaksuraarabic;0649 +alefmaksurafinalarabic;FEF0 +alefmaksurainitialarabic;FEF3 +alefmaksuramedialarabic;FEF4 +alefpatahhebrew;FB2E +alefqamatshebrew;FB2F +aleph;2135 +allequal;224C +alpha;03B1 +alphatonos;03AC +amacron;0101 +amonospace;FF41 +ampersand;0026 +ampersandmonospace;FF06 +ampersandsmall;F726 +amsquare;33C2 +anbopomofo;3122 +angbopomofo;3124 +angkhankhuthai;0E5A +angle;2220 +anglebracketleft;3008 +anglebracketleftvertical;FE3F +anglebracketright;3009 +anglebracketrightvertical;FE40 +angleleft;2329 +angleright;232A +angstrom;212B +anoteleia;0387 +anudattadeva;0952 +anusvarabengali;0982 +anusvaradeva;0902 +anusvaragujarati;0A82 +aogonek;0105 +apaatosquare;3300 +aparen;249C +apostrophearmenian;055A +apostrophemod;02BC +apple;F8FF +approaches;2250 +approxequal;2248 +approxequalorimage;2252 +approximatelyequal;2245 +araeaekorean;318E +araeakorean;318D +arc;2312 +arighthalfring;1E9A +aring;00E5 +aringacute;01FB +aringbelow;1E01 +arrowboth;2194 +arrowdashdown;21E3 +arrowdashleft;21E0 +arrowdashright;21E2 +arrowdashup;21E1 +arrowdblboth;21D4 +arrowdbldown;21D3 +arrowdblleft;21D0 +arrowdblright;21D2 +arrowdblup;21D1 +arrowdown;2193 +arrowdownleft;2199 +arrowdownright;2198 +arrowdownwhite;21E9 +arrowheaddownmod;02C5 +arrowheadleftmod;02C2 +arrowheadrightmod;02C3 +arrowheadupmod;02C4 +arrowhorizex;F8E7 +arrowleft;2190 +arrowleftdbl;21D0 +arrowleftdblstroke;21CD +arrowleftoverright;21C6 +arrowleftwhite;21E6 +arrowright;2192 +arrowrightdblstroke;21CF +arrowrightheavy;279E +arrowrightoverleft;21C4 +arrowrightwhite;21E8 +arrowtableft;21E4 +arrowtabright;21E5 +arrowup;2191 +arrowupdn;2195 +arrowupdnbse;21A8 +arrowupdownbase;21A8 +arrowupleft;2196 +arrowupleftofdown;21C5 +arrowupright;2197 +arrowupwhite;21E7 +arrowvertex;F8E6 +asciicircum;005E +asciicircummonospace;FF3E +asciitilde;007E +asciitildemonospace;FF5E +ascript;0251 +ascriptturned;0252 +asmallhiragana;3041 +asmallkatakana;30A1 +asmallkatakanahalfwidth;FF67 +asterisk;002A +asteriskaltonearabic;066D +asteriskarabic;066D +asteriskmath;2217 +asteriskmonospace;FF0A +asterisksmall;FE61 +asterism;2042 +asuperior;F6E9 +asymptoticallyequal;2243 +at;0040 +atilde;00E3 +atmonospace;FF20 +atsmall;FE6B +aturned;0250 +aubengali;0994 +aubopomofo;3120 +audeva;0914 +augujarati;0A94 +augurmukhi;0A14 +aulengthmarkbengali;09D7 +aumatragurmukhi;0A4C +auvowelsignbengali;09CC +auvowelsigndeva;094C +auvowelsigngujarati;0ACC +avagrahadeva;093D +aybarmenian;0561 +ayin;05E2 +ayinaltonehebrew;FB20 +ayinhebrew;05E2 +b;0062 +babengali;09AC +backslash;005C +backslashmonospace;FF3C +badeva;092C +bagujarati;0AAC +bagurmukhi;0A2C +bahiragana;3070 +bahtthai;0E3F +bakatakana;30D0 +bar;007C +barmonospace;FF5C +bbopomofo;3105 +bcircle;24D1 +bdotaccent;1E03 +bdotbelow;1E05 +beamedsixteenthnotes;266C +because;2235 +becyrillic;0431 +beharabic;0628 +behfinalarabic;FE90 +behinitialarabic;FE91 +behiragana;3079 +behmedialarabic;FE92 +behmeeminitialarabic;FC9F +behmeemisolatedarabic;FC08 +behnoonfinalarabic;FC6D +bekatakana;30D9 +benarmenian;0562 +bet;05D1 +beta;03B2 +betasymbolgreek;03D0 +betdagesh;FB31 +betdageshhebrew;FB31 +bethebrew;05D1 +betrafehebrew;FB4C +bhabengali;09AD +bhadeva;092D +bhagujarati;0AAD +bhagurmukhi;0A2D +bhook;0253 +bihiragana;3073 +bikatakana;30D3 +bilabialclick;0298 +bindigurmukhi;0A02 +birusquare;3331 +blackcircle;25CF +blackdiamond;25C6 +blackdownpointingtriangle;25BC +blackleftpointingpointer;25C4 +blackleftpointingtriangle;25C0 +blacklenticularbracketleft;3010 +blacklenticularbracketleftvertical;FE3B +blacklenticularbracketright;3011 +blacklenticularbracketrightvertical;FE3C +blacklowerlefttriangle;25E3 +blacklowerrighttriangle;25E2 +blackrectangle;25AC +blackrightpointingpointer;25BA +blackrightpointingtriangle;25B6 +blacksmallsquare;25AA +blacksmilingface;263B +blacksquare;25A0 +blackstar;2605 +blackupperlefttriangle;25E4 +blackupperrighttriangle;25E5 +blackuppointingsmalltriangle;25B4 +blackuppointingtriangle;25B2 +blank;2423 +blinebelow;1E07 +block;2588 +bmonospace;FF42 +bobaimaithai;0E1A +bohiragana;307C +bokatakana;30DC +bparen;249D +bqsquare;33C3 +braceex;F8F4 +braceleft;007B +braceleftbt;F8F3 +braceleftmid;F8F2 +braceleftmonospace;FF5B +braceleftsmall;FE5B +bracelefttp;F8F1 +braceleftvertical;FE37 +braceright;007D +bracerightbt;F8FE +bracerightmid;F8FD +bracerightmonospace;FF5D +bracerightsmall;FE5C +bracerighttp;F8FC +bracerightvertical;FE38 +bracketleft;005B +bracketleftbt;F8F0 +bracketleftex;F8EF +bracketleftmonospace;FF3B +bracketlefttp;F8EE +bracketright;005D +bracketrightbt;F8FB +bracketrightex;F8FA +bracketrightmonospace;FF3D +bracketrighttp;F8F9 +breve;02D8 +brevebelowcmb;032E +brevecmb;0306 +breveinvertedbelowcmb;032F +breveinvertedcmb;0311 +breveinverteddoublecmb;0361 +bridgebelowcmb;032A +bridgeinvertedbelowcmb;033A +brokenbar;00A6 +bstroke;0180 +bsuperior;F6EA +btopbar;0183 +buhiragana;3076 +bukatakana;30D6 +bullet;2022 +bulletinverse;25D8 +bulletoperator;2219 +bullseye;25CE +c;0063 +caarmenian;056E +cabengali;099A +cacute;0107 +cadeva;091A +cagujarati;0A9A +cagurmukhi;0A1A +calsquare;3388 +candrabindubengali;0981 +candrabinducmb;0310 +candrabindudeva;0901 +candrabindugujarati;0A81 +capslock;21EA +careof;2105 +caron;02C7 +caronbelowcmb;032C +caroncmb;030C +carriagereturn;21B5 +cbopomofo;3118 +ccaron;010D +ccedilla;00E7 +ccedillaacute;1E09 +ccircle;24D2 +ccircumflex;0109 +ccurl;0255 +cdot;010B +cdotaccent;010B +cdsquare;33C5 +cedilla;00B8 +cedillacmb;0327 +cent;00A2 +centigrade;2103 +centinferior;F6DF +centmonospace;FFE0 +centoldstyle;F7A2 +centsuperior;F6E0 +chaarmenian;0579 +chabengali;099B +chadeva;091B +chagujarati;0A9B +chagurmukhi;0A1B +chbopomofo;3114 +cheabkhasiancyrillic;04BD +checkmark;2713 +checyrillic;0447 +chedescenderabkhasiancyrillic;04BF +chedescendercyrillic;04B7 +chedieresiscyrillic;04F5 +cheharmenian;0573 +chekhakassiancyrillic;04CC +cheverticalstrokecyrillic;04B9 +chi;03C7 +chieuchacirclekorean;3277 +chieuchaparenkorean;3217 +chieuchcirclekorean;3269 +chieuchkorean;314A +chieuchparenkorean;3209 +chochangthai;0E0A +chochanthai;0E08 +chochingthai;0E09 +chochoethai;0E0C +chook;0188 +cieucacirclekorean;3276 +cieucaparenkorean;3216 +cieuccirclekorean;3268 +cieuckorean;3148 +cieucparenkorean;3208 +cieucuparenkorean;321C +circle;25CB +circlemultiply;2297 +circleot;2299 +circleplus;2295 +circlepostalmark;3036 +circlewithlefthalfblack;25D0 +circlewithrighthalfblack;25D1 +circumflex;02C6 +circumflexbelowcmb;032D +circumflexcmb;0302 +clear;2327 +clickalveolar;01C2 +clickdental;01C0 +clicklateral;01C1 +clickretroflex;01C3 +club;2663 +clubsuitblack;2663 +clubsuitwhite;2667 +cmcubedsquare;33A4 +cmonospace;FF43 +cmsquaredsquare;33A0 +coarmenian;0581 +colon;003A +colonmonetary;20A1 +colonmonospace;FF1A +colonsign;20A1 +colonsmall;FE55 +colontriangularhalfmod;02D1 +colontriangularmod;02D0 +comma;002C +commaabovecmb;0313 +commaaboverightcmb;0315 +commaaccent;F6C3 +commaarabic;060C +commaarmenian;055D +commainferior;F6E1 +commamonospace;FF0C +commareversedabovecmb;0314 +commareversedmod;02BD +commasmall;FE50 +commasuperior;F6E2 +commaturnedabovecmb;0312 +commaturnedmod;02BB +compass;263C +congruent;2245 +contourintegral;222E +control;2303 +controlACK;0006 +controlBEL;0007 +controlBS;0008 +controlCAN;0018 +controlCR;000D +controlDC1;0011 +controlDC2;0012 +controlDC3;0013 +controlDC4;0014 +controlDEL;007F +controlDLE;0010 +controlEM;0019 +controlENQ;0005 +controlEOT;0004 +controlESC;001B +controlETB;0017 +controlETX;0003 +controlFF;000C +controlFS;001C +controlGS;001D +controlHT;0009 +controlLF;000A +controlNAK;0015 +controlRS;001E +controlSI;000F +controlSO;000E +controlSOT;0002 +controlSTX;0001 +controlSUB;001A +controlSYN;0016 +controlUS;001F +controlVT;000B +copyright;00A9 +copyrightsans;F8E9 +copyrightserif;F6D9 +cornerbracketleft;300C +cornerbracketlefthalfwidth;FF62 +cornerbracketleftvertical;FE41 +cornerbracketright;300D +cornerbracketrighthalfwidth;FF63 +cornerbracketrightvertical;FE42 +corporationsquare;337F +cosquare;33C7 +coverkgsquare;33C6 +cparen;249E +cruzeiro;20A2 +cstretched;0297 +curlyand;22CF +curlyor;22CE +currency;00A4 +cyrBreve;F6D1 +cyrFlex;F6D2 +cyrbreve;F6D4 +cyrflex;F6D5 +d;0064 +daarmenian;0564 +dabengali;09A6 +dadarabic;0636 +dadeva;0926 +dadfinalarabic;FEBE +dadinitialarabic;FEBF +dadmedialarabic;FEC0 +dagesh;05BC +dageshhebrew;05BC +dagger;2020 +daggerdbl;2021 +dagujarati;0AA6 +dagurmukhi;0A26 +dahiragana;3060 +dakatakana;30C0 +dalarabic;062F +dalet;05D3 +daletdagesh;FB33 +daletdageshhebrew;FB33 +dalethatafpatah;05D3 05B2 +dalethatafpatahhebrew;05D3 05B2 +dalethatafsegol;05D3 05B1 +dalethatafsegolhebrew;05D3 05B1 +dalethebrew;05D3 +dalethiriq;05D3 05B4 +dalethiriqhebrew;05D3 05B4 +daletholam;05D3 05B9 +daletholamhebrew;05D3 05B9 +daletpatah;05D3 05B7 +daletpatahhebrew;05D3 05B7 +daletqamats;05D3 05B8 +daletqamatshebrew;05D3 05B8 +daletqubuts;05D3 05BB +daletqubutshebrew;05D3 05BB +daletsegol;05D3 05B6 +daletsegolhebrew;05D3 05B6 +daletsheva;05D3 05B0 +daletshevahebrew;05D3 05B0 +dalettsere;05D3 05B5 +dalettserehebrew;05D3 05B5 +dalfinalarabic;FEAA +dammaarabic;064F +dammalowarabic;064F +dammatanaltonearabic;064C +dammatanarabic;064C +danda;0964 +dargahebrew;05A7 +dargalefthebrew;05A7 +dasiapneumatacyrilliccmb;0485 +dblGrave;F6D3 +dblanglebracketleft;300A +dblanglebracketleftvertical;FE3D +dblanglebracketright;300B +dblanglebracketrightvertical;FE3E +dblarchinvertedbelowcmb;032B +dblarrowleft;21D4 +dblarrowright;21D2 +dbldanda;0965 +dblgrave;F6D6 +dblgravecmb;030F +dblintegral;222C +dbllowline;2017 +dbllowlinecmb;0333 +dbloverlinecmb;033F +dblprimemod;02BA +dblverticalbar;2016 +dblverticallineabovecmb;030E +dbopomofo;3109 +dbsquare;33C8 +dcaron;010F +dcedilla;1E11 +dcircle;24D3 +dcircumflexbelow;1E13 +dcroat;0111 +ddabengali;09A1 +ddadeva;0921 +ddagujarati;0AA1 +ddagurmukhi;0A21 +ddalarabic;0688 +ddalfinalarabic;FB89 +dddhadeva;095C +ddhabengali;09A2 +ddhadeva;0922 +ddhagujarati;0AA2 +ddhagurmukhi;0A22 +ddotaccent;1E0B +ddotbelow;1E0D +decimalseparatorarabic;066B +decimalseparatorpersian;066B +decyrillic;0434 +degree;00B0 +dehihebrew;05AD +dehiragana;3067 +deicoptic;03EF +dekatakana;30C7 +deleteleft;232B +deleteright;2326 +delta;03B4 +deltaturned;018D +denominatorminusonenumeratorbengali;09F8 +dezh;02A4 +dhabengali;09A7 +dhadeva;0927 +dhagujarati;0AA7 +dhagurmukhi;0A27 +dhook;0257 +dialytikatonos;0385 +dialytikatonoscmb;0344 +diamond;2666 +diamondsuitwhite;2662 +dieresis;00A8 +dieresisacute;F6D7 +dieresisbelowcmb;0324 +dieresiscmb;0308 +dieresisgrave;F6D8 +dieresistonos;0385 +dihiragana;3062 +dikatakana;30C2 +dittomark;3003 +divide;00F7 +divides;2223 +divisionslash;2215 +djecyrillic;0452 +dkshade;2593 +dlinebelow;1E0F +dlsquare;3397 +dmacron;0111 +dmonospace;FF44 +dnblock;2584 +dochadathai;0E0E +dodekthai;0E14 +dohiragana;3069 +dokatakana;30C9 +dollar;0024 +dollarinferior;F6E3 +dollarmonospace;FF04 +dollaroldstyle;F724 +dollarsmall;FE69 +dollarsuperior;F6E4 +dong;20AB +dorusquare;3326 +dotaccent;02D9 +dotaccentcmb;0307 +dotbelowcmb;0323 +dotbelowcomb;0323 +dotkatakana;30FB +dotlessi;0131 +dotlessj;F6BE +dotlessjstrokehook;0284 +dotmath;22C5 +dottedcircle;25CC +doubleyodpatah;FB1F +doubleyodpatahhebrew;FB1F +downtackbelowcmb;031E +downtackmod;02D5 +dparen;249F +dsuperior;F6EB +dtail;0256 +dtopbar;018C +duhiragana;3065 +dukatakana;30C5 +dz;01F3 +dzaltone;02A3 +dzcaron;01C6 +dzcurl;02A5 +dzeabkhasiancyrillic;04E1 +dzecyrillic;0455 +dzhecyrillic;045F +e;0065 +eacute;00E9 +earth;2641 +ebengali;098F +ebopomofo;311C +ebreve;0115 +ecandradeva;090D +ecandragujarati;0A8D +ecandravowelsigndeva;0945 +ecandravowelsigngujarati;0AC5 +ecaron;011B +ecedillabreve;1E1D +echarmenian;0565 +echyiwnarmenian;0587 +ecircle;24D4 +ecircumflex;00EA +ecircumflexacute;1EBF +ecircumflexbelow;1E19 +ecircumflexdotbelow;1EC7 +ecircumflexgrave;1EC1 +ecircumflexhookabove;1EC3 +ecircumflextilde;1EC5 +ecyrillic;0454 +edblgrave;0205 +edeva;090F +edieresis;00EB +edot;0117 +edotaccent;0117 +edotbelow;1EB9 +eegurmukhi;0A0F +eematragurmukhi;0A47 +efcyrillic;0444 +egrave;00E8 +egujarati;0A8F +eharmenian;0567 +ehbopomofo;311D +ehiragana;3048 +ehookabove;1EBB +eibopomofo;311F +eight;0038 +eightarabic;0668 +eightbengali;09EE +eightcircle;2467 +eightcircleinversesansserif;2791 +eightdeva;096E +eighteencircle;2471 +eighteenparen;2485 +eighteenperiod;2499 +eightgujarati;0AEE +eightgurmukhi;0A6E +eighthackarabic;0668 +eighthangzhou;3028 +eighthnotebeamed;266B +eightideographicparen;3227 +eightinferior;2088 +eightmonospace;FF18 +eightoldstyle;F738 +eightparen;247B +eightperiod;248F +eightpersian;06F8 +eightroman;2177 +eightsuperior;2078 +eightthai;0E58 +einvertedbreve;0207 +eiotifiedcyrillic;0465 +ekatakana;30A8 +ekatakanahalfwidth;FF74 +ekonkargurmukhi;0A74 +ekorean;3154 +elcyrillic;043B +element;2208 +elevencircle;246A +elevenparen;247E +elevenperiod;2492 +elevenroman;217A +ellipsis;2026 +ellipsisvertical;22EE +emacron;0113 +emacronacute;1E17 +emacrongrave;1E15 +emcyrillic;043C +emdash;2014 +emdashvertical;FE31 +emonospace;FF45 +emphasismarkarmenian;055B +emptyset;2205 +enbopomofo;3123 +encyrillic;043D +endash;2013 +endashvertical;FE32 +endescendercyrillic;04A3 +eng;014B +engbopomofo;3125 +enghecyrillic;04A5 +enhookcyrillic;04C8 +enspace;2002 +eogonek;0119 +eokorean;3153 +eopen;025B +eopenclosed;029A +eopenreversed;025C +eopenreversedclosed;025E +eopenreversedhook;025D +eparen;24A0 +epsilon;03B5 +epsilontonos;03AD +equal;003D +equalmonospace;FF1D +equalsmall;FE66 +equalsuperior;207C +equivalence;2261 +erbopomofo;3126 +ercyrillic;0440 +ereversed;0258 +ereversedcyrillic;044D +escyrillic;0441 +esdescendercyrillic;04AB +esh;0283 +eshcurl;0286 +eshortdeva;090E +eshortvowelsigndeva;0946 +eshreversedloop;01AA +eshsquatreversed;0285 +esmallhiragana;3047 +esmallkatakana;30A7 +esmallkatakanahalfwidth;FF6A +estimated;212E +esuperior;F6EC +eta;03B7 +etarmenian;0568 +etatonos;03AE +eth;00F0 +etilde;1EBD +etildebelow;1E1B +etnahtafoukhhebrew;0591 +etnahtafoukhlefthebrew;0591 +etnahtahebrew;0591 +etnahtalefthebrew;0591 +eturned;01DD +eukorean;3161 +euro;20AC +evowelsignbengali;09C7 +evowelsigndeva;0947 +evowelsigngujarati;0AC7 +exclam;0021 +exclamarmenian;055C +exclamdbl;203C +exclamdown;00A1 +exclamdownsmall;F7A1 +exclammonospace;FF01 +exclamsmall;F721 +existential;2203 +ezh;0292 +ezhcaron;01EF +ezhcurl;0293 +ezhreversed;01B9 +ezhtail;01BA +f;0066 +fadeva;095E +fagurmukhi;0A5E +fahrenheit;2109 +fathaarabic;064E +fathalowarabic;064E +fathatanarabic;064B +fbopomofo;3108 +fcircle;24D5 +fdotaccent;1E1F +feharabic;0641 +feharmenian;0586 +fehfinalarabic;FED2 +fehinitialarabic;FED3 +fehmedialarabic;FED4 +feicoptic;03E5 +female;2640 +ff;FB00 +ffi;FB03 +ffl;FB04 +fi;FB01 +fifteencircle;246E +fifteenparen;2482 +fifteenperiod;2496 +figuredash;2012 +filledbox;25A0 +filledrect;25AC +finalkaf;05DA +finalkafdagesh;FB3A +finalkafdageshhebrew;FB3A +finalkafhebrew;05DA +finalkafqamats;05DA 05B8 +finalkafqamatshebrew;05DA 05B8 +finalkafsheva;05DA 05B0 +finalkafshevahebrew;05DA 05B0 +finalmem;05DD +finalmemhebrew;05DD +finalnun;05DF +finalnunhebrew;05DF +finalpe;05E3 +finalpehebrew;05E3 +finaltsadi;05E5 +finaltsadihebrew;05E5 +firsttonechinese;02C9 +fisheye;25C9 +fitacyrillic;0473 +five;0035 +fivearabic;0665 +fivebengali;09EB +fivecircle;2464 +fivecircleinversesansserif;278E +fivedeva;096B +fiveeighths;215D +fivegujarati;0AEB +fivegurmukhi;0A6B +fivehackarabic;0665 +fivehangzhou;3025 +fiveideographicparen;3224 +fiveinferior;2085 +fivemonospace;FF15 +fiveoldstyle;F735 +fiveparen;2478 +fiveperiod;248C +fivepersian;06F5 +fiveroman;2174 +fivesuperior;2075 +fivethai;0E55 +fl;FB02 +florin;0192 +fmonospace;FF46 +fmsquare;3399 +fofanthai;0E1F +fofathai;0E1D +fongmanthai;0E4F +forall;2200 +four;0034 +fourarabic;0664 +fourbengali;09EA +fourcircle;2463 +fourcircleinversesansserif;278D +fourdeva;096A +fourgujarati;0AEA +fourgurmukhi;0A6A +fourhackarabic;0664 +fourhangzhou;3024 +fourideographicparen;3223 +fourinferior;2084 +fourmonospace;FF14 +fournumeratorbengali;09F7 +fouroldstyle;F734 +fourparen;2477 +fourperiod;248B +fourpersian;06F4 +fourroman;2173 +foursuperior;2074 +fourteencircle;246D +fourteenparen;2481 +fourteenperiod;2495 +fourthai;0E54 +fourthtonechinese;02CB +fparen;24A1 +fraction;2044 +franc;20A3 +g;0067 +gabengali;0997 +gacute;01F5 +gadeva;0917 +gafarabic;06AF +gaffinalarabic;FB93 +gafinitialarabic;FB94 +gafmedialarabic;FB95 +gagujarati;0A97 +gagurmukhi;0A17 +gahiragana;304C +gakatakana;30AC +gamma;03B3 +gammalatinsmall;0263 +gammasuperior;02E0 +gangiacoptic;03EB +gbopomofo;310D +gbreve;011F +gcaron;01E7 +gcedilla;0123 +gcircle;24D6 +gcircumflex;011D +gcommaaccent;0123 +gdot;0121 +gdotaccent;0121 +gecyrillic;0433 +gehiragana;3052 +gekatakana;30B2 +geometricallyequal;2251 +gereshaccenthebrew;059C +gereshhebrew;05F3 +gereshmuqdamhebrew;059D +germandbls;00DF +gershayimaccenthebrew;059E +gershayimhebrew;05F4 +getamark;3013 +ghabengali;0998 +ghadarmenian;0572 +ghadeva;0918 +ghagujarati;0A98 +ghagurmukhi;0A18 +ghainarabic;063A +ghainfinalarabic;FECE +ghaininitialarabic;FECF +ghainmedialarabic;FED0 +ghemiddlehookcyrillic;0495 +ghestrokecyrillic;0493 +gheupturncyrillic;0491 +ghhadeva;095A +ghhagurmukhi;0A5A +ghook;0260 +ghzsquare;3393 +gihiragana;304E +gikatakana;30AE +gimarmenian;0563 +gimel;05D2 +gimeldagesh;FB32 +gimeldageshhebrew;FB32 +gimelhebrew;05D2 +gjecyrillic;0453 +glottalinvertedstroke;01BE +glottalstop;0294 +glottalstopinverted;0296 +glottalstopmod;02C0 +glottalstopreversed;0295 +glottalstopreversedmod;02C1 +glottalstopreversedsuperior;02E4 +glottalstopstroke;02A1 +glottalstopstrokereversed;02A2 +gmacron;1E21 +gmonospace;FF47 +gohiragana;3054 +gokatakana;30B4 +gparen;24A2 +gpasquare;33AC +gradient;2207 +grave;0060 +gravebelowcmb;0316 +gravecmb;0300 +gravecomb;0300 +gravedeva;0953 +gravelowmod;02CE +gravemonospace;FF40 +gravetonecmb;0340 +greater;003E +greaterequal;2265 +greaterequalorless;22DB +greatermonospace;FF1E +greaterorequivalent;2273 +greaterorless;2277 +greateroverequal;2267 +greatersmall;FE65 +gscript;0261 +gstroke;01E5 +guhiragana;3050 +guillemotleft;00AB +guillemotright;00BB +guilsinglleft;2039 +guilsinglright;203A +gukatakana;30B0 +guramusquare;3318 +gysquare;33C9 +h;0068 +haabkhasiancyrillic;04A9 +haaltonearabic;06C1 +habengali;09B9 +hadescendercyrillic;04B3 +hadeva;0939 +hagujarati;0AB9 +hagurmukhi;0A39 +haharabic;062D +hahfinalarabic;FEA2 +hahinitialarabic;FEA3 +hahiragana;306F +hahmedialarabic;FEA4 +haitusquare;332A +hakatakana;30CF +hakatakanahalfwidth;FF8A +halantgurmukhi;0A4D +hamzaarabic;0621 +hamzadammaarabic;0621 064F +hamzadammatanarabic;0621 064C +hamzafathaarabic;0621 064E +hamzafathatanarabic;0621 064B +hamzalowarabic;0621 +hamzalowkasraarabic;0621 0650 +hamzalowkasratanarabic;0621 064D +hamzasukunarabic;0621 0652 +hangulfiller;3164 +hardsigncyrillic;044A +harpoonleftbarbup;21BC +harpoonrightbarbup;21C0 +hasquare;33CA +hatafpatah;05B2 +hatafpatah16;05B2 +hatafpatah23;05B2 +hatafpatah2f;05B2 +hatafpatahhebrew;05B2 +hatafpatahnarrowhebrew;05B2 +hatafpatahquarterhebrew;05B2 +hatafpatahwidehebrew;05B2 +hatafqamats;05B3 +hatafqamats1b;05B3 +hatafqamats28;05B3 +hatafqamats34;05B3 +hatafqamatshebrew;05B3 +hatafqamatsnarrowhebrew;05B3 +hatafqamatsquarterhebrew;05B3 +hatafqamatswidehebrew;05B3 +hatafsegol;05B1 +hatafsegol17;05B1 +hatafsegol24;05B1 +hatafsegol30;05B1 +hatafsegolhebrew;05B1 +hatafsegolnarrowhebrew;05B1 +hatafsegolquarterhebrew;05B1 +hatafsegolwidehebrew;05B1 +hbar;0127 +hbopomofo;310F +hbrevebelow;1E2B +hcedilla;1E29 +hcircle;24D7 +hcircumflex;0125 +hdieresis;1E27 +hdotaccent;1E23 +hdotbelow;1E25 +he;05D4 +heart;2665 +heartsuitblack;2665 +heartsuitwhite;2661 +hedagesh;FB34 +hedageshhebrew;FB34 +hehaltonearabic;06C1 +heharabic;0647 +hehebrew;05D4 +hehfinalaltonearabic;FBA7 +hehfinalalttwoarabic;FEEA +hehfinalarabic;FEEA +hehhamzaabovefinalarabic;FBA5 +hehhamzaaboveisolatedarabic;FBA4 +hehinitialaltonearabic;FBA8 +hehinitialarabic;FEEB +hehiragana;3078 +hehmedialaltonearabic;FBA9 +hehmedialarabic;FEEC +heiseierasquare;337B +hekatakana;30D8 +hekatakanahalfwidth;FF8D +hekutaarusquare;3336 +henghook;0267 +herutusquare;3339 +het;05D7 +hethebrew;05D7 +hhook;0266 +hhooksuperior;02B1 +hieuhacirclekorean;327B +hieuhaparenkorean;321B +hieuhcirclekorean;326D +hieuhkorean;314E +hieuhparenkorean;320D +hihiragana;3072 +hikatakana;30D2 +hikatakanahalfwidth;FF8B +hiriq;05B4 +hiriq14;05B4 +hiriq21;05B4 +hiriq2d;05B4 +hiriqhebrew;05B4 +hiriqnarrowhebrew;05B4 +hiriqquarterhebrew;05B4 +hiriqwidehebrew;05B4 +hlinebelow;1E96 +hmonospace;FF48 +hoarmenian;0570 +hohipthai;0E2B +hohiragana;307B +hokatakana;30DB +hokatakanahalfwidth;FF8E +holam;05B9 +holam19;05B9 +holam26;05B9 +holam32;05B9 +holamhebrew;05B9 +holamnarrowhebrew;05B9 +holamquarterhebrew;05B9 +holamwidehebrew;05B9 +honokhukthai;0E2E +hookabovecomb;0309 +hookcmb;0309 +hookpalatalizedbelowcmb;0321 +hookretroflexbelowcmb;0322 +hoonsquare;3342 +horicoptic;03E9 +horizontalbar;2015 +horncmb;031B +hotsprings;2668 +house;2302 +hparen;24A3 +hsuperior;02B0 +hturned;0265 +huhiragana;3075 +huiitosquare;3333 +hukatakana;30D5 +hukatakanahalfwidth;FF8C +hungarumlaut;02DD +hungarumlautcmb;030B +hv;0195 +hyphen;002D +hypheninferior;F6E5 +hyphenmonospace;FF0D +hyphensmall;FE63 +hyphensuperior;F6E6 +hyphentwo;2010 +i;0069 +iacute;00ED +iacyrillic;044F +ibengali;0987 +ibopomofo;3127 +ibreve;012D +icaron;01D0 +icircle;24D8 +icircumflex;00EE +icyrillic;0456 +idblgrave;0209 +ideographearthcircle;328F +ideographfirecircle;328B +ideographicallianceparen;323F +ideographiccallparen;323A +ideographiccentrecircle;32A5 +ideographicclose;3006 +ideographiccomma;3001 +ideographiccommaleft;FF64 +ideographiccongratulationparen;3237 +ideographiccorrectcircle;32A3 +ideographicearthparen;322F +ideographicenterpriseparen;323D +ideographicexcellentcircle;329D +ideographicfestivalparen;3240 +ideographicfinancialcircle;3296 +ideographicfinancialparen;3236 +ideographicfireparen;322B +ideographichaveparen;3232 +ideographichighcircle;32A4 +ideographiciterationmark;3005 +ideographiclaborcircle;3298 +ideographiclaborparen;3238 +ideographicleftcircle;32A7 +ideographiclowcircle;32A6 +ideographicmedicinecircle;32A9 +ideographicmetalparen;322E +ideographicmoonparen;322A +ideographicnameparen;3234 +ideographicperiod;3002 +ideographicprintcircle;329E +ideographicreachparen;3243 +ideographicrepresentparen;3239 +ideographicresourceparen;323E +ideographicrightcircle;32A8 +ideographicsecretcircle;3299 +ideographicselfparen;3242 +ideographicsocietyparen;3233 +ideographicspace;3000 +ideographicspecialparen;3235 +ideographicstockparen;3231 +ideographicstudyparen;323B +ideographicsunparen;3230 +ideographicsuperviseparen;323C +ideographicwaterparen;322C +ideographicwoodparen;322D +ideographiczero;3007 +ideographmetalcircle;328E +ideographmooncircle;328A +ideographnamecircle;3294 +ideographsuncircle;3290 +ideographwatercircle;328C +ideographwoodcircle;328D +ideva;0907 +idieresis;00EF +idieresisacute;1E2F +idieresiscyrillic;04E5 +idotbelow;1ECB +iebrevecyrillic;04D7 +iecyrillic;0435 +ieungacirclekorean;3275 +ieungaparenkorean;3215 +ieungcirclekorean;3267 +ieungkorean;3147 +ieungparenkorean;3207 +igrave;00EC +igujarati;0A87 +igurmukhi;0A07 +ihiragana;3044 +ihookabove;1EC9 +iibengali;0988 +iicyrillic;0438 +iideva;0908 +iigujarati;0A88 +iigurmukhi;0A08 +iimatragurmukhi;0A40 +iinvertedbreve;020B +iishortcyrillic;0439 +iivowelsignbengali;09C0 +iivowelsigndeva;0940 +iivowelsigngujarati;0AC0 +ij;0133 +ikatakana;30A4 +ikatakanahalfwidth;FF72 +ikorean;3163 +ilde;02DC +iluyhebrew;05AC +imacron;012B +imacroncyrillic;04E3 +imageorapproximatelyequal;2253 +imatragurmukhi;0A3F +imonospace;FF49 +increment;2206 +infinity;221E +iniarmenian;056B +integral;222B +integralbottom;2321 +integralbt;2321 +integralex;F8F5 +integraltop;2320 +integraltp;2320 +intersection;2229 +intisquare;3305 +invbullet;25D8 +invcircle;25D9 +invsmileface;263B +iocyrillic;0451 +iogonek;012F +iota;03B9 +iotadieresis;03CA +iotadieresistonos;0390 +iotalatin;0269 +iotatonos;03AF +iparen;24A4 +irigurmukhi;0A72 +ismallhiragana;3043 +ismallkatakana;30A3 +ismallkatakanahalfwidth;FF68 +issharbengali;09FA +istroke;0268 +isuperior;F6ED +iterationhiragana;309D +iterationkatakana;30FD +itilde;0129 +itildebelow;1E2D +iubopomofo;3129 +iucyrillic;044E +ivowelsignbengali;09BF +ivowelsigndeva;093F +ivowelsigngujarati;0ABF +izhitsacyrillic;0475 +izhitsadblgravecyrillic;0477 +j;006A +jaarmenian;0571 +jabengali;099C +jadeva;091C +jagujarati;0A9C +jagurmukhi;0A1C +jbopomofo;3110 +jcaron;01F0 +jcircle;24D9 +jcircumflex;0135 +jcrossedtail;029D +jdotlessstroke;025F +jecyrillic;0458 +jeemarabic;062C +jeemfinalarabic;FE9E +jeeminitialarabic;FE9F +jeemmedialarabic;FEA0 +jeharabic;0698 +jehfinalarabic;FB8B +jhabengali;099D +jhadeva;091D +jhagujarati;0A9D +jhagurmukhi;0A1D +jheharmenian;057B +jis;3004 +jmonospace;FF4A +jparen;24A5 +jsuperior;02B2 +k;006B +kabashkircyrillic;04A1 +kabengali;0995 +kacute;1E31 +kacyrillic;043A +kadescendercyrillic;049B +kadeva;0915 +kaf;05DB +kafarabic;0643 +kafdagesh;FB3B +kafdageshhebrew;FB3B +kaffinalarabic;FEDA +kafhebrew;05DB +kafinitialarabic;FEDB +kafmedialarabic;FEDC +kafrafehebrew;FB4D +kagujarati;0A95 +kagurmukhi;0A15 +kahiragana;304B +kahookcyrillic;04C4 +kakatakana;30AB +kakatakanahalfwidth;FF76 +kappa;03BA +kappasymbolgreek;03F0 +kapyeounmieumkorean;3171 +kapyeounphieuphkorean;3184 +kapyeounpieupkorean;3178 +kapyeounssangpieupkorean;3179 +karoriisquare;330D +kashidaautoarabic;0640 +kashidaautonosidebearingarabic;0640 +kasmallkatakana;30F5 +kasquare;3384 +kasraarabic;0650 +kasratanarabic;064D +kastrokecyrillic;049F +katahiraprolongmarkhalfwidth;FF70 +kaverticalstrokecyrillic;049D +kbopomofo;310E +kcalsquare;3389 +kcaron;01E9 +kcedilla;0137 +kcircle;24DA +kcommaaccent;0137 +kdotbelow;1E33 +keharmenian;0584 +kehiragana;3051 +kekatakana;30B1 +kekatakanahalfwidth;FF79 +kenarmenian;056F +kesmallkatakana;30F6 +kgreenlandic;0138 +khabengali;0996 +khacyrillic;0445 +khadeva;0916 +khagujarati;0A96 +khagurmukhi;0A16 +khaharabic;062E +khahfinalarabic;FEA6 +khahinitialarabic;FEA7 +khahmedialarabic;FEA8 +kheicoptic;03E7 +khhadeva;0959 +khhagurmukhi;0A59 +khieukhacirclekorean;3278 +khieukhaparenkorean;3218 +khieukhcirclekorean;326A +khieukhkorean;314B +khieukhparenkorean;320A +khokhaithai;0E02 +khokhonthai;0E05 +khokhuatthai;0E03 +khokhwaithai;0E04 +khomutthai;0E5B +khook;0199 +khorakhangthai;0E06 +khzsquare;3391 +kihiragana;304D +kikatakana;30AD +kikatakanahalfwidth;FF77 +kiroguramusquare;3315 +kiromeetorusquare;3316 +kirosquare;3314 +kiyeokacirclekorean;326E +kiyeokaparenkorean;320E +kiyeokcirclekorean;3260 +kiyeokkorean;3131 +kiyeokparenkorean;3200 +kiyeoksioskorean;3133 +kjecyrillic;045C +klinebelow;1E35 +klsquare;3398 +kmcubedsquare;33A6 +kmonospace;FF4B +kmsquaredsquare;33A2 +kohiragana;3053 +kohmsquare;33C0 +kokaithai;0E01 +kokatakana;30B3 +kokatakanahalfwidth;FF7A +kooposquare;331E +koppacyrillic;0481 +koreanstandardsymbol;327F +koroniscmb;0343 +kparen;24A6 +kpasquare;33AA +ksicyrillic;046F +ktsquare;33CF +kturned;029E +kuhiragana;304F +kukatakana;30AF +kukatakanahalfwidth;FF78 +kvsquare;33B8 +kwsquare;33BE +l;006C +labengali;09B2 +lacute;013A +ladeva;0932 +lagujarati;0AB2 +lagurmukhi;0A32 +lakkhangyaothai;0E45 +lamaleffinalarabic;FEFC +lamalefhamzaabovefinalarabic;FEF8 +lamalefhamzaaboveisolatedarabic;FEF7 +lamalefhamzabelowfinalarabic;FEFA +lamalefhamzabelowisolatedarabic;FEF9 +lamalefisolatedarabic;FEFB +lamalefmaddaabovefinalarabic;FEF6 +lamalefmaddaaboveisolatedarabic;FEF5 +lamarabic;0644 +lambda;03BB +lambdastroke;019B +lamed;05DC +lameddagesh;FB3C +lameddageshhebrew;FB3C +lamedhebrew;05DC +lamedholam;05DC 05B9 +lamedholamdagesh;05DC 05B9 05BC +lamedholamdageshhebrew;05DC 05B9 05BC +lamedholamhebrew;05DC 05B9 +lamfinalarabic;FEDE +lamhahinitialarabic;FCCA +laminitialarabic;FEDF +lamjeeminitialarabic;FCC9 +lamkhahinitialarabic;FCCB +lamlamhehisolatedarabic;FDF2 +lammedialarabic;FEE0 +lammeemhahinitialarabic;FD88 +lammeeminitialarabic;FCCC +lammeemjeeminitialarabic;FEDF FEE4 FEA0 +lammeemkhahinitialarabic;FEDF FEE4 FEA8 +largecircle;25EF +lbar;019A +lbelt;026C +lbopomofo;310C +lcaron;013E +lcedilla;013C +lcircle;24DB +lcircumflexbelow;1E3D +lcommaaccent;013C +ldot;0140 +ldotaccent;0140 +ldotbelow;1E37 +ldotbelowmacron;1E39 +leftangleabovecmb;031A +lefttackbelowcmb;0318 +less;003C +lessequal;2264 +lessequalorgreater;22DA +lessmonospace;FF1C +lessorequivalent;2272 +lessorgreater;2276 +lessoverequal;2266 +lesssmall;FE64 +lezh;026E +lfblock;258C +lhookretroflex;026D +lira;20A4 +liwnarmenian;056C +lj;01C9 +ljecyrillic;0459 +ll;F6C0 +lladeva;0933 +llagujarati;0AB3 +llinebelow;1E3B +llladeva;0934 +llvocalicbengali;09E1 +llvocalicdeva;0961 +llvocalicvowelsignbengali;09E3 +llvocalicvowelsigndeva;0963 +lmiddletilde;026B +lmonospace;FF4C +lmsquare;33D0 +lochulathai;0E2C +logicaland;2227 +logicalnot;00AC +logicalnotreversed;2310 +logicalor;2228 +lolingthai;0E25 +longs;017F +lowlinecenterline;FE4E +lowlinecmb;0332 +lowlinedashed;FE4D +lozenge;25CA +lparen;24A7 +lslash;0142 +lsquare;2113 +lsuperior;F6EE +ltshade;2591 +luthai;0E26 +lvocalicbengali;098C +lvocalicdeva;090C +lvocalicvowelsignbengali;09E2 +lvocalicvowelsigndeva;0962 +lxsquare;33D3 +m;006D +mabengali;09AE +macron;00AF +macronbelowcmb;0331 +macroncmb;0304 +macronlowmod;02CD +macronmonospace;FFE3 +macute;1E3F +madeva;092E +magujarati;0AAE +magurmukhi;0A2E +mahapakhhebrew;05A4 +mahapakhlefthebrew;05A4 +mahiragana;307E +maichattawalowleftthai;F895 +maichattawalowrightthai;F894 +maichattawathai;0E4B +maichattawaupperleftthai;F893 +maieklowleftthai;F88C +maieklowrightthai;F88B +maiekthai;0E48 +maiekupperleftthai;F88A +maihanakatleftthai;F884 +maihanakatthai;0E31 +maitaikhuleftthai;F889 +maitaikhuthai;0E47 +maitholowleftthai;F88F +maitholowrightthai;F88E +maithothai;0E49 +maithoupperleftthai;F88D +maitrilowleftthai;F892 +maitrilowrightthai;F891 +maitrithai;0E4A +maitriupperleftthai;F890 +maiyamokthai;0E46 +makatakana;30DE +makatakanahalfwidth;FF8F +male;2642 +mansyonsquare;3347 +maqafhebrew;05BE +mars;2642 +masoracirclehebrew;05AF +masquare;3383 +mbopomofo;3107 +mbsquare;33D4 +mcircle;24DC +mcubedsquare;33A5 +mdotaccent;1E41 +mdotbelow;1E43 +meemarabic;0645 +meemfinalarabic;FEE2 +meeminitialarabic;FEE3 +meemmedialarabic;FEE4 +meemmeeminitialarabic;FCD1 +meemmeemisolatedarabic;FC48 +meetorusquare;334D +mehiragana;3081 +meizierasquare;337E +mekatakana;30E1 +mekatakanahalfwidth;FF92 +mem;05DE +memdagesh;FB3E +memdageshhebrew;FB3E +memhebrew;05DE +menarmenian;0574 +merkhahebrew;05A5 +merkhakefulahebrew;05A6 +merkhakefulalefthebrew;05A6 +merkhalefthebrew;05A5 +mhook;0271 +mhzsquare;3392 +middledotkatakanahalfwidth;FF65 +middot;00B7 +mieumacirclekorean;3272 +mieumaparenkorean;3212 +mieumcirclekorean;3264 +mieumkorean;3141 +mieumpansioskorean;3170 +mieumparenkorean;3204 +mieumpieupkorean;316E +mieumsioskorean;316F +mihiragana;307F +mikatakana;30DF +mikatakanahalfwidth;FF90 +minus;2212 +minusbelowcmb;0320 +minuscircle;2296 +minusmod;02D7 +minusplus;2213 +minute;2032 +miribaarusquare;334A +mirisquare;3349 +mlonglegturned;0270 +mlsquare;3396 +mmcubedsquare;33A3 +mmonospace;FF4D +mmsquaredsquare;339F +mohiragana;3082 +mohmsquare;33C1 +mokatakana;30E2 +mokatakanahalfwidth;FF93 +molsquare;33D6 +momathai;0E21 +moverssquare;33A7 +moverssquaredsquare;33A8 +mparen;24A8 +mpasquare;33AB +mssquare;33B3 +msuperior;F6EF +mturned;026F +mu;00B5 +mu1;00B5 +muasquare;3382 +muchgreater;226B +muchless;226A +mufsquare;338C +mugreek;03BC +mugsquare;338D +muhiragana;3080 +mukatakana;30E0 +mukatakanahalfwidth;FF91 +mulsquare;3395 +multiply;00D7 +mumsquare;339B +munahhebrew;05A3 +munahlefthebrew;05A3 +musicalnote;266A +musicalnotedbl;266B +musicflatsign;266D +musicsharpsign;266F +mussquare;33B2 +muvsquare;33B6 +muwsquare;33BC +mvmegasquare;33B9 +mvsquare;33B7 +mwmegasquare;33BF +mwsquare;33BD +n;006E +nabengali;09A8 +nabla;2207 +nacute;0144 +nadeva;0928 +nagujarati;0AA8 +nagurmukhi;0A28 +nahiragana;306A +nakatakana;30CA +nakatakanahalfwidth;FF85 +napostrophe;0149 +nasquare;3381 +nbopomofo;310B +nbspace;00A0 +ncaron;0148 +ncedilla;0146 +ncircle;24DD +ncircumflexbelow;1E4B +ncommaaccent;0146 +ndotaccent;1E45 +ndotbelow;1E47 +nehiragana;306D +nekatakana;30CD +nekatakanahalfwidth;FF88 +newsheqelsign;20AA +nfsquare;338B +ngabengali;0999 +ngadeva;0919 +ngagujarati;0A99 +ngagurmukhi;0A19 +ngonguthai;0E07 +nhiragana;3093 +nhookleft;0272 +nhookretroflex;0273 +nieunacirclekorean;326F +nieunaparenkorean;320F +nieuncieuckorean;3135 +nieuncirclekorean;3261 +nieunhieuhkorean;3136 +nieunkorean;3134 +nieunpansioskorean;3168 +nieunparenkorean;3201 +nieunsioskorean;3167 +nieuntikeutkorean;3166 +nihiragana;306B +nikatakana;30CB +nikatakanahalfwidth;FF86 +nikhahitleftthai;F899 +nikhahitthai;0E4D +nine;0039 +ninearabic;0669 +ninebengali;09EF +ninecircle;2468 +ninecircleinversesansserif;2792 +ninedeva;096F +ninegujarati;0AEF +ninegurmukhi;0A6F +ninehackarabic;0669 +ninehangzhou;3029 +nineideographicparen;3228 +nineinferior;2089 +ninemonospace;FF19 +nineoldstyle;F739 +nineparen;247C +nineperiod;2490 +ninepersian;06F9 +nineroman;2178 +ninesuperior;2079 +nineteencircle;2472 +nineteenparen;2486 +nineteenperiod;249A +ninethai;0E59 +nj;01CC +njecyrillic;045A +nkatakana;30F3 +nkatakanahalfwidth;FF9D +nlegrightlong;019E +nlinebelow;1E49 +nmonospace;FF4E +nmsquare;339A +nnabengali;09A3 +nnadeva;0923 +nnagujarati;0AA3 +nnagurmukhi;0A23 +nnnadeva;0929 +nohiragana;306E +nokatakana;30CE +nokatakanahalfwidth;FF89 +nonbreakingspace;00A0 +nonenthai;0E13 +nonuthai;0E19 +noonarabic;0646 +noonfinalarabic;FEE6 +noonghunnaarabic;06BA +noonghunnafinalarabic;FB9F +noonhehinitialarabic;FEE7 FEEC +nooninitialarabic;FEE7 +noonjeeminitialarabic;FCD2 +noonjeemisolatedarabic;FC4B +noonmedialarabic;FEE8 +noonmeeminitialarabic;FCD5 +noonmeemisolatedarabic;FC4E +noonnoonfinalarabic;FC8D +notcontains;220C +notelement;2209 +notelementof;2209 +notequal;2260 +notgreater;226F +notgreaternorequal;2271 +notgreaternorless;2279 +notidentical;2262 +notless;226E +notlessnorequal;2270 +notparallel;2226 +notprecedes;2280 +notsubset;2284 +notsucceeds;2281 +notsuperset;2285 +nowarmenian;0576 +nparen;24A9 +nssquare;33B1 +nsuperior;207F +ntilde;00F1 +nu;03BD +nuhiragana;306C +nukatakana;30CC +nukatakanahalfwidth;FF87 +nuktabengali;09BC +nuktadeva;093C +nuktagujarati;0ABC +nuktagurmukhi;0A3C +numbersign;0023 +numbersignmonospace;FF03 +numbersignsmall;FE5F +numeralsigngreek;0374 +numeralsignlowergreek;0375 +numero;2116 +nun;05E0 +nundagesh;FB40 +nundageshhebrew;FB40 +nunhebrew;05E0 +nvsquare;33B5 +nwsquare;33BB +nyabengali;099E +nyadeva;091E +nyagujarati;0A9E +nyagurmukhi;0A1E +o;006F +oacute;00F3 +oangthai;0E2D +obarred;0275 +obarredcyrillic;04E9 +obarreddieresiscyrillic;04EB +obengali;0993 +obopomofo;311B +obreve;014F +ocandradeva;0911 +ocandragujarati;0A91 +ocandravowelsigndeva;0949 +ocandravowelsigngujarati;0AC9 +ocaron;01D2 +ocircle;24DE +ocircumflex;00F4 +ocircumflexacute;1ED1 +ocircumflexdotbelow;1ED9 +ocircumflexgrave;1ED3 +ocircumflexhookabove;1ED5 +ocircumflextilde;1ED7 +ocyrillic;043E +odblacute;0151 +odblgrave;020D +odeva;0913 +odieresis;00F6 +odieresiscyrillic;04E7 +odotbelow;1ECD +oe;0153 +oekorean;315A +ogonek;02DB +ogonekcmb;0328 +ograve;00F2 +ogujarati;0A93 +oharmenian;0585 +ohiragana;304A +ohookabove;1ECF +ohorn;01A1 +ohornacute;1EDB +ohorndotbelow;1EE3 +ohorngrave;1EDD +ohornhookabove;1EDF +ohorntilde;1EE1 +ohungarumlaut;0151 +oi;01A3 +oinvertedbreve;020F +okatakana;30AA +okatakanahalfwidth;FF75 +okorean;3157 +olehebrew;05AB +omacron;014D +omacronacute;1E53 +omacrongrave;1E51 +omdeva;0950 +omega;03C9 +omega1;03D6 +omegacyrillic;0461 +omegalatinclosed;0277 +omegaroundcyrillic;047B +omegatitlocyrillic;047D +omegatonos;03CE +omgujarati;0AD0 +omicron;03BF +omicrontonos;03CC +omonospace;FF4F +one;0031 +onearabic;0661 +onebengali;09E7 +onecircle;2460 +onecircleinversesansserif;278A +onedeva;0967 +onedotenleader;2024 +oneeighth;215B +onefitted;F6DC +onegujarati;0AE7 +onegurmukhi;0A67 +onehackarabic;0661 +onehalf;00BD +onehangzhou;3021 +oneideographicparen;3220 +oneinferior;2081 +onemonospace;FF11 +onenumeratorbengali;09F4 +oneoldstyle;F731 +oneparen;2474 +oneperiod;2488 +onepersian;06F1 +onequarter;00BC +oneroman;2170 +onesuperior;00B9 +onethai;0E51 +onethird;2153 +oogonek;01EB +oogonekmacron;01ED +oogurmukhi;0A13 +oomatragurmukhi;0A4B +oopen;0254 +oparen;24AA +openbullet;25E6 +option;2325 +ordfeminine;00AA +ordmasculine;00BA +orthogonal;221F +oshortdeva;0912 +oshortvowelsigndeva;094A +oslash;00F8 +oslashacute;01FF +osmallhiragana;3049 +osmallkatakana;30A9 +osmallkatakanahalfwidth;FF6B +ostrokeacute;01FF +osuperior;F6F0 +otcyrillic;047F +otilde;00F5 +otildeacute;1E4D +otildedieresis;1E4F +oubopomofo;3121 +overline;203E +overlinecenterline;FE4A +overlinecmb;0305 +overlinedashed;FE49 +overlinedblwavy;FE4C +overlinewavy;FE4B +overscore;00AF +ovowelsignbengali;09CB +ovowelsigndeva;094B +ovowelsigngujarati;0ACB +p;0070 +paampssquare;3380 +paasentosquare;332B +pabengali;09AA +pacute;1E55 +padeva;092A +pagedown;21DF +pageup;21DE +pagujarati;0AAA +pagurmukhi;0A2A +pahiragana;3071 +paiyannoithai;0E2F +pakatakana;30D1 +palatalizationcyrilliccmb;0484 +palochkacyrillic;04C0 +pansioskorean;317F +paragraph;00B6 +parallel;2225 +parenleft;0028 +parenleftaltonearabic;FD3E +parenleftbt;F8ED +parenleftex;F8EC +parenleftinferior;208D +parenleftmonospace;FF08 +parenleftsmall;FE59 +parenleftsuperior;207D +parenlefttp;F8EB +parenleftvertical;FE35 +parenright;0029 +parenrightaltonearabic;FD3F +parenrightbt;F8F8 +parenrightex;F8F7 +parenrightinferior;208E +parenrightmonospace;FF09 +parenrightsmall;FE5A +parenrightsuperior;207E +parenrighttp;F8F6 +parenrightvertical;FE36 +partialdiff;2202 +paseqhebrew;05C0 +pashtahebrew;0599 +pasquare;33A9 +patah;05B7 +patah11;05B7 +patah1d;05B7 +patah2a;05B7 +patahhebrew;05B7 +patahnarrowhebrew;05B7 +patahquarterhebrew;05B7 +patahwidehebrew;05B7 +pazerhebrew;05A1 +pbopomofo;3106 +pcircle;24DF +pdotaccent;1E57 +pe;05E4 +pecyrillic;043F +pedagesh;FB44 +pedageshhebrew;FB44 +peezisquare;333B +pefinaldageshhebrew;FB43 +peharabic;067E +peharmenian;057A +pehebrew;05E4 +pehfinalarabic;FB57 +pehinitialarabic;FB58 +pehiragana;307A +pehmedialarabic;FB59 +pekatakana;30DA +pemiddlehookcyrillic;04A7 +perafehebrew;FB4E +percent;0025 +percentarabic;066A +percentmonospace;FF05 +percentsmall;FE6A +period;002E +periodarmenian;0589 +periodcentered;00B7 +periodhalfwidth;FF61 +periodinferior;F6E7 +periodmonospace;FF0E +periodsmall;FE52 +periodsuperior;F6E8 +perispomenigreekcmb;0342 +perpendicular;22A5 +perthousand;2030 +peseta;20A7 +pfsquare;338A +phabengali;09AB +phadeva;092B +phagujarati;0AAB +phagurmukhi;0A2B +phi;03C6 +phi1;03D5 +phieuphacirclekorean;327A +phieuphaparenkorean;321A +phieuphcirclekorean;326C +phieuphkorean;314D +phieuphparenkorean;320C +philatin;0278 +phinthuthai;0E3A +phisymbolgreek;03D5 +phook;01A5 +phophanthai;0E1E +phophungthai;0E1C +phosamphaothai;0E20 +pi;03C0 +pieupacirclekorean;3273 +pieupaparenkorean;3213 +pieupcieuckorean;3176 +pieupcirclekorean;3265 +pieupkiyeokkorean;3172 +pieupkorean;3142 +pieupparenkorean;3205 +pieupsioskiyeokkorean;3174 +pieupsioskorean;3144 +pieupsiostikeutkorean;3175 +pieupthieuthkorean;3177 +pieuptikeutkorean;3173 +pihiragana;3074 +pikatakana;30D4 +pisymbolgreek;03D6 +piwrarmenian;0583 +plus;002B +plusbelowcmb;031F +pluscircle;2295 +plusminus;00B1 +plusmod;02D6 +plusmonospace;FF0B +plussmall;FE62 +plussuperior;207A +pmonospace;FF50 +pmsquare;33D8 +pohiragana;307D +pointingindexdownwhite;261F +pointingindexleftwhite;261C +pointingindexrightwhite;261E +pointingindexupwhite;261D +pokatakana;30DD +poplathai;0E1B +postalmark;3012 +postalmarkface;3020 +pparen;24AB +precedes;227A +prescription;211E +primemod;02B9 +primereversed;2035 +product;220F +projective;2305 +prolongedkana;30FC +propellor;2318 +propersubset;2282 +propersuperset;2283 +proportion;2237 +proportional;221D +psi;03C8 +psicyrillic;0471 +psilipneumatacyrilliccmb;0486 +pssquare;33B0 +puhiragana;3077 +pukatakana;30D7 +pvsquare;33B4 +pwsquare;33BA +q;0071 +qadeva;0958 +qadmahebrew;05A8 +qafarabic;0642 +qaffinalarabic;FED6 +qafinitialarabic;FED7 +qafmedialarabic;FED8 +qamats;05B8 +qamats10;05B8 +qamats1a;05B8 +qamats1c;05B8 +qamats27;05B8 +qamats29;05B8 +qamats33;05B8 +qamatsde;05B8 +qamatshebrew;05B8 +qamatsnarrowhebrew;05B8 +qamatsqatanhebrew;05B8 +qamatsqatannarrowhebrew;05B8 +qamatsqatanquarterhebrew;05B8 +qamatsqatanwidehebrew;05B8 +qamatsquarterhebrew;05B8 +qamatswidehebrew;05B8 +qarneyparahebrew;059F +qbopomofo;3111 +qcircle;24E0 +qhook;02A0 +qmonospace;FF51 +qof;05E7 +qofdagesh;FB47 +qofdageshhebrew;FB47 +qofhatafpatah;05E7 05B2 +qofhatafpatahhebrew;05E7 05B2 +qofhatafsegol;05E7 05B1 +qofhatafsegolhebrew;05E7 05B1 +qofhebrew;05E7 +qofhiriq;05E7 05B4 +qofhiriqhebrew;05E7 05B4 +qofholam;05E7 05B9 +qofholamhebrew;05E7 05B9 +qofpatah;05E7 05B7 +qofpatahhebrew;05E7 05B7 +qofqamats;05E7 05B8 +qofqamatshebrew;05E7 05B8 +qofqubuts;05E7 05BB +qofqubutshebrew;05E7 05BB +qofsegol;05E7 05B6 +qofsegolhebrew;05E7 05B6 +qofsheva;05E7 05B0 +qofshevahebrew;05E7 05B0 +qoftsere;05E7 05B5 +qoftserehebrew;05E7 05B5 +qparen;24AC +quarternote;2669 +qubuts;05BB +qubuts18;05BB +qubuts25;05BB +qubuts31;05BB +qubutshebrew;05BB +qubutsnarrowhebrew;05BB +qubutsquarterhebrew;05BB +qubutswidehebrew;05BB +question;003F +questionarabic;061F +questionarmenian;055E +questiondown;00BF +questiondownsmall;F7BF +questiongreek;037E +questionmonospace;FF1F +questionsmall;F73F +quotedbl;0022 +quotedblbase;201E +quotedblleft;201C +quotedblmonospace;FF02 +quotedblprime;301E +quotedblprimereversed;301D +quotedblright;201D +quoteleft;2018 +quoteleftreversed;201B +quotereversed;201B +quoteright;2019 +quoterightn;0149 +quotesinglbase;201A +quotesingle;0027 +quotesinglemonospace;FF07 +r;0072 +raarmenian;057C +rabengali;09B0 +racute;0155 +radeva;0930 +radical;221A +radicalex;F8E5 +radoverssquare;33AE +radoverssquaredsquare;33AF +radsquare;33AD +rafe;05BF +rafehebrew;05BF +ragujarati;0AB0 +ragurmukhi;0A30 +rahiragana;3089 +rakatakana;30E9 +rakatakanahalfwidth;FF97 +ralowerdiagonalbengali;09F1 +ramiddlediagonalbengali;09F0 +ramshorn;0264 +ratio;2236 +rbopomofo;3116 +rcaron;0159 +rcedilla;0157 +rcircle;24E1 +rcommaaccent;0157 +rdblgrave;0211 +rdotaccent;1E59 +rdotbelow;1E5B +rdotbelowmacron;1E5D +referencemark;203B +reflexsubset;2286 +reflexsuperset;2287 +registered;00AE +registersans;F8E8 +registerserif;F6DA +reharabic;0631 +reharmenian;0580 +rehfinalarabic;FEAE +rehiragana;308C +rehyehaleflamarabic;0631 FEF3 FE8E 0644 +rekatakana;30EC +rekatakanahalfwidth;FF9A +resh;05E8 +reshdageshhebrew;FB48 +reshhatafpatah;05E8 05B2 +reshhatafpatahhebrew;05E8 05B2 +reshhatafsegol;05E8 05B1 +reshhatafsegolhebrew;05E8 05B1 +reshhebrew;05E8 +reshhiriq;05E8 05B4 +reshhiriqhebrew;05E8 05B4 +reshholam;05E8 05B9 +reshholamhebrew;05E8 05B9 +reshpatah;05E8 05B7 +reshpatahhebrew;05E8 05B7 +reshqamats;05E8 05B8 +reshqamatshebrew;05E8 05B8 +reshqubuts;05E8 05BB +reshqubutshebrew;05E8 05BB +reshsegol;05E8 05B6 +reshsegolhebrew;05E8 05B6 +reshsheva;05E8 05B0 +reshshevahebrew;05E8 05B0 +reshtsere;05E8 05B5 +reshtserehebrew;05E8 05B5 +reversedtilde;223D +reviahebrew;0597 +reviamugrashhebrew;0597 +revlogicalnot;2310 +rfishhook;027E +rfishhookreversed;027F +rhabengali;09DD +rhadeva;095D +rho;03C1 +rhook;027D +rhookturned;027B +rhookturnedsuperior;02B5 +rhosymbolgreek;03F1 +rhotichookmod;02DE +rieulacirclekorean;3271 +rieulaparenkorean;3211 +rieulcirclekorean;3263 +rieulhieuhkorean;3140 +rieulkiyeokkorean;313A +rieulkiyeoksioskorean;3169 +rieulkorean;3139 +rieulmieumkorean;313B +rieulpansioskorean;316C +rieulparenkorean;3203 +rieulphieuphkorean;313F +rieulpieupkorean;313C +rieulpieupsioskorean;316B +rieulsioskorean;313D +rieulthieuthkorean;313E +rieultikeutkorean;316A +rieulyeorinhieuhkorean;316D +rightangle;221F +righttackbelowcmb;0319 +righttriangle;22BF +rihiragana;308A +rikatakana;30EA +rikatakanahalfwidth;FF98 +ring;02DA +ringbelowcmb;0325 +ringcmb;030A +ringhalfleft;02BF +ringhalfleftarmenian;0559 +ringhalfleftbelowcmb;031C +ringhalfleftcentered;02D3 +ringhalfright;02BE +ringhalfrightbelowcmb;0339 +ringhalfrightcentered;02D2 +rinvertedbreve;0213 +rittorusquare;3351 +rlinebelow;1E5F +rlongleg;027C +rlonglegturned;027A +rmonospace;FF52 +rohiragana;308D +rokatakana;30ED +rokatakanahalfwidth;FF9B +roruathai;0E23 +rparen;24AD +rrabengali;09DC +rradeva;0931 +rragurmukhi;0A5C +rreharabic;0691 +rrehfinalarabic;FB8D +rrvocalicbengali;09E0 +rrvocalicdeva;0960 +rrvocalicgujarati;0AE0 +rrvocalicvowelsignbengali;09C4 +rrvocalicvowelsigndeva;0944 +rrvocalicvowelsigngujarati;0AC4 +rsuperior;F6F1 +rtblock;2590 +rturned;0279 +rturnedsuperior;02B4 +ruhiragana;308B +rukatakana;30EB +rukatakanahalfwidth;FF99 +rupeemarkbengali;09F2 +rupeesignbengali;09F3 +rupiah;F6DD +ruthai;0E24 +rvocalicbengali;098B +rvocalicdeva;090B +rvocalicgujarati;0A8B +rvocalicvowelsignbengali;09C3 +rvocalicvowelsigndeva;0943 +rvocalicvowelsigngujarati;0AC3 +s;0073 +sabengali;09B8 +sacute;015B +sacutedotaccent;1E65 +sadarabic;0635 +sadeva;0938 +sadfinalarabic;FEBA +sadinitialarabic;FEBB +sadmedialarabic;FEBC +sagujarati;0AB8 +sagurmukhi;0A38 +sahiragana;3055 +sakatakana;30B5 +sakatakanahalfwidth;FF7B +sallallahoualayhewasallamarabic;FDFA +samekh;05E1 +samekhdagesh;FB41 +samekhdageshhebrew;FB41 +samekhhebrew;05E1 +saraaathai;0E32 +saraaethai;0E41 +saraaimaimalaithai;0E44 +saraaimaimuanthai;0E43 +saraamthai;0E33 +saraathai;0E30 +saraethai;0E40 +saraiileftthai;F886 +saraiithai;0E35 +saraileftthai;F885 +saraithai;0E34 +saraothai;0E42 +saraueeleftthai;F888 +saraueethai;0E37 +saraueleftthai;F887 +sarauethai;0E36 +sarauthai;0E38 +sarauuthai;0E39 +sbopomofo;3119 +scaron;0161 +scarondotaccent;1E67 +scedilla;015F +schwa;0259 +schwacyrillic;04D9 +schwadieresiscyrillic;04DB +schwahook;025A +scircle;24E2 +scircumflex;015D +scommaaccent;0219 +sdotaccent;1E61 +sdotbelow;1E63 +sdotbelowdotaccent;1E69 +seagullbelowcmb;033C +second;2033 +secondtonechinese;02CA +section;00A7 +seenarabic;0633 +seenfinalarabic;FEB2 +seeninitialarabic;FEB3 +seenmedialarabic;FEB4 +segol;05B6 +segol13;05B6 +segol1f;05B6 +segol2c;05B6 +segolhebrew;05B6 +segolnarrowhebrew;05B6 +segolquarterhebrew;05B6 +segoltahebrew;0592 +segolwidehebrew;05B6 +seharmenian;057D +sehiragana;305B +sekatakana;30BB +sekatakanahalfwidth;FF7E +semicolon;003B +semicolonarabic;061B +semicolonmonospace;FF1B +semicolonsmall;FE54 +semivoicedmarkkana;309C +semivoicedmarkkanahalfwidth;FF9F +sentisquare;3322 +sentosquare;3323 +seven;0037 +sevenarabic;0667 +sevenbengali;09ED +sevencircle;2466 +sevencircleinversesansserif;2790 +sevendeva;096D +seveneighths;215E +sevengujarati;0AED +sevengurmukhi;0A6D +sevenhackarabic;0667 +sevenhangzhou;3027 +sevenideographicparen;3226 +seveninferior;2087 +sevenmonospace;FF17 +sevenoldstyle;F737 +sevenparen;247A +sevenperiod;248E +sevenpersian;06F7 +sevenroman;2176 +sevensuperior;2077 +seventeencircle;2470 +seventeenparen;2484 +seventeenperiod;2498 +seventhai;0E57 +sfthyphen;00AD +shaarmenian;0577 +shabengali;09B6 +shacyrillic;0448 +shaddaarabic;0651 +shaddadammaarabic;FC61 +shaddadammatanarabic;FC5E +shaddafathaarabic;FC60 +shaddafathatanarabic;0651 064B +shaddakasraarabic;FC62 +shaddakasratanarabic;FC5F +shade;2592 +shadedark;2593 +shadelight;2591 +shademedium;2592 +shadeva;0936 +shagujarati;0AB6 +shagurmukhi;0A36 +shalshelethebrew;0593 +shbopomofo;3115 +shchacyrillic;0449 +sheenarabic;0634 +sheenfinalarabic;FEB6 +sheeninitialarabic;FEB7 +sheenmedialarabic;FEB8 +sheicoptic;03E3 +sheqel;20AA +sheqelhebrew;20AA +sheva;05B0 +sheva115;05B0 +sheva15;05B0 +sheva22;05B0 +sheva2e;05B0 +shevahebrew;05B0 +shevanarrowhebrew;05B0 +shevaquarterhebrew;05B0 +shevawidehebrew;05B0 +shhacyrillic;04BB +shimacoptic;03ED +shin;05E9 +shindagesh;FB49 +shindageshhebrew;FB49 +shindageshshindot;FB2C +shindageshshindothebrew;FB2C +shindageshsindot;FB2D +shindageshsindothebrew;FB2D +shindothebrew;05C1 +shinhebrew;05E9 +shinshindot;FB2A +shinshindothebrew;FB2A +shinsindot;FB2B +shinsindothebrew;FB2B +shook;0282 +sigma;03C3 +sigma1;03C2 +sigmafinal;03C2 +sigmalunatesymbolgreek;03F2 +sihiragana;3057 +sikatakana;30B7 +sikatakanahalfwidth;FF7C +siluqhebrew;05BD +siluqlefthebrew;05BD +similar;223C +sindothebrew;05C2 +siosacirclekorean;3274 +siosaparenkorean;3214 +sioscieuckorean;317E +sioscirclekorean;3266 +sioskiyeokkorean;317A +sioskorean;3145 +siosnieunkorean;317B +siosparenkorean;3206 +siospieupkorean;317D +siostikeutkorean;317C +six;0036 +sixarabic;0666 +sixbengali;09EC +sixcircle;2465 +sixcircleinversesansserif;278F +sixdeva;096C +sixgujarati;0AEC +sixgurmukhi;0A6C +sixhackarabic;0666 +sixhangzhou;3026 +sixideographicparen;3225 +sixinferior;2086 +sixmonospace;FF16 +sixoldstyle;F736 +sixparen;2479 +sixperiod;248D +sixpersian;06F6 +sixroman;2175 +sixsuperior;2076 +sixteencircle;246F +sixteencurrencydenominatorbengali;09F9 +sixteenparen;2483 +sixteenperiod;2497 +sixthai;0E56 +slash;002F +slashmonospace;FF0F +slong;017F +slongdotaccent;1E9B +smileface;263A +smonospace;FF53 +sofpasuqhebrew;05C3 +softhyphen;00AD +softsigncyrillic;044C +sohiragana;305D +sokatakana;30BD +sokatakanahalfwidth;FF7F +soliduslongoverlaycmb;0338 +solidusshortoverlaycmb;0337 +sorusithai;0E29 +sosalathai;0E28 +sosothai;0E0B +sosuathai;0E2A +space;0020 +spacehackarabic;0020 +spade;2660 +spadesuitblack;2660 +spadesuitwhite;2664 +sparen;24AE +squarebelowcmb;033B +squarecc;33C4 +squarecm;339D +squarediagonalcrosshatchfill;25A9 +squarehorizontalfill;25A4 +squarekg;338F +squarekm;339E +squarekmcapital;33CE +squareln;33D1 +squarelog;33D2 +squaremg;338E +squaremil;33D5 +squaremm;339C +squaremsquared;33A1 +squareorthogonalcrosshatchfill;25A6 +squareupperlefttolowerrightfill;25A7 +squareupperrighttolowerleftfill;25A8 +squareverticalfill;25A5 +squarewhitewithsmallblack;25A3 +srsquare;33DB +ssabengali;09B7 +ssadeva;0937 +ssagujarati;0AB7 +ssangcieuckorean;3149 +ssanghieuhkorean;3185 +ssangieungkorean;3180 +ssangkiyeokkorean;3132 +ssangnieunkorean;3165 +ssangpieupkorean;3143 +ssangsioskorean;3146 +ssangtikeutkorean;3138 +ssuperior;F6F2 +sterling;00A3 +sterlingmonospace;FFE1 +strokelongoverlaycmb;0336 +strokeshortoverlaycmb;0335 +subset;2282 +subsetnotequal;228A +subsetorequal;2286 +succeeds;227B +suchthat;220B +suhiragana;3059 +sukatakana;30B9 +sukatakanahalfwidth;FF7D +sukunarabic;0652 +summation;2211 +sun;263C +superset;2283 +supersetnotequal;228B +supersetorequal;2287 +svsquare;33DC +syouwaerasquare;337C +t;0074 +tabengali;09A4 +tackdown;22A4 +tackleft;22A3 +tadeva;0924 +tagujarati;0AA4 +tagurmukhi;0A24 +taharabic;0637 +tahfinalarabic;FEC2 +tahinitialarabic;FEC3 +tahiragana;305F +tahmedialarabic;FEC4 +taisyouerasquare;337D +takatakana;30BF +takatakanahalfwidth;FF80 +tatweelarabic;0640 +tau;03C4 +tav;05EA +tavdages;FB4A +tavdagesh;FB4A +tavdageshhebrew;FB4A +tavhebrew;05EA +tbar;0167 +tbopomofo;310A +tcaron;0165 +tccurl;02A8 +tcedilla;0163 +tcheharabic;0686 +tchehfinalarabic;FB7B +tchehinitialarabic;FB7C +tchehmedialarabic;FB7D +tchehmeeminitialarabic;FB7C FEE4 +tcircle;24E3 +tcircumflexbelow;1E71 +tcommaaccent;0163 +tdieresis;1E97 +tdotaccent;1E6B +tdotbelow;1E6D +tecyrillic;0442 +tedescendercyrillic;04AD +teharabic;062A +tehfinalarabic;FE96 +tehhahinitialarabic;FCA2 +tehhahisolatedarabic;FC0C +tehinitialarabic;FE97 +tehiragana;3066 +tehjeeminitialarabic;FCA1 +tehjeemisolatedarabic;FC0B +tehmarbutaarabic;0629 +tehmarbutafinalarabic;FE94 +tehmedialarabic;FE98 +tehmeeminitialarabic;FCA4 +tehmeemisolatedarabic;FC0E +tehnoonfinalarabic;FC73 +tekatakana;30C6 +tekatakanahalfwidth;FF83 +telephone;2121 +telephoneblack;260E +telishagedolahebrew;05A0 +telishaqetanahebrew;05A9 +tencircle;2469 +tenideographicparen;3229 +tenparen;247D +tenperiod;2491 +tenroman;2179 +tesh;02A7 +tet;05D8 +tetdagesh;FB38 +tetdageshhebrew;FB38 +tethebrew;05D8 +tetsecyrillic;04B5 +tevirhebrew;059B +tevirlefthebrew;059B +thabengali;09A5 +thadeva;0925 +thagujarati;0AA5 +thagurmukhi;0A25 +thalarabic;0630 +thalfinalarabic;FEAC +thanthakhatlowleftthai;F898 +thanthakhatlowrightthai;F897 +thanthakhatthai;0E4C +thanthakhatupperleftthai;F896 +theharabic;062B +thehfinalarabic;FE9A +thehinitialarabic;FE9B +thehmedialarabic;FE9C +thereexists;2203 +therefore;2234 +theta;03B8 +theta1;03D1 +thetasymbolgreek;03D1 +thieuthacirclekorean;3279 +thieuthaparenkorean;3219 +thieuthcirclekorean;326B +thieuthkorean;314C +thieuthparenkorean;320B +thirteencircle;246C +thirteenparen;2480 +thirteenperiod;2494 +thonangmonthothai;0E11 +thook;01AD +thophuthaothai;0E12 +thorn;00FE +thothahanthai;0E17 +thothanthai;0E10 +thothongthai;0E18 +thothungthai;0E16 +thousandcyrillic;0482 +thousandsseparatorarabic;066C +thousandsseparatorpersian;066C +three;0033 +threearabic;0663 +threebengali;09E9 +threecircle;2462 +threecircleinversesansserif;278C +threedeva;0969 +threeeighths;215C +threegujarati;0AE9 +threegurmukhi;0A69 +threehackarabic;0663 +threehangzhou;3023 +threeideographicparen;3222 +threeinferior;2083 +threemonospace;FF13 +threenumeratorbengali;09F6 +threeoldstyle;F733 +threeparen;2476 +threeperiod;248A +threepersian;06F3 +threequarters;00BE +threequartersemdash;F6DE +threeroman;2172 +threesuperior;00B3 +threethai;0E53 +thzsquare;3394 +tihiragana;3061 +tikatakana;30C1 +tikatakanahalfwidth;FF81 +tikeutacirclekorean;3270 +tikeutaparenkorean;3210 +tikeutcirclekorean;3262 +tikeutkorean;3137 +tikeutparenkorean;3202 +tilde;02DC +tildebelowcmb;0330 +tildecmb;0303 +tildecomb;0303 +tildedoublecmb;0360 +tildeoperator;223C +tildeoverlaycmb;0334 +tildeverticalcmb;033E +timescircle;2297 +tipehahebrew;0596 +tipehalefthebrew;0596 +tippigurmukhi;0A70 +titlocyrilliccmb;0483 +tiwnarmenian;057F +tlinebelow;1E6F +tmonospace;FF54 +toarmenian;0569 +tohiragana;3068 +tokatakana;30C8 +tokatakanahalfwidth;FF84 +tonebarextrahighmod;02E5 +tonebarextralowmod;02E9 +tonebarhighmod;02E6 +tonebarlowmod;02E8 +tonebarmidmod;02E7 +tonefive;01BD +tonesix;0185 +tonetwo;01A8 +tonos;0384 +tonsquare;3327 +topatakthai;0E0F +tortoiseshellbracketleft;3014 +tortoiseshellbracketleftsmall;FE5D +tortoiseshellbracketleftvertical;FE39 +tortoiseshellbracketright;3015 +tortoiseshellbracketrightsmall;FE5E +tortoiseshellbracketrightvertical;FE3A +totaothai;0E15 +tpalatalhook;01AB +tparen;24AF +trademark;2122 +trademarksans;F8EA +trademarkserif;F6DB +tretroflexhook;0288 +triagdn;25BC +triaglf;25C4 +triagrt;25BA +triagup;25B2 +ts;02A6 +tsadi;05E6 +tsadidagesh;FB46 +tsadidageshhebrew;FB46 +tsadihebrew;05E6 +tsecyrillic;0446 +tsere;05B5 +tsere12;05B5 +tsere1e;05B5 +tsere2b;05B5 +tserehebrew;05B5 +tserenarrowhebrew;05B5 +tserequarterhebrew;05B5 +tserewidehebrew;05B5 +tshecyrillic;045B +tsuperior;F6F3 +ttabengali;099F +ttadeva;091F +ttagujarati;0A9F +ttagurmukhi;0A1F +tteharabic;0679 +ttehfinalarabic;FB67 +ttehinitialarabic;FB68 +ttehmedialarabic;FB69 +tthabengali;09A0 +tthadeva;0920 +tthagujarati;0AA0 +tthagurmukhi;0A20 +tturned;0287 +tuhiragana;3064 +tukatakana;30C4 +tukatakanahalfwidth;FF82 +tusmallhiragana;3063 +tusmallkatakana;30C3 +tusmallkatakanahalfwidth;FF6F +twelvecircle;246B +twelveparen;247F +twelveperiod;2493 +twelveroman;217B +twentycircle;2473 +twentyhangzhou;5344 +twentyparen;2487 +twentyperiod;249B +two;0032 +twoarabic;0662 +twobengali;09E8 +twocircle;2461 +twocircleinversesansserif;278B +twodeva;0968 +twodotenleader;2025 +twodotleader;2025 +twodotleadervertical;FE30 +twogujarati;0AE8 +twogurmukhi;0A68 +twohackarabic;0662 +twohangzhou;3022 +twoideographicparen;3221 +twoinferior;2082 +twomonospace;FF12 +twonumeratorbengali;09F5 +twooldstyle;F732 +twoparen;2475 +twoperiod;2489 +twopersian;06F2 +tworoman;2171 +twostroke;01BB +twosuperior;00B2 +twothai;0E52 +twothirds;2154 +u;0075 +uacute;00FA +ubar;0289 +ubengali;0989 +ubopomofo;3128 +ubreve;016D +ucaron;01D4 +ucircle;24E4 +ucircumflex;00FB +ucircumflexbelow;1E77 +ucyrillic;0443 +udattadeva;0951 +udblacute;0171 +udblgrave;0215 +udeva;0909 +udieresis;00FC +udieresisacute;01D8 +udieresisbelow;1E73 +udieresiscaron;01DA +udieresiscyrillic;04F1 +udieresisgrave;01DC +udieresismacron;01D6 +udotbelow;1EE5 +ugrave;00F9 +ugujarati;0A89 +ugurmukhi;0A09 +uhiragana;3046 +uhookabove;1EE7 +uhorn;01B0 +uhornacute;1EE9 +uhorndotbelow;1EF1 +uhorngrave;1EEB +uhornhookabove;1EED +uhorntilde;1EEF +uhungarumlaut;0171 +uhungarumlautcyrillic;04F3 +uinvertedbreve;0217 +ukatakana;30A6 +ukatakanahalfwidth;FF73 +ukcyrillic;0479 +ukorean;315C +umacron;016B +umacroncyrillic;04EF +umacrondieresis;1E7B +umatragurmukhi;0A41 +umonospace;FF55 +underscore;005F +underscoredbl;2017 +underscoremonospace;FF3F +underscorevertical;FE33 +underscorewavy;FE4F +union;222A +universal;2200 +uogonek;0173 +uparen;24B0 +upblock;2580 +upperdothebrew;05C4 +upsilon;03C5 +upsilondieresis;03CB +upsilondieresistonos;03B0 +upsilonlatin;028A +upsilontonos;03CD +uptackbelowcmb;031D +uptackmod;02D4 +uragurmukhi;0A73 +uring;016F +ushortcyrillic;045E +usmallhiragana;3045 +usmallkatakana;30A5 +usmallkatakanahalfwidth;FF69 +ustraightcyrillic;04AF +ustraightstrokecyrillic;04B1 +utilde;0169 +utildeacute;1E79 +utildebelow;1E75 +uubengali;098A +uudeva;090A +uugujarati;0A8A +uugurmukhi;0A0A +uumatragurmukhi;0A42 +uuvowelsignbengali;09C2 +uuvowelsigndeva;0942 +uuvowelsigngujarati;0AC2 +uvowelsignbengali;09C1 +uvowelsigndeva;0941 +uvowelsigngujarati;0AC1 +v;0076 +vadeva;0935 +vagujarati;0AB5 +vagurmukhi;0A35 +vakatakana;30F7 +vav;05D5 +vavdagesh;FB35 +vavdagesh65;FB35 +vavdageshhebrew;FB35 +vavhebrew;05D5 +vavholam;FB4B +vavholamhebrew;FB4B +vavvavhebrew;05F0 +vavyodhebrew;05F1 +vcircle;24E5 +vdotbelow;1E7F +vecyrillic;0432 +veharabic;06A4 +vehfinalarabic;FB6B +vehinitialarabic;FB6C +vehmedialarabic;FB6D +vekatakana;30F9 +venus;2640 +verticalbar;007C +verticallineabovecmb;030D +verticallinebelowcmb;0329 +verticallinelowmod;02CC +verticallinemod;02C8 +vewarmenian;057E +vhook;028B +vikatakana;30F8 +viramabengali;09CD +viramadeva;094D +viramagujarati;0ACD +visargabengali;0983 +visargadeva;0903 +visargagujarati;0A83 +vmonospace;FF56 +voarmenian;0578 +voicediterationhiragana;309E +voicediterationkatakana;30FE +voicedmarkkana;309B +voicedmarkkanahalfwidth;FF9E +vokatakana;30FA +vparen;24B1 +vtilde;1E7D +vturned;028C +vuhiragana;3094 +vukatakana;30F4 +w;0077 +wacute;1E83 +waekorean;3159 +wahiragana;308F +wakatakana;30EF +wakatakanahalfwidth;FF9C +wakorean;3158 +wasmallhiragana;308E +wasmallkatakana;30EE +wattosquare;3357 +wavedash;301C +wavyunderscorevertical;FE34 +wawarabic;0648 +wawfinalarabic;FEEE +wawhamzaabovearabic;0624 +wawhamzaabovefinalarabic;FE86 +wbsquare;33DD +wcircle;24E6 +wcircumflex;0175 +wdieresis;1E85 +wdotaccent;1E87 +wdotbelow;1E89 +wehiragana;3091 +weierstrass;2118 +wekatakana;30F1 +wekorean;315E +weokorean;315D +wgrave;1E81 +whitebullet;25E6 +whitecircle;25CB +whitecircleinverse;25D9 +whitecornerbracketleft;300E +whitecornerbracketleftvertical;FE43 +whitecornerbracketright;300F +whitecornerbracketrightvertical;FE44 +whitediamond;25C7 +whitediamondcontainingblacksmalldiamond;25C8 +whitedownpointingsmalltriangle;25BF +whitedownpointingtriangle;25BD +whiteleftpointingsmalltriangle;25C3 +whiteleftpointingtriangle;25C1 +whitelenticularbracketleft;3016 +whitelenticularbracketright;3017 +whiterightpointingsmalltriangle;25B9 +whiterightpointingtriangle;25B7 +whitesmallsquare;25AB +whitesmilingface;263A +whitesquare;25A1 +whitestar;2606 +whitetelephone;260F +whitetortoiseshellbracketleft;3018 +whitetortoiseshellbracketright;3019 +whiteuppointingsmalltriangle;25B5 +whiteuppointingtriangle;25B3 +wihiragana;3090 +wikatakana;30F0 +wikorean;315F +wmonospace;FF57 +wohiragana;3092 +wokatakana;30F2 +wokatakanahalfwidth;FF66 +won;20A9 +wonmonospace;FFE6 +wowaenthai;0E27 +wparen;24B2 +wring;1E98 +wsuperior;02B7 +wturned;028D +wynn;01BF +x;0078 +xabovecmb;033D +xbopomofo;3112 +xcircle;24E7 +xdieresis;1E8D +xdotaccent;1E8B +xeharmenian;056D +xi;03BE +xmonospace;FF58 +xparen;24B3 +xsuperior;02E3 +y;0079 +yaadosquare;334E +yabengali;09AF +yacute;00FD +yadeva;092F +yaekorean;3152 +yagujarati;0AAF +yagurmukhi;0A2F +yahiragana;3084 +yakatakana;30E4 +yakatakanahalfwidth;FF94 +yakorean;3151 +yamakkanthai;0E4E +yasmallhiragana;3083 +yasmallkatakana;30E3 +yasmallkatakanahalfwidth;FF6C +yatcyrillic;0463 +ycircle;24E8 +ycircumflex;0177 +ydieresis;00FF +ydotaccent;1E8F +ydotbelow;1EF5 +yeharabic;064A +yehbarreearabic;06D2 +yehbarreefinalarabic;FBAF +yehfinalarabic;FEF2 +yehhamzaabovearabic;0626 +yehhamzaabovefinalarabic;FE8A +yehhamzaaboveinitialarabic;FE8B +yehhamzaabovemedialarabic;FE8C +yehinitialarabic;FEF3 +yehmedialarabic;FEF4 +yehmeeminitialarabic;FCDD +yehmeemisolatedarabic;FC58 +yehnoonfinalarabic;FC94 +yehthreedotsbelowarabic;06D1 +yekorean;3156 +yen;00A5 +yenmonospace;FFE5 +yeokorean;3155 +yeorinhieuhkorean;3186 +yerahbenyomohebrew;05AA +yerahbenyomolefthebrew;05AA +yericyrillic;044B +yerudieresiscyrillic;04F9 +yesieungkorean;3181 +yesieungpansioskorean;3183 +yesieungsioskorean;3182 +yetivhebrew;059A +ygrave;1EF3 +yhook;01B4 +yhookabove;1EF7 +yiarmenian;0575 +yicyrillic;0457 +yikorean;3162 +yinyang;262F +yiwnarmenian;0582 +ymonospace;FF59 +yod;05D9 +yoddagesh;FB39 +yoddageshhebrew;FB39 +yodhebrew;05D9 +yodyodhebrew;05F2 +yodyodpatahhebrew;FB1F +yohiragana;3088 +yoikorean;3189 +yokatakana;30E8 +yokatakanahalfwidth;FF96 +yokorean;315B +yosmallhiragana;3087 +yosmallkatakana;30E7 +yosmallkatakanahalfwidth;FF6E +yotgreek;03F3 +yoyaekorean;3188 +yoyakorean;3187 +yoyakthai;0E22 +yoyingthai;0E0D +yparen;24B4 +ypogegrammeni;037A +ypogegrammenigreekcmb;0345 +yr;01A6 +yring;1E99 +ysuperior;02B8 +ytilde;1EF9 +yturned;028E +yuhiragana;3086 +yuikorean;318C +yukatakana;30E6 +yukatakanahalfwidth;FF95 +yukorean;3160 +yusbigcyrillic;046B +yusbigiotifiedcyrillic;046D +yuslittlecyrillic;0467 +yuslittleiotifiedcyrillic;0469 +yusmallhiragana;3085 +yusmallkatakana;30E5 +yusmallkatakanahalfwidth;FF6D +yuyekorean;318B +yuyeokorean;318A +yyabengali;09DF +yyadeva;095F +z;007A +zaarmenian;0566 +zacute;017A +zadeva;095B +zagurmukhi;0A5B +zaharabic;0638 +zahfinalarabic;FEC6 +zahinitialarabic;FEC7 +zahiragana;3056 +zahmedialarabic;FEC8 +zainarabic;0632 +zainfinalarabic;FEB0 +zakatakana;30B6 +zaqefgadolhebrew;0595 +zaqefqatanhebrew;0594 +zarqahebrew;0598 +zayin;05D6 +zayindagesh;FB36 +zayindageshhebrew;FB36 +zayinhebrew;05D6 +zbopomofo;3117 +zcaron;017E +zcircle;24E9 +zcircumflex;1E91 +zcurl;0291 +zdot;017C +zdotaccent;017C +zdotbelow;1E93 +zecyrillic;0437 +zedescendercyrillic;0499 +zedieresiscyrillic;04DF +zehiragana;305C +zekatakana;30BC +zero;0030 +zeroarabic;0660 +zerobengali;09E6 +zerodeva;0966 +zerogujarati;0AE6 +zerogurmukhi;0A66 +zerohackarabic;0660 +zeroinferior;2080 +zeromonospace;FF10 +zerooldstyle;F730 +zeropersian;06F0 +zerosuperior;2070 +zerothai;0E50 +zerowidthjoiner;FEFF +zerowidthnonjoiner;200C +zerowidthspace;200B +zeta;03B6 +zhbopomofo;3113 +zhearmenian;056A +zhebrevecyrillic;04C2 +zhecyrillic;0436 +zhedescendercyrillic;0497 +zhedieresiscyrillic;04DD +zihiragana;3058 +zikatakana;30B8 +zinorhebrew;05AE +zlinebelow;1E95 +zmonospace;FF5A +zohiragana;305E +zokatakana;30BE +zparen;24B5 +zretroflexhook;0290 +zstroke;01B6 +zuhiragana;305A +zukatakana;30BA +""" + + +t1_bias = 0 +glyph_list = [] + + +def adobe_glyph_names(): + """return the list of glyph names from the adobe list""" + + lines = string.split( adobe_glyph_list, '\n' ) + glyphs = [] + + for line in lines: + if line: + fields = string.split( line, ';' ) +# print fields[1] + ' - ' + fields[0] + glyphs.append( fields[0] ) + + return glyphs + + +def adobe_glyph_values(): + """return the list of glyph names and their unicode values""" + + lines = string.split( adobe_glyph_list, '\n' ) + glyphs = [] + values = [] + + for line in lines: + if line: + fields = string.split( line, ';' ) +# print fields[1] + ' - ' + fields[0] + subfields = string.split( fields[1], ' ' ) + if len( subfields ) == 1: + glyphs.append( fields[0] ) + values.append( fields[1] ) + + return glyphs, values + + +def filter_glyph_names( alist, filter ): + """filter 'alist' by taking _out_ all glyph names that are in 'filter'""" + + count = 0 + extras = [] + + for name in alist: + try: + filtered_index = filter.index( name ) + except: + extras.append( name ) + + return extras + + +def dump_mac_indices( file, all_glyphs ): + write = file.write + + write( " static const unsigned short mac_standard_names[" + \ + repr( len( mac_standard_names ) + 1 ) + "] =\n" ) + write( " {\n" ) + + for name in mac_standard_names: + write( " " + repr( all_glyphs.index( name ) ) + ",\n" ) + + write( " 0\n" ) + write( " };\n" ) + write( "\n" ) + write( "\n" ) + + +def dump_glyph_list( file, base_list, adobe_list ): + write = file.write + + name_list = [] + + write( " static const char* const ps_glyph_names[] =\n" ) + write( " {\n" ) + + for name in base_list: + write( ' "' + name + '",\n' ) + name_list.append( name ) + + write( "\n" ) + write( "#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST\n" ) + write( "\n" ) + + for name in adobe_list: + write( ' "' + name + '",\n' ) + name_list.append( name ) + + write( "\n" ) + write( "#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */\n" ) + write( "\n" ) + write( " NULL\n" ) + write( " };\n" ) + write( "\n" ) + write( "\n" ) + + return name_list + + +def dump_unicode_values( file, sid_list, adobe_list ): + """build the glyph names to unicode values table""" + + write = file.write + + agl_names, agl_unicodes = adobe_glyph_values() + + write( "\n" ) + write( " static const unsigned short ps_names_to_unicode[" + \ + repr( len( sid_list ) + len( adobe_list ) + 1 ) + "] =\n" ) + write( " {\n" ) + + for name in sid_list: + try: + index = agl_names.index( name ) + write( " 0x" + agl_unicodes[index] + "U,\n" ) + except: + write( " 0,\n" ) + + write( "\n" ) + write( "#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST\n" ) + write( "\n" ) + + for name in adobe_list: + try: + index = agl_names.index( name ) + write( " 0x" + agl_unicodes[index] + "U,\n" ) + except: + write( " 0,\n" ) + + write( "\n" ) + write( "#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */\n" ) + write( " 0\n" ) + write( " };\n" ) + write( "\n" ) + write( "\n" ) + write( "\n" ) + + +def dump_encoding( file, encoding_name, encoding_list ): + """dumps a given encoding""" + + write = file.write + + write( " static const unsigned short " + encoding_name + "[" + \ + repr( len( encoding_list ) + 1 ) + "] =\n" ) + write( " {\n" ) + + for value in encoding_list: + write( " " + repr( value ) + ",\n" ) + write( " 0\n" ) + write( " };\n" ) + write( "\n" ) + write( "\n" ) + + +def main(): + """main program body""" + + if len( sys.argv ) != 2: + print __doc__ % sys.argv[0] + sys.exit( 1 ) + + file = open( sys.argv[1], "w\n" ) + write = file.write + + count_sid = len( sid_standard_names ) + + # 'mac_extras' contains the list of glyph names in the Macintosh standard + # encoding which are not in either the Adobe Glyph List or the SID + # Standard Names. + # + mac_extras = filter_glyph_names( mac_standard_names, adobe_glyph_names() ) + mac_extras = filter_glyph_names( mac_extras, sid_standard_names ) + + # 'base_list' contains the first names of our final glyph names table. + # It consists of the 'mac_extras' glyph names, followed by the SID + # Standard names. + # + mac_extras_count = len( mac_extras ) + t1_bias = mac_extras_count + base_list = mac_extras + sid_standard_names + + # 'adobe_list' contains the glyph names that are in the AGL, but not in + # the base_list; they will be placed after base_list glyph names in + # our final table. + # + adobe_list = filter_glyph_names( adobe_glyph_names(), base_list ) + adobe_count = len( adobe_list ) + + write( "/***************************************************************************/\n" ) + write( "/* */\n" ) + + write( "/* %-71s*/\n" % sys.argv[1] ) + + write( "/* */\n" ) + write( "/* PostScript glyph names (specification only). */\n" ) + write( "/* */\n" ) + write( "/* Copyright 2000-2001, 2003 by */\n" ) + write( "/* David Turner, Robert Wilhelm, and Werner Lemberg. */\n" ) + write( "/* */\n" ) + write( "/* This file is part of the FreeType project, and may only be used, */\n" ) + write( "/* modified, and distributed under the terms of the FreeType project */\n" ) + write( "/* license, LICENSE.TXT. By continuing to use, modify, or distribute */\n" ) + write( "/* this file you indicate that you have read the license and */\n" ) + write( "/* understand and accept it fully. */\n" ) + write( "/* */\n" ) + write( "/***************************************************************************/\n" ) + write( "\n" ) + write( "\n" ) + write( " /* this file has been generated automatically -- do not edit! */\n" ) + write( "\n" ) + write( "\n" ) + + # dump final glyph list (mac extras + sid standard names + AGL glyph names) + # + name_list = dump_glyph_list( file, base_list, adobe_list ) + + # dump t1_standard_list + write( " static const char* const * const sid_standard_names = " \ + + "ps_glyph_names + " + repr( t1_bias ) + ";\n" ) + write( "\n" ) + write( "\n" ) + + write( "#define NUM_SID_GLYPHS " + repr( len( sid_standard_names ) ) + "\n" ) + write( "\n" ) + write( "#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST\n" ) + write( "#define NUM_ADOBE_GLYPHS " + \ + repr( len( base_list ) + len( adobe_list ) - t1_bias ) + "\n" ) + write( "#else\n" ) + write( "#define NUM_ADOBE_GLYPHS " + \ + repr( len( base_list ) - t1_bias ) + "\n" ) + write( "#endif\n" ) + write( "\n" ) + write( "\n" ) + + # dump mac indices table + dump_mac_indices( file, name_list ) + + # dump unicode values table + dump_unicode_values( file, sid_standard_names, adobe_list ) + + dump_encoding( file, "t1_standard_encoding", t1_standard_encoding ) + dump_encoding( file, "t1_expert_encoding", t1_expert_encoding ) + + write( "/* END */\n" ) + + +# Now run the main routine +# +main() + + +# END diff --git a/src/libs/freetype2/tools/test_bbox.c b/src/libs/freetype2/tools/test_bbox.c index 5a76a647f5..e085c5b3d6 100644 --- a/src/libs/freetype2/tools/test_bbox.c +++ b/src/libs/freetype2/tools/test_bbox.c @@ -1,160 +1,160 @@ -#include -#include FT_FREETYPE_H -#include FT_BBOX_H - - -#include /* for clock() */ - -/* SunOS 4.1.* does not define CLOCKS_PER_SEC, so include */ -/* to get the HZ macro which is the equivalent. */ -#if defined(__sun__) && !defined(SVR4) && !defined(__SVR4) -#include -#define CLOCKS_PER_SEC HZ -#endif - - static long - get_time( void ) - { - return clock() * 10000L / CLOCKS_PER_SEC; - } - - - - - /* test bbox computations */ - -#define XSCALE 65536 -#define XX(x) ((FT_Pos)(x*XSCALE)) -#define XVEC(x,y) { XX(x), XX(y) } -#define XVAL(x) ((x)/(1.0*XSCALE)) - - /* dummy outline #1 */ - static FT_Vector dummy_vec_1[4] = - { -#if 1 - XVEC( 408.9111, 535.3164 ), - XVEC( 455.8887, 634.396 ), - XVEC( -37.8765, 786.2207 ), - XVEC( 164.6074, 535.3164 ) -#else - { (FT_Int32)0x0198E93DL , (FT_Int32)0x021750FFL }, /* 408.9111, 535.3164 */ - { (FT_Int32)0x01C7E312L , (FT_Int32)0x027A6560L }, /* 455.8887, 634.3960 */ - { (FT_Int32)0xFFDA1F9EL , (FT_Int32)0x0312387FL }, /* -37.8765, 786.2207 */ - { (FT_Int32)0x00A49B7EL , (FT_Int32)0x021750FFL } /* 164.6074, 535.3164 */ -#endif - }; - - static char dummy_tag_1[4] = - { - FT_CURVE_TAG_ON, - FT_CURVE_TAG_CUBIC, - FT_CURVE_TAG_CUBIC, - FT_CURVE_TAG_ON - }; - - static short dummy_contour_1[1] = - { - 3 - }; - - static FT_Outline dummy_outline_1 = - { - 1, - 4, - dummy_vec_1, - dummy_tag_1, - dummy_contour_1, - 0 - }; - - - /* dummy outline #2 */ - static FT_Vector dummy_vec_2[4] = - { - XVEC( 100.0, 100.0 ), - XVEC( 100.0, 200.0 ), - XVEC( 200.0, 200.0 ), - XVEC( 200.0, 133.0 ) - }; - - static FT_Outline dummy_outline_2 = - { - 1, - 4, - dummy_vec_2, - dummy_tag_1, - dummy_contour_1, - 0 - }; - - - static void - dump_outline( FT_Outline* outline ) - { - FT_BBox bbox; - - /* compute and display cbox */ - FT_Outline_Get_CBox( outline, &bbox ); - printf( "cbox = [%.2f %.2f %.2f %.2f]\n", - XVAL( bbox.xMin ), - XVAL( bbox.yMin ), - XVAL( bbox.xMax ), - XVAL( bbox.yMax ) ); - - /* compute and display bbox */ - FT_Outline_Get_BBox( outline, &bbox ); - printf( "bbox = [%.2f %.2f %.2f %.2f]\n", - XVAL( bbox.xMin ), - XVAL( bbox.yMin ), - XVAL( bbox.xMax ), - XVAL( bbox.yMax ) ); - } - - - - static void - profile_outline( FT_Outline* outline, - long repeat ) - { - FT_BBox bbox; - long count; - long time0; - - time0 = get_time(); - for ( count = repeat; count > 0; count-- ) - FT_Outline_Get_CBox( outline, &bbox ); - - time0 = get_time() - time0; - printf( "time = %5.2f cbox = [%.2f %.2f %.2f %.2f]\n", - ((double)time0/10000.0), - XVAL( bbox.xMin ), - XVAL( bbox.yMin ), - XVAL( bbox.xMax ), - XVAL( bbox.yMax ) ); - - - time0 = get_time(); - for ( count = repeat; count > 0; count-- ) - FT_Outline_Get_BBox( outline, &bbox ); - - time0 = get_time() - time0; - printf( "time = %5.2f bbox = [%.2f %.2f %.2f %.2f]\n", - ((double)time0/10000.0), - XVAL( bbox.xMin ), - XVAL( bbox.yMin ), - XVAL( bbox.xMax ), - XVAL( bbox.yMax ) ); - } - -#define REPEAT 100000L - - int main( int argc, char** argv ) - { - printf( "outline #1\n" ); - profile_outline( &dummy_outline_1, REPEAT ); - - printf( "outline #2\n" ); - profile_outline( &dummy_outline_2, REPEAT ); - return 0; - } - +#include +#include FT_FREETYPE_H +#include FT_BBOX_H + + +#include /* for clock() */ + +/* SunOS 4.1.* does not define CLOCKS_PER_SEC, so include */ +/* to get the HZ macro which is the equivalent. */ +#if defined(__sun__) && !defined(SVR4) && !defined(__SVR4) +#include +#define CLOCKS_PER_SEC HZ +#endif + + static long + get_time( void ) + { + return clock() * 10000L / CLOCKS_PER_SEC; + } + + + + + /* test bbox computations */ + +#define XSCALE 65536 +#define XX(x) ((FT_Pos)(x*XSCALE)) +#define XVEC(x,y) { XX(x), XX(y) } +#define XVAL(x) ((x)/(1.0*XSCALE)) + + /* dummy outline #1 */ + static FT_Vector dummy_vec_1[4] = + { +#if 1 + XVEC( 408.9111, 535.3164 ), + XVEC( 455.8887, 634.396 ), + XVEC( -37.8765, 786.2207 ), + XVEC( 164.6074, 535.3164 ) +#else + { (FT_Int32)0x0198E93DL , (FT_Int32)0x021750FFL }, /* 408.9111, 535.3164 */ + { (FT_Int32)0x01C7E312L , (FT_Int32)0x027A6560L }, /* 455.8887, 634.3960 */ + { (FT_Int32)0xFFDA1F9EL , (FT_Int32)0x0312387FL }, /* -37.8765, 786.2207 */ + { (FT_Int32)0x00A49B7EL , (FT_Int32)0x021750FFL } /* 164.6074, 535.3164 */ +#endif + }; + + static char dummy_tag_1[4] = + { + FT_CURVE_TAG_ON, + FT_CURVE_TAG_CUBIC, + FT_CURVE_TAG_CUBIC, + FT_CURVE_TAG_ON + }; + + static short dummy_contour_1[1] = + { + 3 + }; + + static FT_Outline dummy_outline_1 = + { + 1, + 4, + dummy_vec_1, + dummy_tag_1, + dummy_contour_1, + 0 + }; + + + /* dummy outline #2 */ + static FT_Vector dummy_vec_2[4] = + { + XVEC( 100.0, 100.0 ), + XVEC( 100.0, 200.0 ), + XVEC( 200.0, 200.0 ), + XVEC( 200.0, 133.0 ) + }; + + static FT_Outline dummy_outline_2 = + { + 1, + 4, + dummy_vec_2, + dummy_tag_1, + dummy_contour_1, + 0 + }; + + + static void + dump_outline( FT_Outline* outline ) + { + FT_BBox bbox; + + /* compute and display cbox */ + FT_Outline_Get_CBox( outline, &bbox ); + printf( "cbox = [%.2f %.2f %.2f %.2f]\n", + XVAL( bbox.xMin ), + XVAL( bbox.yMin ), + XVAL( bbox.xMax ), + XVAL( bbox.yMax ) ); + + /* compute and display bbox */ + FT_Outline_Get_BBox( outline, &bbox ); + printf( "bbox = [%.2f %.2f %.2f %.2f]\n", + XVAL( bbox.xMin ), + XVAL( bbox.yMin ), + XVAL( bbox.xMax ), + XVAL( bbox.yMax ) ); + } + + + + static void + profile_outline( FT_Outline* outline, + long repeat ) + { + FT_BBox bbox; + long count; + long time0; + + time0 = get_time(); + for ( count = repeat; count > 0; count-- ) + FT_Outline_Get_CBox( outline, &bbox ); + + time0 = get_time() - time0; + printf( "time = %5.2f cbox = [%.2f %.2f %.2f %.2f]\n", + ((double)time0/10000.0), + XVAL( bbox.xMin ), + XVAL( bbox.yMin ), + XVAL( bbox.xMax ), + XVAL( bbox.yMax ) ); + + + time0 = get_time(); + for ( count = repeat; count > 0; count-- ) + FT_Outline_Get_BBox( outline, &bbox ); + + time0 = get_time() - time0; + printf( "time = %5.2f bbox = [%.2f %.2f %.2f %.2f]\n", + ((double)time0/10000.0), + XVAL( bbox.xMin ), + XVAL( bbox.yMin ), + XVAL( bbox.xMax ), + XVAL( bbox.yMax ) ); + } + +#define REPEAT 100000L + + int main( int argc, char** argv ) + { + printf( "outline #1\n" ); + profile_outline( &dummy_outline_1, REPEAT ); + + printf( "outline #2\n" ); + profile_outline( &dummy_outline_2, REPEAT ); + return 0; + } + diff --git a/src/libs/freetype2/tools/test_trig.c b/src/libs/freetype2/tools/test_trig.c index 4b5111dea4..8c8a544aa9 100644 --- a/src/libs/freetype2/tools/test_trig.c +++ b/src/libs/freetype2/tools/test_trig.c @@ -1,236 +1,236 @@ -#include -#include FT_FREETYPE_H -#include FT_TRIGONOMETRY_H - -#include -#include - -#define PI 3.14159265358979323846 -#define SPI (PI/FT_ANGLE_PI) - -/* the precision in 16.16 fixed float points of the checks. Expect */ -/* between 2 and 5 noise LSB bits during operations, due to */ -/* rounding errors.. */ -#define THRESHOLD 64 - - static error = 0; - - static void - test_cos( void ) - { - FT_Fixed f1, f2; - double d1, d2; - int i; - - for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000 ) - { - f1 = FT_Cos(i); - d1 = f1/65536.0; - d2 = cos( i*SPI ); - f2 = (FT_Fixed)(d2*65536.0); - - if ( abs( f2-f1 ) > THRESHOLD ) - { - error = 1; - printf( "FT_Cos[%3d] = %.7f cos[%3d] = %.7f\n", - (i >> 16), f1/65536.0, (i >> 16), d2 ); - } - } - } - - - - static void - test_sin( void ) - { - FT_Fixed f1, f2; - double d1, d2; - int i; - - for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000 ) - { - f1 = FT_Sin(i); - d1 = f1/65536.0; - d2 = sin( i*SPI ); - f2 = (FT_Fixed)(d2*65536.0); - - if ( abs( f2-f1 ) > THRESHOLD ) - { - error = 1; - printf( "FT_Sin[%3d] = %.7f sin[%3d] = %.7f\n", - (i >> 16), f1/65536.0, (i >> 16), d2 ); - } - } - } - - - static void - test_tan( void ) - { - FT_Fixed f1, f2; - double d1, d2; - int i; - - for ( i = 0; i < FT_ANGLE_PI2-0x2000000; i += 0x10000 ) - { - f1 = FT_Tan(i); - d1 = f1/65536.0; - d2 = tan( i*SPI ); - f2 = (FT_Fixed)(d2*65536.0); - - if ( abs( f2-f1 ) > THRESHOLD ) - { - error = 1; - printf( "FT_Tan[%3d] = %.7f tan[%3d] = %.7f\n", - (i >> 16), f1/65536.0, (i >> 16), d2 ); - } - } - } - - - static void - test_atan2( void ) - { - FT_Fixed c2, s2; - double l, a, c1, s1; - int i, j; - - for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000 ) - { - l = 5.0; - a = i*SPI; - - c1 = l * cos(a); - s1 = l * sin(a); - - c2 = (FT_Fixed)(c1*65536.0); - s2 = (FT_Fixed)(s1*65536.0); - - j = FT_Atan2( c2, s2 ); - if ( j < 0 ) - j += FT_ANGLE_2PI; - - if ( abs( i - j ) > 1 ) - { - printf( "FT_Atan2( %.7f, %.7f ) = %.5f, atan = %.5f\n", - c2/65536.0, s2/65536.0, j/65536.0, i/65536.0 ); - } - } - } - - static void - test_unit( void ) - { - FT_Vector v; - double a, c1, s1; - FT_Fixed c2, s2; - int i; - - for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000 ) - { - FT_Vector_Unit( &v, i ); - a = ( i*SPI ); - c1 = cos(a); - s1 = sin(a); - c2 = (FT_Fixed)(c1*65536.0); - s2 = (FT_Fixed)(s1*65536.0); - - if ( abs( v.x-c2 ) > THRESHOLD || - abs( v.y-s2 ) > THRESHOLD ) - { - error = 1; - printf( "FT_Vector_Unit[%3d] = ( %.7f, %.7f ) vec = ( %.7f, %.7f )\n", - (i >> 16), - v.x/65536.0, v.y/65536.0, - c1, s1 ); - } - } - } - - - static void - test_length( void ) - { - FT_Vector v; - FT_Fixed l, l2; - int i; - - for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000 ) - { - l = (FT_Fixed)(500.0*65536.0); - v.x = (FT_Fixed)( l * cos( i*SPI ) ); - v.y = (FT_Fixed)( l * sin( i*SPI ) ); - l2 = FT_Vector_Length( &v ); - - if ( abs( l2-l ) > THRESHOLD ) - { - error = 1; - printf( "FT_Length( %.7f, %.7f ) = %.5f, length = %.5f\n", - v.x/65536.0, v.y/65536.0, l2/65536.0, l/65536.0 ); - } - } - } - - - static void - test_rotate( void ) - { - FT_Fixed c2, s2, c4, s4; - FT_Vector v; - double l, ra, a, c1, s1, cra, sra, c3, s3; - int i, j, rotate; - - for ( rotate = 0; rotate < FT_ANGLE_2PI; rotate += 0x10000 ) - { - ra = rotate*SPI; - cra = cos( ra ); - sra = sin( ra ); - - for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000 ) - { - l = 500.0; - a = i*SPI; - - c1 = l * cos(a); - s1 = l * sin(a); - - v.x = c2 = (FT_Fixed)(c1*65536.0); - v.y = s2 = (FT_Fixed)(s1*65536.0); - - FT_Vector_Rotate( &v, rotate ); - - c3 = c1 * cra - s1 * sra; - s3 = c1 * sra + s1 * cra; - - c4 = (FT_Fixed)(c3*65536.0); - s4 = (FT_Fixed)(s3*65536.0); - - if ( abs( c4 - v.x ) > THRESHOLD || - abs( s4 - v.y ) > THRESHOLD ) - { - error = 1; - printf( "FT_Rotate( (%.7f,%.7f), %.5f ) = ( %.7f, %.7f ), rot = ( %.7f, %.7f )\n", - c1, s1, ra, - c2/65536.0, s2/65536.0, - c4/65536.0, s4/65536.0 ); - } - } - } - } - - - int main( void ) - { - test_cos(); - test_sin(); - test_tan(); - test_atan2(); - test_unit(); - test_length(); - test_rotate(); - - if (!error) - printf( "trigonometry test ok !\n" ); - - return !error; - } +#include +#include FT_FREETYPE_H +#include FT_TRIGONOMETRY_H + +#include +#include + +#define PI 3.14159265358979323846 +#define SPI (PI/FT_ANGLE_PI) + +/* the precision in 16.16 fixed float points of the checks. Expect */ +/* between 2 and 5 noise LSB bits during operations, due to */ +/* rounding errors.. */ +#define THRESHOLD 64 + + static error = 0; + + static void + test_cos( void ) + { + FT_Fixed f1, f2; + double d1, d2; + int i; + + for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000 ) + { + f1 = FT_Cos(i); + d1 = f1/65536.0; + d2 = cos( i*SPI ); + f2 = (FT_Fixed)(d2*65536.0); + + if ( abs( f2-f1 ) > THRESHOLD ) + { + error = 1; + printf( "FT_Cos[%3d] = %.7f cos[%3d] = %.7f\n", + (i >> 16), f1/65536.0, (i >> 16), d2 ); + } + } + } + + + + static void + test_sin( void ) + { + FT_Fixed f1, f2; + double d1, d2; + int i; + + for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000 ) + { + f1 = FT_Sin(i); + d1 = f1/65536.0; + d2 = sin( i*SPI ); + f2 = (FT_Fixed)(d2*65536.0); + + if ( abs( f2-f1 ) > THRESHOLD ) + { + error = 1; + printf( "FT_Sin[%3d] = %.7f sin[%3d] = %.7f\n", + (i >> 16), f1/65536.0, (i >> 16), d2 ); + } + } + } + + + static void + test_tan( void ) + { + FT_Fixed f1, f2; + double d1, d2; + int i; + + for ( i = 0; i < FT_ANGLE_PI2-0x2000000; i += 0x10000 ) + { + f1 = FT_Tan(i); + d1 = f1/65536.0; + d2 = tan( i*SPI ); + f2 = (FT_Fixed)(d2*65536.0); + + if ( abs( f2-f1 ) > THRESHOLD ) + { + error = 1; + printf( "FT_Tan[%3d] = %.7f tan[%3d] = %.7f\n", + (i >> 16), f1/65536.0, (i >> 16), d2 ); + } + } + } + + + static void + test_atan2( void ) + { + FT_Fixed c2, s2; + double l, a, c1, s1; + int i, j; + + for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000 ) + { + l = 5.0; + a = i*SPI; + + c1 = l * cos(a); + s1 = l * sin(a); + + c2 = (FT_Fixed)(c1*65536.0); + s2 = (FT_Fixed)(s1*65536.0); + + j = FT_Atan2( c2, s2 ); + if ( j < 0 ) + j += FT_ANGLE_2PI; + + if ( abs( i - j ) > 1 ) + { + printf( "FT_Atan2( %.7f, %.7f ) = %.5f, atan = %.5f\n", + c2/65536.0, s2/65536.0, j/65536.0, i/65536.0 ); + } + } + } + + static void + test_unit( void ) + { + FT_Vector v; + double a, c1, s1; + FT_Fixed c2, s2; + int i; + + for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000 ) + { + FT_Vector_Unit( &v, i ); + a = ( i*SPI ); + c1 = cos(a); + s1 = sin(a); + c2 = (FT_Fixed)(c1*65536.0); + s2 = (FT_Fixed)(s1*65536.0); + + if ( abs( v.x-c2 ) > THRESHOLD || + abs( v.y-s2 ) > THRESHOLD ) + { + error = 1; + printf( "FT_Vector_Unit[%3d] = ( %.7f, %.7f ) vec = ( %.7f, %.7f )\n", + (i >> 16), + v.x/65536.0, v.y/65536.0, + c1, s1 ); + } + } + } + + + static void + test_length( void ) + { + FT_Vector v; + FT_Fixed l, l2; + int i; + + for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000 ) + { + l = (FT_Fixed)(500.0*65536.0); + v.x = (FT_Fixed)( l * cos( i*SPI ) ); + v.y = (FT_Fixed)( l * sin( i*SPI ) ); + l2 = FT_Vector_Length( &v ); + + if ( abs( l2-l ) > THRESHOLD ) + { + error = 1; + printf( "FT_Length( %.7f, %.7f ) = %.5f, length = %.5f\n", + v.x/65536.0, v.y/65536.0, l2/65536.0, l/65536.0 ); + } + } + } + + + static void + test_rotate( void ) + { + FT_Fixed c2, s2, c4, s4; + FT_Vector v; + double l, ra, a, c1, s1, cra, sra, c3, s3; + int i, j, rotate; + + for ( rotate = 0; rotate < FT_ANGLE_2PI; rotate += 0x10000 ) + { + ra = rotate*SPI; + cra = cos( ra ); + sra = sin( ra ); + + for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000 ) + { + l = 500.0; + a = i*SPI; + + c1 = l * cos(a); + s1 = l * sin(a); + + v.x = c2 = (FT_Fixed)(c1*65536.0); + v.y = s2 = (FT_Fixed)(s1*65536.0); + + FT_Vector_Rotate( &v, rotate ); + + c3 = c1 * cra - s1 * sra; + s3 = c1 * sra + s1 * cra; + + c4 = (FT_Fixed)(c3*65536.0); + s4 = (FT_Fixed)(s3*65536.0); + + if ( abs( c4 - v.x ) > THRESHOLD || + abs( s4 - v.y ) > THRESHOLD ) + { + error = 1; + printf( "FT_Rotate( (%.7f,%.7f), %.5f ) = ( %.7f, %.7f ), rot = ( %.7f, %.7f )\n", + c1, s1, ra, + c2/65536.0, s2/65536.0, + c4/65536.0, s4/65536.0 ); + } + } + } + } + + + int main( void ) + { + test_cos(); + test_sin(); + test_tan(); + test_atan2(); + test_unit(); + test_length(); + test_rotate(); + + if (!error) + printf( "trigonometry test ok !\n" ); + + return !error; + } diff --git a/src/libs/freetype2/truetype/descrip.mms b/src/libs/freetype2/truetype/descrip.mms index c596c2455f..e30ee1b3f8 100644 --- a/src/libs/freetype2/truetype/descrip.mms +++ b/src/libs/freetype2/truetype/descrip.mms @@ -20,4 +20,4 @@ OBJS=truetype.obj all : $(OBJS) library [--.lib]freetype.olb $(OBJS) -# EOF +# EOF diff --git a/src/libs/freetype2/truetype/module.mk b/src/libs/freetype2/truetype/module.mk index 60279f51a0..bb042beae1 100644 --- a/src/libs/freetype2/truetype/module.mk +++ b/src/libs/freetype2/truetype/module.mk @@ -19,4 +19,4 @@ add_truetype_driver: $(OPEN_DRIVER)tt_driver_class$(CLOSE_DRIVER) $(ECHO_DRIVER)truetype $(ECHO_DRIVER_DESC)Windows/Mac font files with extension *.ttf or *.ttc$(ECHO_DRIVER_DONE) -# EOF +# EOF diff --git a/src/libs/freetype2/truetype/rules.mk b/src/libs/freetype2/truetype/rules.mk index 4e00022a64..bbb0c9f8ec 100644 --- a/src/libs/freetype2/truetype/rules.mk +++ b/src/libs/freetype2/truetype/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2001 by +# Copyright 1996-2000, 2001, 2003 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -15,27 +15,26 @@ # TrueType driver directory # -TT_DIR := $(SRC_)truetype -TT_DIR_ := $(TT_DIR)$(SEP) +TT_DIR := $(SRC_DIR)/truetype # compilation flags for the driver # -TT_COMPILE := $(FT_COMPILE) $I$(TT_DIR) +TT_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(TT_DIR)) # TrueType driver sources (i.e., C files) # -TT_DRV_SRC := $(TT_DIR_)ttobjs.c \ - $(TT_DIR_)ttpload.c \ - $(TT_DIR_)ttgload.c \ - $(TT_DIR_)ttinterp.c \ - $(TT_DIR_)ttdriver.c +TT_DRV_SRC := $(TT_DIR)/ttobjs.c \ + $(TT_DIR)/ttpload.c \ + $(TT_DIR)/ttgload.c \ + $(TT_DIR)/ttinterp.c \ + $(TT_DIR)/ttdriver.c # TrueType driver headers # TT_DRV_H := $(TT_DRV_SRC:%.c=%.h) \ - $(TT_DIR_)tterrors.h + $(TT_DIR)/tterrors.h # TrueType driver object(s) @@ -43,24 +42,24 @@ TT_DRV_H := $(TT_DRV_SRC:%.c=%.h) \ # TT_DRV_OBJ_M is used during `multi' builds # TT_DRV_OBJ_S is used during `single' builds # -TT_DRV_OBJ_M := $(TT_DRV_SRC:$(TT_DIR_)%.c=$(OBJ_)%.$O) -TT_DRV_OBJ_S := $(OBJ_)truetype.$O +TT_DRV_OBJ_M := $(TT_DRV_SRC:$(TT_DIR)/%.c=$(OBJ_DIR)/%.$O) +TT_DRV_OBJ_S := $(OBJ_DIR)/truetype.$O # TrueType driver source file for single build # -TT_DRV_SRC_S := $(TT_DIR_)truetype.c +TT_DRV_SRC_S := $(TT_DIR)/truetype.c # TrueType driver - single object # $(TT_DRV_OBJ_S): $(TT_DRV_SRC_S) $(TT_DRV_SRC) $(FREETYPE_H) $(TT_DRV_H) - $(TT_COMPILE) $T$@ $(TT_DRV_SRC_S) + $(TT_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(TT_DRV_SRC_S)) # driver - multiple objects # -$(OBJ_)%.$O: $(TT_DIR_)%.c $(FREETYPE_H) $(TT_DRV_H) - $(TT_COMPILE) $T$@ $< +$(OBJ_DIR)/%.$O: $(TT_DIR)/%.c $(FREETYPE_H) $(TT_DRV_H) + $(TT_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) # update main driver object lists @@ -68,4 +67,5 @@ $(OBJ_)%.$O: $(TT_DIR_)%.c $(FREETYPE_H) $(TT_DRV_H) DRV_OBJS_S += $(TT_DRV_OBJ_S) DRV_OBJS_M += $(TT_DRV_OBJ_M) -# EOF + +# EOF diff --git a/src/libs/freetype2/truetype/truetype.c b/src/libs/freetype2/truetype/truetype.c index c2fe42ab7f..1ed3cebc99 100644 --- a/src/libs/freetype2/truetype/truetype.c +++ b/src/libs/freetype2/truetype/truetype.c @@ -29,4 +29,4 @@ #endif -/* END */ +/* END */ diff --git a/src/libs/freetype2/truetype/ttdriver.c b/src/libs/freetype2/truetype/ttdriver.c index 965747edac..a5b800d538 100644 --- a/src/libs/freetype2/truetype/ttdriver.c +++ b/src/libs/freetype2/truetype/ttdriver.c @@ -4,7 +4,7 @@ /* */ /* TrueType font driver implementation (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,6 +21,7 @@ #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_SFNT_H #include FT_TRUETYPE_IDS_H +#include FT_SERVICE_XFREE86_NAME_H #include "ttdriver.h" #include "ttgload.h" @@ -115,7 +116,7 @@ while ( left <= right ) { - FT_Int middle = left + ( ( right - left ) >> 1 ); + FT_Long middle = left + ( ( right - left ) >> 1 ); FT_ULong cur_pair; @@ -207,8 +208,8 @@ /* we need to use rounding in the following computations. Otherwise, * the resulting hinted outlines will be very slightly distorted */ - dim_x = ( ( char_width * horz_resolution + (36+32*72) ) / 72 ) & -64; - dim_y = ( ( char_height * vert_resolution + (36+32*72) ) / 72 ) & -64; + dim_x = ( ( char_width * horz_resolution + (36+32*72) ) / 72 ) & ~63; + dim_y = ( ( char_height * vert_resolution + (36+32*72) ) / 72 ) & ~63; } else { @@ -226,7 +227,7 @@ size->ttmetrics.valid = FALSE; #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - size->strike_index = 0xFFFF; + size->strike_index = 0xFFFFU; #endif return tt_size_reset( size ); @@ -242,11 +243,6 @@ /* A driver method used to reset a size's character sizes (horizontal */ /* and vertical) expressed in integer pixels. */ /* */ - /* */ - /* pixel_width :: The character width expressed in integer pixels. */ - /* */ - /* pixel_height :: The character height expressed in integer pixels. */ - /* */ /* */ /* size :: A handle to the target size object. */ /* */ @@ -254,19 +250,14 @@ /* FreeType error code. 0 means success. */ /* */ static FT_Error - Set_Pixel_Sizes( TT_Size size, - FT_UInt pixel_width, - FT_UInt pixel_height ) + Set_Pixel_Sizes( TT_Size size ) { - FT_UNUSED( pixel_width ); - FT_UNUSED( pixel_height ); - /* many things have been pre-computed by the base layer */ size->metrics = size->root.metrics; size->ttmetrics.valid = FALSE; #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - size->strike_index = 0xFFFF; + size->strike_index = 0xFFFFU; #endif return tt_size_reset( size ); @@ -302,7 +293,7 @@ static FT_Error Load_Glyph( TT_GlyphSlot slot, TT_Size size, - FT_UShort glyph_index, + FT_UInt glyph_index, FT_Int32 load_flags ) { FT_Error error; @@ -354,17 +345,27 @@ /*************************************************************************/ /*************************************************************************/ + static const FT_ServiceDescRec tt_services[] = + { + { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE }, + { NULL, NULL } + }; static FT_Module_Interface tt_get_interface( TT_Driver driver, const char* tt_interface ) { - FT_Module sfntd = FT_Get_Module( driver->root.root.library, - "sfnt" ); - SFNT_Service sfnt; + FT_Module_Interface result; + FT_Module sfntd; + SFNT_Service sfnt; + result = ft_service_list_lookup( tt_services, tt_interface ); + if ( result != NULL ) + return result; + /* only return the default interface from the SFNT module */ + sfntd = FT_Get_Module( driver->root.root.library, "sfnt" ); if ( sfntd ) { sfnt = (SFNT_Service)( sfntd->clazz->module_interface ); @@ -382,10 +383,10 @@ const FT_Driver_ClassRec tt_driver_class = { { - ft_module_font_driver | - ft_module_driver_scalable | + FT_MODULE_FONT_DRIVER | + FT_MODULE_DRIVER_SCALABLE | #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - ft_module_driver_has_hinter, + FT_MODULE_DRIVER_HAS_HINTER, #else 0, #endif @@ -408,21 +409,21 @@ sizeof ( FT_GlyphSlotRec ), - (FT_Face_InitFunc) tt_face_init, - (FT_Face_DoneFunc) tt_face_done, - (FT_Size_InitFunc) tt_size_init, - (FT_Size_DoneFunc) tt_size_done, - (FT_Slot_InitFunc) 0, - (FT_Slot_DoneFunc) 0, + (FT_Face_InitFunc) tt_face_init, + (FT_Face_DoneFunc) tt_face_done, + (FT_Size_InitFunc) tt_size_init, + (FT_Size_DoneFunc) tt_size_done, + (FT_Slot_InitFunc) 0, + (FT_Slot_DoneFunc) 0, - (FT_Size_ResetPointsFunc) Set_Char_Sizes, - (FT_Size_ResetPixelsFunc) Set_Pixel_Sizes, - (FT_Slot_LoadFunc) Load_Glyph, + (FT_Size_ResetPointsFunc)Set_Char_Sizes, + (FT_Size_ResetPixelsFunc)Set_Pixel_Sizes, + (FT_Slot_LoadFunc) Load_Glyph, - (FT_Face_GetKerningFunc) Get_Kerning, - (FT_Face_AttachFunc) 0, - (FT_Face_GetAdvancesFunc) 0 + (FT_Face_GetKerningFunc) Get_Kerning, + (FT_Face_AttachFunc) 0, + (FT_Face_GetAdvancesFunc)0 }; -/* END */ +/* END */ diff --git a/src/libs/freetype2/truetype/ttdriver.h b/src/libs/freetype2/truetype/ttdriver.h index f6dbcd0521..f6f26e4b59 100644 --- a/src/libs/freetype2/truetype/ttdriver.h +++ b/src/libs/freetype2/truetype/ttdriver.h @@ -35,4 +35,4 @@ FT_END_HEADER #endif /* __TTDRIVER_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/truetype/tterrors.h b/src/libs/freetype2/truetype/tterrors.h index 10e39297d4..d317c70e0e 100644 --- a/src/libs/freetype2/truetype/tterrors.h +++ b/src/libs/freetype2/truetype/tterrors.h @@ -37,4 +37,4 @@ #endif /* __TTERRORS_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/truetype/ttgload.c b/src/libs/freetype2/truetype/ttgload.c index 8d64c1d59f..00da0c2240 100644 --- a/src/libs/freetype2/truetype/ttgload.c +++ b/src/libs/freetype2/truetype/ttgload.c @@ -4,7 +4,7 @@ /* */ /* TrueType Glyph Loader (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -162,11 +162,62 @@ } + /*************************************************************************/ + /* */ + /* Returns the vertical metrics in font units for a given glyph. */ + /* Greg Hitchcock from Microsoft told us that if there were no `vmtx' */ + /* table, typoAscender/Descender from the `OS/2' table would be used */ + /* instead, and if there were no `OS/2' table, use ascender/descender */ + /* from the `hhea' table. But that is not what Microsoft's rasterizer */ + /* apparently does: It uses the ppem value as the advance height, and */ + /* sets the top side bearing to be zero. */ + /* */ + /* The monospace `check' is probably not meaningful here, but we leave */ + /* it in for a consistent interface. */ + /* */ + static void + Get_VMetrics( TT_Face face, + FT_UInt idx, + FT_Bool check, + FT_Short* tsb, + FT_UShort* ah ) + { + FT_UNUSED( check ); + + if ( face->vertical_info ) + TT_Get_Metrics( (TT_HoriHeader *)&face->vertical, idx, tsb, ah ); + +#if 1 /* Emperically determined, at variance with what MS said */ + + else + { + *tsb = 0; + *ah = face->root.units_per_EM; + } + +#else /* This is what MS said to do. It isn't what they do, however. */ + + else if ( face->os2.version != 0xFFFFU ) + { + *tsb = face->os2.sTypoAscender; + *ah = face->os2.sTypoAscender - face->os2.sTypoDescender; + } + else + { + *tsb = face->horizontal.Ascender; + *ah = face->horizontal.Ascender - face->horizontal.Descender; + } + +#endif + + } + + #define cur_to_org( n, zone ) \ - FT_MEM_COPY( (zone)->org, (zone)->cur, (n) * sizeof ( FT_Vector ) ) + FT_ARRAY_COPY( (zone)->org, (zone)->cur, (n) ) #define org_to_cur( n, zone ) \ - FT_MEM_COPY( (zone)->cur, (zone)->org, (n) * sizeof ( FT_Vector ) ) + FT_ARRAY_COPY( (zone)->cur, (zone)->org, (n) ) /*************************************************************************/ @@ -294,44 +345,47 @@ FT_Int n, n_points; FT_Int byte_len = load->byte_len; + FT_Byte *flag, *flag_limit; + FT_Byte c, count; + FT_Vector *vec, *vec_limit; + FT_Pos x; + FT_Short *cont, *cont_limit; + /* reading the contours endpoints & number of points */ - { - short* cur = gloader->current.outline.contours; - short* limit = cur + n_contours; + cont = gloader->current.outline.contours; + cont_limit = cont + n_contours; + /* check space for contours array + instructions count */ + byte_len -= 2 * ( n_contours + 1 ); + if ( byte_len < 0 ) + goto Invalid_Outline; - /* check space for contours array + instructions count */ - byte_len -= 2 * ( n_contours + 1 ); - if ( byte_len < 0 ) + for ( ; cont < cont_limit; cont++ ) + cont[0] = FT_GET_USHORT(); + + n_points = 0; + if ( n_contours > 0 ) + n_points = cont[-1] + 1; + + error = FT_GlyphLoader_CheckPoints( gloader, n_points + 4, 0 ); + if ( error ) + goto Fail; + + /* we'd better check the contours table right now */ + outline = &gloader->current.outline; + + for ( cont = outline->contours + 1; cont < cont_limit; cont++ ) + if ( cont[-1] >= cont[0] ) goto Invalid_Outline; - for ( ; cur < limit; cur++ ) - cur[0] = FT_GET_USHORT(); - - n_points = 0; - if ( n_contours > 0 ) - n_points = cur[-1] + 1; - - error = FT_GlyphLoader_CheckPoints( gloader, n_points + 2, 0 ); - if ( error ) - goto Fail; - - /* we'd better check the contours table right now */ - outline = &gloader->current.outline; - - for ( cur = outline->contours + 1; cur < limit; cur++ ) - if ( cur[-1] >= cur[0] ) - goto Invalid_Outline; - } - /* reading the bytecode instructions */ slot->control_len = 0; slot->control_data = 0; n_ins = FT_GET_USHORT(); - FT_TRACE5(( " Instructions size: %d\n", n_ins )); + FT_TRACE5(( " Instructions size: %u\n", n_ins )); if ( n_ins > face->max_profile.maxSizeOfInstructions ) { @@ -340,7 +394,7 @@ goto Fail; } - byte_len -= n_ins; + byte_len -= (FT_Int)n_ins; if ( byte_len < 0 ) { FT_TRACE0(( "TT_Load_Simple_Glyph: Instruction count mismatch!\n" )); @@ -357,112 +411,102 @@ slot->control_len = n_ins; slot->control_data = load->instructions; - FT_MEM_COPY( load->instructions, stream->cursor, n_ins ); + FT_MEM_COPY( load->instructions, stream->cursor, (FT_Long)n_ins ); } #endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ - stream->cursor += n_ins; + stream->cursor += (FT_Int)n_ins; /* reading the point tags */ + flag = (FT_Byte*)outline->tags; + flag_limit = flag + n_points; + + while ( flag < flag_limit ) { - FT_Byte* flag = (FT_Byte*)outline->tags; - FT_Byte* limit = flag + n_points; - FT_Byte c, count; + if ( --byte_len < 0 ) + goto Invalid_Outline; - - while ( flag < limit ) + *flag++ = c = FT_GET_BYTE(); + if ( c & 8 ) { if ( --byte_len < 0 ) goto Invalid_Outline; - *flag++ = c = FT_GET_BYTE(); - if ( c & 8 ) - { - if ( --byte_len < 0 ) - goto Invalid_Outline; + count = FT_GET_BYTE(); + if ( flag + (FT_Int)count > flag_limit ) + goto Invalid_Outline; - count = FT_GET_BYTE(); - if ( flag + count > limit ) - goto Invalid_Outline; - - for ( ; count > 0; count-- ) - *flag++ = c; - } + for ( ; count > 0; count-- ) + *flag++ = c; } - - /* check that there is enough room to load the coordinates */ - for ( flag = (FT_Byte*)outline->tags; flag < limit; flag++ ) - { - if ( *flag & 2 ) - byte_len -= 1; - else if ( ( *flag & 16 ) == 0 ) - byte_len -= 2; - - if ( *flag & 4 ) - byte_len -= 1; - else if ( ( *flag & 32 ) == 0 ) - byte_len -= 2; - } - - if ( byte_len < 0 ) - goto Invalid_Outline; } + /* check that there is enough room to load the coordinates */ + for ( flag = (FT_Byte*)outline->tags; flag < flag_limit; flag++ ) + { + if ( *flag & 2 ) + byte_len -= 1; + else if ( ( *flag & 16 ) == 0 ) + byte_len -= 2; + + if ( *flag & 4 ) + byte_len -= 1; + else if ( ( *flag & 32 ) == 0 ) + byte_len -= 2; + } + + if ( byte_len < 0 ) + goto Invalid_Outline; + /* reading the X coordinates */ + vec = outline->points; + vec_limit = vec + n_points; + flag = (FT_Byte*)outline->tags; + x = 0; + + for ( ; vec < vec_limit; vec++, flag++ ) { - FT_Vector* vec = outline->points; - FT_Vector* limit = vec + n_points; - FT_Byte* flag = (FT_Byte*)outline->tags; - FT_Pos x = 0; + FT_Pos y = 0; - for ( ; vec < limit; vec++, flag++ ) + if ( *flag & 2 ) { - FT_Pos y = 0; - - - if ( *flag & 2 ) - { - y = FT_GET_BYTE(); - if ( ( *flag & 16 ) == 0 ) - y = -y; - } - else if ( ( *flag & 16 ) == 0 ) - y = FT_GET_SHORT(); - - x += y; - vec->x = x; + y = (FT_Pos)FT_GET_BYTE(); + if ( ( *flag & 16 ) == 0 ) + y = -y; } + else if ( ( *flag & 16 ) == 0 ) + y = (FT_Pos)FT_GET_SHORT(); + + x += y; + vec->x = x; } /* reading the Y coordinates */ + vec = gloader->current.outline.points; + vec_limit = vec + n_points; + flag = (FT_Byte*)outline->tags; + x = 0; + + for ( ; vec < vec_limit; vec++, flag++ ) { - FT_Vector* vec = gloader->current.outline.points; - FT_Vector* limit = vec + n_points; - FT_Byte* flag = (FT_Byte*)outline->tags; - FT_Pos x = 0; + FT_Pos y = 0; - for ( ; vec < limit; vec++, flag++ ) + if ( *flag & 4 ) { - FT_Pos y = 0; - - - if ( *flag & 4 ) - { - y = FT_GET_BYTE(); - if ( ( *flag & 32 ) == 0 ) - y = -y; - } - else if ( ( *flag & 32 ) == 0 ) - y = FT_GET_SHORT(); - - x += y; - vec->y = x; + y = (FT_Pos)FT_GET_BYTE(); + if ( ( *flag & 32 ) == 0 ) + y = -y; } + else if ( ( *flag & 32 ) == 0 ) + y = (FT_Pos)FT_GET_SHORT(); + + x += y; + vec->y = x; } /* clear the touch tags */ @@ -642,12 +686,16 @@ /* add shadow points */ - /* Now add the two shadow points at n and n + 1. */ + /* Add two horizontal shadow points at n and n+1. */ /* We need the left side bearing and advance width. */ + /* Add two vertical shadow points at n+2 and n+3. */ + /* We need the top side bearing and advance height. */ { FT_Vector* pp1; FT_Vector* pp2; + FT_Vector* pp3; + FT_Vector* pp4; /* pp1 = xMin - lsb */ @@ -660,14 +708,26 @@ pp2->x = pp1->x + load->advance; pp2->y = 0; + /* pp3 = top side bearing */ + pp3 = pp1 + 2; + pp3->x = 0; + pp3->y = load->top_bearing + load->bbox.yMax; + + /* pp4 = pp3 - ah */ + pp4 = pp1 + 3; + pp4->x = 0; + pp4->y = pp3->y - load->vadvance; + outline->tags[n_points ] = 0; outline->tags[n_points + 1] = 0; + outline->tags[n_points + 2] = 0; + outline->tags[n_points + 3] = 0; } /* Note that we return two more points that are not */ /* part of the glyph outline. */ - n_points += 2; + n_points += 4; /* set up zone for hinting */ tt_prepare_zone( zone, &gloader->current, 0, 0 ); @@ -694,15 +754,18 @@ /* eventually hint the glyph */ if ( IS_HINTED( load->load_flags ) ) { - FT_Pos x = zone->org[n_points-2].x; + FT_Pos x = zone->org[n_points-4].x; + FT_Pos y = zone->org[n_points-2].y; - x = ( ( x + 32 ) & -64 ) - x; - translate_array( n_points, zone->org, x, 0 ); + x = FT_PIX_ROUND( x ) - x; + y = FT_PIX_ROUND( y ) - y; + translate_array( n_points, zone->org, x, y ); org_to_cur( n_points, zone ); - zone->cur[n_points - 1].x = ( zone->cur[n_points - 1].x + 32 ) & -64; + zone->cur[n_points - 3].x = FT_PIX_ROUND( zone->cur[n_points - 3].x ); + zone->cur[n_points - 1].y = FT_PIX_ROUND( zone->cur[n_points - 1].y ); #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER @@ -718,7 +781,7 @@ load->exec->pedantic_hinting = (FT_Bool)( load->load_flags & FT_LOAD_PEDANTIC ); load->exec->pts = *zone; - load->exec->pts.n_points += 2; + load->exec->pts.n_points += 4; error = TT_Run_Context( load->exec, debug ); if ( error && load->exec->pedantic_hinting ) @@ -734,8 +797,10 @@ /* save glyph phantom points */ if ( !load->preserve_pps ) { - load->pp1 = zone->cur[n_points - 2]; - load->pp2 = zone->cur[n_points - 1]; + load->pp1 = zone->cur[n_points - 4]; + load->pp2 = zone->cur[n_points - 3]; + load->pp3 = zone->cur[n_points - 2]; + load->pp4 = zone->cur[n_points - 1]; } #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER @@ -779,6 +844,7 @@ FT_Bool glyph_data_loaded = 0; #endif + if ( recurse_count >= TT_MAX_COMPOSITE_RECURSE ) { error = TT_Err_Invalid_Composite; @@ -803,16 +869,22 @@ y_scale = loader->size->metrics.y_scale; } - /* get horizontal metrics */ + /* get metrics, horizontal and vertical */ { - FT_Short left_bearing = 0; - FT_UShort advance_width = 0; + FT_Short left_bearing = 0, top_bearing = 0; + FT_UShort advance_width = 0, advance_height = 0; + Get_HMetrics( face, glyph_index, (FT_Bool)!( loader->load_flags & FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ), &left_bearing, &advance_width ); + Get_VMetrics( face, glyph_index, + (FT_Bool)!( loader->load_flags & + FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ), + &top_bearing, + &advance_height ); #ifdef FT_CONFIG_OPTION_INCREMENTAL @@ -823,9 +895,10 @@ { FT_Incremental_MetricsRec metrics; - metrics.bearing_x = left_bearing; - metrics.bearing_y = 0; - metrics.advance = advance_width; + + metrics.bearing_x = left_bearing; + metrics.bearing_y = 0; + metrics.advance = advance_width; error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( face->root.internal->incremental_interface->object, glyph_index, FALSE, &metrics ); @@ -835,10 +908,33 @@ advance_width = (FT_UShort)metrics.advance; } +# if 0 + /* GWW: Do I do the same for vertical metrics ??? */ + if ( face->root.internal->incremental_interface && + face->root.internal->incremental_interface->funcs->get_glyph_metrics ) + { + FT_Incremental_MetricsRec metrics; + + + metrics.bearing_x = 0; + metrics.bearing_y = top_bearing; + metrics.advance = advance_height; + error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( + face->root.internal->incremental_interface->object, + glyph_index, TRUE, &metrics ); + if ( error ) + goto Exit; + top_bearing = (FT_Short)metrics.bearing_y; + advance_height = (FT_UShort)metrics.advance; + } +# endif + #endif /* FT_CONFIG_OPTION_INCREMENTAL */ loader->left_bearing = left_bearing; loader->advance = advance_width; + loader->top_bearing = top_bearing; + loader->vadvance = advance_height; if ( !loader->linear_def ) { @@ -884,7 +980,7 @@ count = 0; if ( glyph_index < (FT_UInt)face->num_locations - 1 ) - count = face->glyph_locations[glyph_index + 1] - offset; + count = (FT_UInt)( face->glyph_locations[glyph_index + 1] - offset ); } if ( count == 0 ) @@ -898,9 +994,14 @@ loader->pp1.x = 0; loader->pp2.x = loader->advance; + loader->pp3.y = 0; + loader->pp4.y = loader->pp3.y-loader->vadvance; if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) + { loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale ); + loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale ); + } #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER @@ -938,10 +1039,17 @@ loader->pp2.x = loader->pp1.x + loader->advance; loader->pp2.y = 0; + loader->pp3.x = 0; + loader->pp3.y = loader->top_bearing + loader->bbox.yMax; + loader->pp4.x = 0; + loader->pp4.y = loader->pp3.y - loader->vadvance; + if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) { loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale ); loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale ); + loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale ); + loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale ); } /***********************************************************************/ @@ -1050,7 +1158,7 @@ for ( n = 0; n < (FT_Int)num_subglyphs; n++ ) { - FT_Vector pp1, pp2; + FT_Vector pp1, pp2, pp3, pp4; FT_Pos x, y; @@ -1062,11 +1170,13 @@ pp1 = loader->pp1; pp2 = loader->pp2; + pp3 = loader->pp3; + pp4 = loader->pp4; num_base_points = gloader->base.outline.n_points; error = load_truetype_glyph( loader, subglyph->index, - recurse_count+1 ); + recurse_count + 1 ); if ( error ) goto Fail; @@ -1077,11 +1187,15 @@ { pp1 = loader->pp1; pp2 = loader->pp2; + pp3 = loader->pp3; + pp4 = loader->pp4; } else { loader->pp1 = pp1; loader->pp2 = pp2; + loader->pp3 = pp3; + loader->pp4 = pp4; } num_points = gloader->base.outline.n_points; @@ -1182,16 +1296,16 @@ /* */ /* This algorithm is a guess and works much better than the above. */ /* */ - int mac_xscale = FT_SqrtFixed( - FT_MulFix( subglyph->transform.xx, - subglyph->transform.xx ) + - FT_MulFix( subglyph->transform.xy, - subglyph->transform.xy) ); - int mac_yscale = FT_SqrtFixed( - FT_MulFix( subglyph->transform.yy, - subglyph->transform.yy ) + - FT_MulFix( subglyph->transform.yx, - subglyph->transform.yx ) ); + FT_Fixed mac_xscale = FT_SqrtFixed( + FT_MulFix( subglyph->transform.xx, + subglyph->transform.xx ) + + FT_MulFix( subglyph->transform.xy, + subglyph->transform.xy) ); + FT_Fixed mac_yscale = FT_SqrtFixed( + FT_MulFix( subglyph->transform.yy, + subglyph->transform.yy ) + + FT_MulFix( subglyph->transform.yx, + subglyph->transform.yx ) ); x = FT_MulFix( x, mac_xscale ); @@ -1207,8 +1321,8 @@ if ( subglyph->flags & ROUND_XY_TO_GRID ) { - x = ( x + 32 ) & -64; - y = ( y + 32 ) & -64; + x = FT_PIX_ROUND( x ); + y = FT_PIX_ROUND( y ); } } } @@ -1278,27 +1392,37 @@ if ( error ) goto Fail; + error = FT_GlyphLoader_CheckPoints( gloader, num_points + 4, 0 ); + if ( error ) + goto Fail; + /* prepare the execution context */ tt_prepare_zone( &exec->pts, &gloader->base, start_point, start_contour ); pts = &exec->pts; - pts->n_points = (short)(num_points + 2); + pts->n_points = (short)( num_points + 4 ); pts->n_contours = gloader->base.outline.n_contours; /* add phantom points */ pp1 = pts->cur + num_points; pp1[0] = loader->pp1; pp1[1] = loader->pp2; + pp1[2] = loader->pp3; + pp1[3] = loader->pp4; pts->tags[num_points ] = 0; pts->tags[num_points + 1] = 0; + pts->tags[num_points + 2] = 0; + pts->tags[num_points + 3] = 0; /* if hinting, round the phantom points */ if ( IS_HINTED( loader->load_flags ) ) { - pp1[0].x = ( ( loader->pp1.x + 32 ) & -64 ); - pp1[1].x = ( ( loader->pp2.x + 32 ) & -64 ); + pp1[0].x = FT_PIX_ROUND( loader->pp1.x ); + pp1[1].x = FT_PIX_ROUND( loader->pp2.x ); + pp1[2].y = FT_PIX_ROUND( loader->pp3.y ); + pp1[3].y = FT_PIX_ROUND( loader->pp4.y ); } { @@ -1309,7 +1433,7 @@ pts->tags[k] &= FT_CURVE_TAG_ON; } - cur_to_org( num_points + 2, pts ); + cur_to_org( num_points + 4, pts ); /* now consider hinting */ if ( IS_HINTED( loader->load_flags ) && n_ins > 0 ) @@ -1325,6 +1449,8 @@ /* save glyph origin and advance points */ loader->pp1 = pp1[0]; loader->pp2 = pp1[1]; + loader->pp3 = pp1[2]; + loader->pp4 = pp1[3]; } #endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ @@ -1391,10 +1517,10 @@ if ( IS_HINTED( loader->load_flags ) ) { /* grid-fit the bounding box */ - bbox.xMin &= -64; - bbox.yMin &= -64; - bbox.xMax = ( bbox.xMax + 63 ) & -64; - bbox.yMax = ( bbox.yMax + 63 ) & -64; + bbox.xMin = FT_PIX_FLOOR( bbox.xMin ); + bbox.yMin = FT_PIX_FLOOR( bbox.yMin ); + bbox.xMax = FT_PIX_CEIL( bbox.xMax ); + bbox.yMax = FT_PIX_CEIL( bbox.yMax ); } } else @@ -1426,7 +1552,7 @@ /* don't forget to hint the advance when we need to */ if ( IS_HINTED( loader->load_flags ) ) - glyph->metrics.horiAdvance = ( glyph->metrics.horiAdvance + 32 ) & -64; + glyph->metrics.horiAdvance = FT_PIX_ROUND( glyph->metrics.horiAdvance ); /* Now take care of vertical metrics. In the case where there is */ /* no vertical information within the font (relatively common), make */ @@ -1444,13 +1570,9 @@ if ( face->vertical_info && face->vertical.number_Of_VMetrics > 0 ) { - /* Don't assume that both the vertical header and vertical */ - /* metrics are present in the same font :-) */ + advance_height = loader->pp4.y - loader->pp3.y; + top_bearing = loader->pp3.y - bbox.yMax; - TT_Get_Metrics( (TT_HoriHeader*)&face->vertical, - glyph_index, - &top_bearing, - &advance_height ); } else { @@ -1466,6 +1588,12 @@ /* here with: */ /* ascender - descender + linegap */ /* */ + /* NOTE3: This is different from what MS's rasterizer */ + /* appears to do when getting default values */ + /* for the vertical phantom points. We leave */ + /* the old code untouched, but relying on */ + /* phantom points alone might be reasonable */ + /* (i.e., removing the `if' above). */ if ( face->os2.version != 0xFFFFU ) { top_bearing = (FT_Short)( face->os2.sTypoLineGap / 2 ); @@ -1492,9 +1620,10 @@ FT_Incremental_MetricsRec metrics; FT_Error error = 0; - metrics.bearing_x = 0; - metrics.bearing_y = top_bearing; - metrics.advance = advance_height; + + metrics.bearing_x = 0; + metrics.bearing_y = top_bearing; + metrics.advance = advance_height; error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( face->root.internal->incremental_interface->object, @@ -1507,6 +1636,8 @@ advance_height = (FT_UShort)metrics.advance; } + /* GWW: Do vertical metrics get loaded incrementally too? */ + #endif /* FT_CONFIG_OPTION_INCREMENTAL */ /* We must adjust the top_bearing value from the bounding box given */ @@ -1538,9 +1669,9 @@ /* grid-fit them if necessary */ if ( IS_HINTED( loader->load_flags ) ) { - left &= -64; - top = ( top + 63 ) & -64; - advance = ( advance + 32 ) & -64; + left = FT_PIX_FLOOR( left ); + top = FT_PIX_CEIL( top ); + advance = FT_PIX_ROUND( advance ); } glyph->metrics.vertBearingX = left; @@ -1598,7 +1729,7 @@ FT_LOCAL_DEF( FT_Error ) TT_Load_Glyph( TT_Size size, TT_GlyphSlot glyph, - FT_UShort glyph_index, + FT_UInt glyph_index, FT_Int32 load_flags ) { SFNT_Service sfnt; @@ -1640,9 +1771,9 @@ error = sfnt->load_sbit_image( face, - size->strike_index, + (FT_ULong)size->strike_index, glyph_index, - load_flags, + (FT_Int)load_flags, stream, &glyph->bitmap, &metrics ); @@ -1681,7 +1812,7 @@ /* return immediately if we only want the embedded bitmaps */ if ( load_flags & FT_LOAD_SBITS_ONLY ) - return FT_Err_Invalid_Argument; + return TT_Err_Invalid_Argument; /* seek to the beginning of the glyph table. For Type 42 fonts */ /* the table might be accessed from a Postscript stream or something */ @@ -1795,4 +1926,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/truetype/ttgload.h b/src/libs/freetype2/truetype/ttgload.h index 3922d1c1a9..dfa2a60a5c 100644 --- a/src/libs/freetype2/truetype/ttgload.h +++ b/src/libs/freetype2/truetype/ttgload.h @@ -4,7 +4,7 @@ /* */ /* TrueType Glyph Loader (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -33,7 +33,7 @@ FT_BEGIN_HEADER FT_LOCAL( void ) TT_Get_Metrics( TT_HoriHeader* header, - FT_UInt index, + FT_UInt idx, FT_Short* bearing, FT_UShort* advance ); @@ -43,7 +43,7 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) TT_Load_Glyph( TT_Size size, TT_GlyphSlot glyph, - FT_UShort glyph_index, + FT_UInt glyph_index, FT_Int32 load_flags ); @@ -52,4 +52,4 @@ FT_END_HEADER #endif /* __TTGLOAD_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/truetype/ttinterp.c b/src/libs/freetype2/truetype/ttinterp.c index befb0be988..889ebbf4f2 100644 --- a/src/libs/freetype2/truetype/ttinterp.c +++ b/src/libs/freetype2/truetype/ttinterp.c @@ -4,7 +4,7 @@ /* */ /* TrueType bytecode interpreter (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -30,9 +30,10 @@ #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER -#define TT_MULFIX FT_MulFix -#define TT_MULDIV FT_MulDiv -#define TT_INT64 FT_Int64 +#define TT_MULFIX FT_MulFix +#define TT_MULDIV FT_MulDiv +#define TT_MULDIV_NO_ROUND FT_MulDiv_No_Round + /*************************************************************************/ /* */ @@ -43,9 +44,6 @@ #undef FT_COMPONENT #define FT_COMPONENT trace_ttinterp -#undef NO_APPLE_PATENT -#define APPLE_THRESHOLD 0x4000000L - /*************************************************************************/ /* */ /* In order to detect infinite loops in the code, we set up a counter */ @@ -165,12 +163,12 @@ #define CUR_Func_move( z, p, d ) \ CUR.func_move( EXEC_ARG_ z, p, d ) +#define CUR_Func_move_orig( z, p, d ) \ + CUR.func_move_orig( EXEC_ARG_ z, p, d ) + #define CUR_Func_dualproj( x, y ) \ CUR.func_dualproj( EXEC_ARG_ x, y ) -#define CUR_Func_freeProj( x, y ) \ - CUR.func_freeProj( EXEC_ARG_ x, y ) - #define CUR_Func_round( d, c ) \ CUR.func_round( EXEC_ARG_ d, c ) @@ -221,13 +219,22 @@ /* */ #define BOUNDS( x, n ) ( (FT_UInt)(x) >= (FT_UInt)(n) ) - #undef SUCCESS #define SUCCESS 0 #undef FAILURE #define FAILURE 1 +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING +#define GUESS_VECTOR( V ) \ + if ( CUR.face->unpatented_hinting ) \ + { \ + CUR.GS.V.x = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0x4000 : 0 ); \ + CUR.GS.V.y = (FT_F2Dot14)( CUR.GS.both_x_axis ? 0 : 0x4000 ); \ + } +#else +#define GUESS_VECTOR( V ) +#endif /*************************************************************************/ /* */ @@ -512,8 +519,7 @@ if ( *size < new_max ) { - FT_FREE( *buff ); - if ( FT_ALLOC( *buff, new_max * multiplier ) ) + if ( FT_REALLOC( *buff, *size, new_max * multiplier ) ) return error; *size = new_max; } @@ -719,6 +725,10 @@ exec->GS.freeVector = exec->GS.projVector; exec->GS.dualVector = exec->GS.projVector; +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + exec->GS.both_x_axis = TRUE; +#endif + exec->GS.round_state = 1; exec->GS.loop = 1; @@ -746,6 +756,11 @@ { 0x4000, 0 }, { 0x4000, 0 }, { 0x4000, 0 }, + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + TRUE, +#endif + 1, 64, 1, TRUE, 68, 0, 0, 9, 3, 0, FALSE, 2, 1, 1, 1 @@ -1344,24 +1359,38 @@ static FT_Long Current_Ratio( EXEC_OP ) { - if ( CUR.tt_metrics.ratio ) - return CUR.tt_metrics.ratio; - - if ( CUR.GS.projVector.y == 0 ) - CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio; - - else if ( CUR.GS.projVector.x == 0 ) - CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio; - - else + if ( !CUR.tt_metrics.ratio ) { - FT_Long x, y; +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + if ( CUR.face->unpatented_hinting ) + { + if ( CUR.GS.both_x_axis ) + CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio; + else + CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio; + } + else +#endif + { + if ( CUR.GS.projVector.y == 0 ) + CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio; - x = TT_MULDIV( CUR.GS.projVector.x, CUR.tt_metrics.x_ratio, 0x4000 ); - y = TT_MULDIV( CUR.GS.projVector.y, CUR.tt_metrics.y_ratio, 0x4000 ); - CUR.tt_metrics.ratio = TT_VecLen( x, y ); + else if ( CUR.GS.projVector.x == 0 ) + CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio; + + else + { + FT_Long x, y; + + + x = TT_MULDIV( CUR.GS.projVector.x, + CUR.tt_metrics.x_ratio, 0x4000 ); + y = TT_MULDIV( CUR.GS.projVector.y, + CUR.tt_metrics.y_ratio, 0x4000 ); + CUR.tt_metrics.ratio = TT_VecLen( x, y ); + } + } } - return CUR.tt_metrics.ratio; } @@ -1532,24 +1561,18 @@ FT_F26Dot6 v; +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + FT_ASSERT( !CUR.face->unpatented_hinting ); +#endif + v = CUR.GS.freeVector.x; if ( v != 0 ) { - -#ifdef NO_APPLE_PATENT - - if ( ABS( CUR.F_dot_P ) > APPLE_THRESHOLD ) - zone->cur[point].x += distance; - -#else - zone->cur[point].x += TT_MULDIV( distance, v * 0x10000L, CUR.F_dot_P ); -#endif - zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; } @@ -1557,25 +1580,60 @@ if ( v != 0 ) { - -#ifdef NO_APPLE_PATENT - - if ( ABS( CUR.F_dot_P ) > APPLE_THRESHOLD ) - zone->cur[point].y += distance; - -#else - zone->cur[point].y += TT_MULDIV( distance, v * 0x10000L, CUR.F_dot_P ); -#endif - zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; } } + /*************************************************************************/ + /* */ + /* */ + /* Direct_Move_Orig */ + /* */ + /* */ + /* Moves the *original* position of a point by a given distance along */ + /* the freedom vector. Obviously, the point will not be `touched'. */ + /* */ + /* */ + /* point :: The index of the point to move. */ + /* */ + /* distance :: The distance to apply. */ + /* */ + /* */ + /* zone :: The affected glyph zone. */ + /* */ + static void + Direct_Move_Orig( EXEC_OP_ TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) + { + FT_F26Dot6 v; + + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + FT_ASSERT( !CUR.face->unpatented_hinting ); +#endif + + v = CUR.GS.freeVector.x; + + if ( v != 0 ) + zone->org[point].x += TT_MULDIV( distance, + v * 0x10000L, + CUR.F_dot_P ); + + v = CUR.GS.freeVector.y; + + if ( v != 0 ) + zone->org[point].y += TT_MULDIV( distance, + v * 0x10000L, + CUR.F_dot_P ); + } + + /*************************************************************************/ /* */ /* Special versions of Direct_Move() */ @@ -1610,6 +1668,38 @@ } + /*************************************************************************/ + /* */ + /* Special versions of Direct_Move_Orig() */ + /* */ + /* The following versions are used whenever both vectors are both */ + /* along one of the coordinate unit vectors, i.e. in 90% of the cases. */ + /* */ + /*************************************************************************/ + + + static void + Direct_Move_Orig_X( EXEC_OP_ TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) + { + FT_UNUSED_EXEC; + + zone->org[point].x += distance; + } + + + static void + Direct_Move_Orig_Y( EXEC_OP_ TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) + { + FT_UNUSED_EXEC; + + zone->org[point].y += distance; + } + + /*************************************************************************/ /* */ /* */ @@ -1644,7 +1734,7 @@ if ( distance >= 0 ) { val = distance + compensation; - if ( val < 0 ) + if ( distance && val < 0 ) val = 0; } else { @@ -1684,14 +1774,14 @@ if ( distance >= 0 ) { val = distance + compensation + 32; - if ( val > 0 ) + if ( distance && val > 0 ) val &= ~63; else val = 0; } else { - val = -( ( compensation - distance + 32 ) & -64 ); + val = -FT_PIX_ROUND( compensation - distance ); if ( val > 0 ) val = 0; } @@ -1727,13 +1817,13 @@ if ( distance >= 0 ) { - val = ( ( distance + compensation ) & -64 ) + 32; - if ( val < 0 ) + val = FT_PIX_FLOOR( distance + compensation ) + 32; + if ( distance && val < 0 ) val = 0; } else { - val = -( ( (compensation - distance) & -64 ) + 32 ); + val = -( FT_PIX_FLOOR( compensation - distance ) + 32 ); if ( val > 0 ) val = 0; } @@ -1770,7 +1860,7 @@ if ( distance >= 0 ) { val = distance + compensation; - if ( val > 0 ) + if ( distance && val > 0 ) val &= ~63; else val = 0; @@ -1814,14 +1904,14 @@ if ( distance >= 0 ) { val = distance + compensation + 63; - if ( val > 0 ) + if ( distance && val > 0 ) val &= ~63; else val = 0; } else { - val = -( ( compensation - distance + 63 ) & -64 ); + val = - FT_PIX_CEIL( compensation - distance ); if ( val > 0 ) val = 0; } @@ -1858,14 +1948,14 @@ if ( distance >= 0 ) { val = distance + compensation + 16; - if ( val > 0 ) + if ( distance && val > 0 ) val &= ~31; else val = 0; } else { - val = -( ( compensation - distance + 16 ) & -32 ); + val = -FT_PAD_ROUND( compensation - distance, 32 ); if ( val > 0 ) val = 0; } @@ -1907,7 +1997,7 @@ { val = ( distance - CUR.phase + CUR.threshold + compensation ) & -CUR.period; - if ( val < 0 ) + if ( distance && val < 0 ) val = 0; val += CUR.phase; } @@ -1955,7 +2045,7 @@ { val = ( ( distance - CUR.phase + CUR.threshold + compensation ) / CUR.period ) * CUR.period; - if ( val < 0 ) + if ( distance && val < 0 ) val = 0; val += CUR.phase; } @@ -2075,7 +2165,7 @@ break; case 0x30: - CUR.phase = GridPeriod * 3 / 4; + CUR.phase = CUR.period * 3 / 4; break; } @@ -2110,13 +2200,16 @@ Project( EXEC_OP_ FT_Vector* v1, FT_Vector* v2 ) { +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + FT_ASSERT( !CUR.face->unpatented_hinting ); +#endif + return TT_DotFix14( v1->x - v2->x, v1->y - v2->y, CUR.GS.projVector.x, CUR.GS.projVector.y ); } - /*************************************************************************/ /* */ /* */ @@ -2144,33 +2237,6 @@ } - /*************************************************************************/ - /* */ - /* */ - /* Free_Project */ - /* */ - /* */ - /* Computes the projection of the vector given by (v2-v1) along the */ - /* current freedom vector. */ - /* */ - /* */ - /* v1 :: First input vector. */ - /* v2 :: Second input vector. */ - /* */ - /* */ - /* The distance in F26dot6 format. */ - /* */ - static FT_F26Dot6 - Free_Project( EXEC_OP_ FT_Vector* v1, - FT_Vector* v2 ) - { - return TT_DotFix14( v1->x - v2->x, - v1->y - v2->y, - CUR.GS.freeVector.x, - CUR.GS.freeVector.y ); - } - - /*************************************************************************/ /* */ /* */ @@ -2235,24 +2301,63 @@ static void Compute_Funcs( EXEC_OP ) { - if ( CUR.GS.freeVector.x == 0x4000 ) +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + if ( CUR.face->unpatented_hinting ) { - CUR.func_freeProj = (TT_Project_Func)Project_x; - CUR.F_dot_P = CUR.GS.projVector.x * 0x10000L; - } - else - { - if ( CUR.GS.freeVector.y == 0x4000 ) + /* If both vectors point rightwards along the x axis, set */ + /* `both-x-axis' true, otherwise set it false. The x values only */ + /* need be tested because the vector has been normalised to a unit */ + /* vector of length 0x4000 = unity. */ + CUR.GS.both_x_axis = (FT_Bool)( CUR.GS.projVector.x == 0x4000 && + CUR.GS.freeVector.x == 0x4000 ); + + /* Throw away projection and freedom vector information */ + /* because the patents don't allow them to be stored. */ + /* The relevant US Patents are 5155805 and 5325479. */ + CUR.GS.projVector.x = 0; + CUR.GS.projVector.y = 0; + CUR.GS.freeVector.x = 0; + CUR.GS.freeVector.y = 0; + + if ( CUR.GS.both_x_axis ) { - CUR.func_freeProj = (TT_Project_Func)Project_y; - CUR.F_dot_P = CUR.GS.projVector.y * 0x10000L; + CUR.func_project = Project_x; + CUR.func_move = Direct_Move_X; + CUR.func_move_orig = Direct_Move_Orig_X; } else { - CUR.func_freeProj = (TT_Project_Func)Free_Project; + CUR.func_project = Project_y; + CUR.func_move = Direct_Move_Y; + CUR.func_move_orig = Direct_Move_Orig_Y; + } + + if ( CUR.GS.dualVector.x == 0x4000 ) + CUR.func_dualproj = Project_x; + else + { + if ( CUR.GS.dualVector.y == 0x4000 ) + CUR.func_dualproj = Project_y; + else + CUR.func_dualproj = Dual_Project; + } + + /* Force recalculation of cached aspect ratio */ + CUR.tt_metrics.ratio = 0; + + return; + } +#endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING */ + + if ( CUR.GS.freeVector.x == 0x4000 ) + CUR.F_dot_P = CUR.GS.projVector.x * 0x10000L; + else + { + if ( CUR.GS.freeVector.y == 0x4000 ) + CUR.F_dot_P = CUR.GS.projVector.y * 0x10000L; + else CUR.F_dot_P = (FT_Long)CUR.GS.projVector.x * CUR.GS.freeVector.x * 4 + (FT_Long)CUR.GS.projVector.y * CUR.GS.freeVector.y * 4; - } } if ( CUR.GS.projVector.x == 0x4000 ) @@ -2275,23 +2380,30 @@ CUR.func_dualproj = (TT_Project_Func)Dual_Project; } - CUR.func_move = (TT_Move_Func)Direct_Move; + CUR.func_move = (TT_Move_Func)Direct_Move; + CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig; if ( CUR.F_dot_P == 0x40000000L ) { if ( CUR.GS.freeVector.x == 0x4000 ) - CUR.func_move = (TT_Move_Func)Direct_Move_X; + { + CUR.func_move = (TT_Move_Func)Direct_Move_X; + CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_X; + } else { if ( CUR.GS.freeVector.y == 0x4000 ) - CUR.func_move = (TT_Move_Func)Direct_Move_Y; + { + CUR.func_move = (TT_Move_Func)Direct_Move_Y; + CUR.func_move_orig = (TT_Move_Func)Direct_Move_Orig_Y; + } } } /* at small sizes, F_dot_P can become too small, resulting */ /* in overflows and `spikes' in a number of glyphs like `w'. */ - if ( ABS( CUR.F_dot_P ) < 0x4000000L ) + if ( FT_ABS( CUR.F_dot_P ) < 0x4000000L ) CUR.F_dot_P = 0x40000000L; /* Disable cached aspect ratio */ @@ -2334,7 +2446,7 @@ FT_UNUSED_EXEC; - if ( ABS( Vx ) < 0x10000L && ABS( Vy ) < 0x10000L ) + if ( FT_ABS( Vx ) < 0x10000L && FT_ABS( Vy ) < 0x10000L ) { Vx *= 0x100; Vy *= 0x100; @@ -2503,6 +2615,8 @@ CUR.GS.projVector.y = B; \ CUR.GS.dualVector.y = B; \ \ + GUESS_VECTOR( freeVector ); \ + \ COMPUTE_Funcs(); \ } @@ -2518,6 +2632,8 @@ CUR.GS.freeVector.x = A; \ CUR.GS.freeVector.y = B; \ \ + GUESS_VECTOR( projVector ); \ + \ COMPUTE_Funcs(); \ } @@ -2529,6 +2645,7 @@ &CUR.GS.projVector ) == SUCCESS ) \ { \ CUR.GS.dualVector = CUR.GS.projVector; \ + GUESS_VECTOR( freeVector ); \ COMPUTE_Funcs(); \ } @@ -2538,10 +2655,14 @@ (FT_UShort)args[0], \ CUR.opcode, \ &CUR.GS.freeVector ) == SUCCESS ) \ - COMPUTE_Funcs(); + { \ + GUESS_VECTOR( projVector ); \ + COMPUTE_Funcs(); \ + } #define DO_SFVTPV \ + GUESS_VECTOR( projVector ); \ CUR.GS.freeVector = CUR.GS.projVector; \ COMPUTE_Funcs(); @@ -2561,6 +2682,7 @@ NORMalize( X, Y, &CUR.GS.projVector ); \ \ CUR.GS.dualVector = CUR.GS.projVector; \ + GUESS_VECTOR( freeVector ); \ COMPUTE_Funcs(); \ } @@ -2578,18 +2700,47 @@ X = S; \ \ NORMalize( X, Y, &CUR.GS.freeVector ); \ + GUESS_VECTOR( projVector ); \ COMPUTE_Funcs(); \ } -#define DO_GPV \ - args[0] = CUR.GS.projVector.x; \ +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING +#define DO_GPV \ + if ( CUR.face->unpatented_hinting ) \ + { \ + args[0] = CUR.GS.both_x_axis ? 0x4000 : 0; \ + args[1] = CUR.GS.both_x_axis ? 0 : 0x4000; \ + } \ + else \ + { \ + args[0] = CUR.GS.projVector.x; \ + args[1] = CUR.GS.projVector.y; \ + } +#else +#define DO_GPV \ + args[0] = CUR.GS.projVector.x; \ args[1] = CUR.GS.projVector.y; +#endif -#define DO_GFV \ - args[0] = CUR.GS.freeVector.x; \ +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING +#define DO_GFV \ + if ( CUR.face->unpatented_hinting ) \ + { \ + args[0] = CUR.GS.both_x_axis ? 0x4000 : 0; \ + args[1] = CUR.GS.both_x_axis ? 0 : 0x4000; \ + } \ + else \ + { \ + args[0] = CUR.GS.freeVector.x; \ + args[1] = CUR.GS.freeVector.y; \ + } +#else +#define DO_GFV \ + args[0] = CUR.GS.freeVector.x; \ args[1] = CUR.GS.freeVector.y; +#endif #define DO_SRP0 \ @@ -2823,19 +2974,19 @@ args[0] -= args[1]; -#define DO_DIV \ - if ( args[1] == 0 ) \ - CUR.error = TT_Err_Divide_By_Zero; \ - else \ - args[0] = TT_MULDIV( args[0], 64L, args[1] ); +#define DO_DIV \ + if ( args[1] == 0 ) \ + CUR.error = TT_Err_Divide_By_Zero; \ + else \ + args[0] = TT_MULDIV_NO_ROUND( args[0], 64L, args[1] ); #define DO_MUL \ args[0] = TT_MULDIV( args[0], args[1], 64L ); -#define DO_ABS \ - args[0] = ABS( args[0] ); +#define DO_ABS \ + args[0] = FT_ABS( args[0] ); #define DO_NEG \ @@ -2843,11 +2994,11 @@ #define DO_FLOOR \ - args[0] &= -64; + args[0] = FT_PIX_FLOOR( args[0] ); #define DO_CEILING \ - args[0] = ( args[0] + 63 ) & -64; + args[0] = FT_PIX_CEIL( args[0] ); #define DO_RS \ @@ -3955,9 +4106,9 @@ K = CUR.stack[CUR.args - L]; - FT_MEM_MOVE( &CUR.stack[CUR.args - L ], - &CUR.stack[CUR.args - L + 1], - ( L - 1 ) * sizeof ( FT_Long ) ); + FT_ARRAY_MOVE( &CUR.stack[CUR.args - L ], + &CUR.stack[CUR.args - L + 1], + ( L - 1 ) ); CUR.stack[CUR.args - 1] = K; } @@ -4750,6 +4901,8 @@ NORMalize( A, B, &CUR.GS.projVector ); + GUESS_VECTOR( freeVector ); + COMPUTE_Funcs(); } @@ -5123,21 +5276,30 @@ d = CUR_Func_project( zp.cur + p, zp.org + p ); -#ifdef NO_APPLE_PATENT - - *x = TT_MulFix14( d, CUR.GS.freeVector.x ); - *y = TT_MulFix14( d, CUR.GS.freeVector.y ); - -#else - - *x = TT_MULDIV( d, - (FT_Long)CUR.GS.freeVector.x * 0x10000L, - CUR.F_dot_P ); - *y = TT_MULDIV( d, - (FT_Long)CUR.GS.freeVector.y * 0x10000L, - CUR.F_dot_P ); - -#endif /* NO_APPLE_PATENT */ +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + if ( CUR.face->unpatented_hinting ) + { + if ( CUR.GS.both_x_axis ) + { + *x = d; + *y = 0; + } + else + { + *x = 0; + *y = d; + } + } + else +#endif + { + *x = TT_MULDIV( d, + (FT_Long)CUR.GS.freeVector.x * 0x10000L, + CUR.F_dot_P ); + *y = TT_MULDIV( d, + (FT_Long)CUR.GS.freeVector.y * 0x10000L, + CUR.F_dot_P ); + } return SUCCESS; } @@ -5149,6 +5311,25 @@ FT_F26Dot6 dy, FT_Bool touch ) { +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + if ( CUR.face->unpatented_hinting ) + { + if ( CUR.GS.both_x_axis ) + { + CUR.zp2.cur[point].x += dx; + if ( touch ) + CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X; + } + else + { + CUR.zp2.cur[point].y += dy; + if ( touch ) + CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y; + } + return; + } +#endif + if ( CUR.GS.freeVector.x != 0 ) { CUR.zp2.cur[point].x += dx; @@ -5265,11 +5446,11 @@ last_point = 0; } - /* XXX: UNDOCUMENTED! SHC doesn't touch the points */ + /* XXX: UNDOCUMENTED! SHC does touch the points */ for ( i = first_point; i <= last_point; i++ ) { if ( zp.cur != CUR.zp2.cur || refp != i ) - MOVE_Zp2_Point( i, dx, dy, FALSE ); + MOVE_Zp2_Point( i, dx, dy, TRUE ); } } @@ -5334,8 +5515,26 @@ return; } - dx = TT_MulFix14( args[0], CUR.GS.freeVector.x ); - dy = TT_MulFix14( args[0], CUR.GS.freeVector.y ); +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + if ( CUR.face->unpatented_hinting ) + { + if ( CUR.GS.both_x_axis ) + { + dx = TT_MulFix14( args[0], 0x4000 ); + dy = 0; + } + else + { + dx = 0; + dy = TT_MulFix14( args[0], 0x4000 ); + } + } + else +#endif + { + dx = TT_MulFix14( args[0], CUR.GS.freeVector.x ); + dy = TT_MulFix14( args[0], CUR.GS.freeVector.y ); + } while ( CUR.GS.loop > 0 ) { @@ -5386,9 +5585,11 @@ } /* XXX: UNDOCUMENTED! behaviour */ - if ( CUR.GS.gep0 == 0 ) /* if in twilight zone */ + if ( CUR.GS.gep1 == 0 ) /* if the point that is to be moved */ + /* is in twilight zone */ { CUR.zp1.org[point] = CUR.zp0.org[CUR.GS.rp0]; + CUR_Func_move_orig( &CUR.zp1, point, args[1] ); CUR.zp1.cur[point] = CUR.zp1.org[point]; } @@ -5507,7 +5708,7 @@ if ( ( CUR.opcode & 1 ) != 0 ) /* rounding and control cutin flag */ { - if ( ABS( distance - org_dist ) > CUR.GS.control_value_cutin ) + if ( FT_ABS( distance - org_dist ) > CUR.GS.control_value_cutin ) distance = org_dist; distance = CUR_Func_round( distance, CUR.tt_metrics.compensations[0] ); @@ -5551,7 +5752,8 @@ /* single width cutin test */ - if ( ABS( org_dist ) < CUR.GS.single_width_cutin ) + if ( FT_ABS( org_dist - CUR.GS.single_width_value ) < + CUR.GS.single_width_cutin ) { if ( org_dist >= 0 ) org_dist = CUR.GS.single_width_value; @@ -5640,7 +5842,8 @@ /* single width test */ - if ( ABS( cvt_dist ) < CUR.GS.single_width_cutin ) + if ( FT_ABS( cvt_dist - CUR.GS.single_width_value ) < + CUR.GS.single_width_cutin ) { if ( cvt_dist >= 0 ) cvt_dist = CUR.GS.single_width_value; @@ -5683,7 +5886,7 @@ /* refer to the same zone. */ if ( CUR.GS.gep0 == CUR.GS.gep1 ) - if ( ABS( cvt_dist - org_dist ) >= CUR.GS.control_value_cutin ) + if ( FT_ABS( cvt_dist - org_dist ) >= CUR.GS.control_value_cutin ) cvt_dist = org_dist; distance = CUR_Func_round( @@ -5833,7 +6036,7 @@ discriminant = TT_MULDIV( dax, -dby, 0x40 ) + TT_MULDIV( day, dbx, 0x40 ); - if ( ABS( discriminant ) >= 0x40 ) + if ( FT_ABS( discriminant ) >= 0x40 ) { val = TT_MULDIV( dx, -dby, 0x40 ) + TT_MULDIV( dy, dbx, 0x40 ); @@ -6231,6 +6434,22 @@ FT_ULong C; FT_Long B; +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + /* Delta hinting is covered by US Patent 5159668. */ + if ( CUR.face->unpatented_hinting ) + { + FT_Long n = args[0] * 2; + if ( CUR.args < n ) + { + CUR.error = TT_Err_Too_Few_Arguments; + return; + } + + CUR.args -= n; + CUR.new_top = CUR.args; + return; + } +#endif nump = (FT_ULong)args[0]; /* some points theoretically may occur more than once, thus UShort isn't enough */ @@ -6307,6 +6526,25 @@ FT_Long B; +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + /* Delta hinting is covered by US Patent 5159668. */ + if ( CUR.face->unpatented_hinting ) + { + FT_Long n = args[0] * 2; + + + if ( CUR.args < n ) + { + CUR.error = TT_Err_Too_Few_Arguments; + return; + } + + CUR.args -= n; + CUR.new_top = CUR.args; + return; + } +#endif + nump = (FT_ULong)args[0]; for ( k = 1; k <= nump; k++ ) @@ -6870,12 +7108,20 @@ CUR.GS.dualVector.x = AA; CUR.GS.dualVector.y = BB; } + else + { + GUESS_VECTOR( projVector ); + } if ( ( opcode & 2 ) == 0 ) { CUR.GS.freeVector.x = AA; CUR.GS.freeVector.y = BB; } + else + { + GUESS_VECTOR( freeVector ); + } COMPUTE_Funcs(); } @@ -7493,4 +7739,4 @@ #endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/truetype/ttinterp.h b/src/libs/freetype2/truetype/ttinterp.h index 4cce641e9f..eb0bb0bb60 100644 --- a/src/libs/freetype2/truetype/ttinterp.h +++ b/src/libs/freetype2/truetype/ttinterp.h @@ -4,7 +4,7 @@ /* */ /* TrueType bytecode interpreter (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -210,6 +210,7 @@ FT_BEGIN_HEADER func_freeProj; /* current freedom proj. func */ TT_Move_Func func_move; /* current point move function */ + TT_Move_Func func_move_orig; /* move original position function */ TT_Get_CVT_Func func_read_cvt; /* read a cvt entry */ TT_Set_CVT_Func func_write_cvt; /* write a cvt entry (in pixels) */ @@ -314,4 +315,4 @@ FT_END_HEADER #endif /* __TTINTERP_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/truetype/ttobjs.c b/src/libs/freetype2/truetype/ttobjs.c index 5a24deda98..d5210f2cd0 100644 --- a/src/libs/freetype2/truetype/ttobjs.c +++ b/src/libs/freetype2/truetype/ttobjs.c @@ -4,7 +4,7 @@ /* */ /* Objects manager (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,7 +23,6 @@ #include FT_TRUETYPE_IDS_H #include FT_TRUETYPE_TAGS_H #include FT_INTERNAL_SFNT_H -#include FT_INTERNAL_POSTSCRIPT_NAMES_H #include "ttgload.h" #include "ttpload.h" @@ -34,6 +33,9 @@ #include "ttinterp.h" #endif +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING +#include FT_TRUETYPE_UNPATENTED_H +#endif /*************************************************************************/ /* */ @@ -70,6 +72,7 @@ { FT_Memory memory = zone->memory; + if ( memory ) { FT_FREE( zone->contours ); @@ -200,26 +203,43 @@ goto Exit; if ( face->root.face_flags & FT_FACE_FLAG_SCALABLE ) - { + { #ifdef FT_CONFIG_OPTION_INCREMENTAL - if ( !face->root.internal->incremental_interface ) - error = tt_face_load_loca( face, stream ); - if ( !error ) - error = tt_face_load_cvt ( face, stream ) || - tt_face_load_fpgm ( face, stream ); + if ( !face->root.internal->incremental_interface ) + error = tt_face_load_loca( face, stream ); + if ( !error ) + error = tt_face_load_cvt( face, stream ) || + tt_face_load_fpgm( face, stream ); #else - if ( !error ) - error = tt_face_load_loca( face, stream ) || - tt_face_load_cvt ( face, stream ) || - tt_face_load_fpgm ( face, stream ); + if ( !error ) + error = tt_face_load_loca( face, stream ) || + tt_face_load_cvt( face, stream ) || + tt_face_load_fpgm( face, stream ); #endif - } + } + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + + /* Determine whether unpatented hinting is to be used for this face. */ + face->unpatented_hinting = FT_BOOL + ( library->debug_hooks[ FT_DEBUG_HOOK_UNPATENTED_HINTING ] != NULL ); + + { + int i; + + + for ( i = 0; i < num_params && !face->unpatented_hinting; i++ ) + if ( params[i].tag == FT_PARAM_TAG_UNPATENTED_HINTING ) + face->unpatented_hinting = TRUE; + } + +#endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING */ /* initialize standard glyph loading routines */ TT_Init_Glyph_Loading( face ); @@ -569,15 +589,16 @@ size->ttmetrics.y_ratio = 0x10000L; } - /* Compute root ascender, descender, test height, and max_advance */ - metrics->ascender = ( FT_MulFix( face->root.ascender, - metrics->y_scale ) + 32 ) & -64; - metrics->descender = ( FT_MulFix( face->root.descender, - metrics->y_scale ) + 32 ) & -64; - metrics->height = ( FT_MulFix( face->root.height, - metrics->y_scale ) + 32 ) & -64; - metrics->max_advance = ( FT_MulFix( face->root.max_advance_width, - metrics->x_scale ) + 32 ) & -64; + /* Compute root ascender, descender, text height, and max_advance */ + metrics->ascender = + FT_PIX_ROUND( FT_MulFix( face->root.ascender, metrics->y_scale ) ); + metrics->descender = + FT_PIX_ROUND( FT_MulFix( face->root.descender, metrics->y_scale ) ); + metrics->height = + FT_PIX_ROUND( FT_MulFix( face->root.height, metrics->y_scale ) ); + metrics->max_advance = + FT_PIX_ROUND( FT_MulFix( face->root.max_advance_width, + metrics->x_scale ) ); #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS @@ -704,39 +725,39 @@ sbit_metrics = &size->strike_metrics; - error = sfnt->set_sbit_strike(face, - metrics->x_ppem, metrics->y_ppem, - &strike_index); + error = sfnt->set_sbit_strike( face, + metrics->x_ppem, metrics->y_ppem, + &strike_index ); if ( !error ) { TT_SBit_Strike strike = face->sbit_strikes + strike_index; - sbit_metrics->x_ppem = metrics->x_ppem; - sbit_metrics->y_ppem = metrics->y_ppem; + sbit_metrics->x_ppem = metrics->x_ppem; + sbit_metrics->y_ppem = metrics->y_ppem; #if 0 /* * sbit_metrics->?_scale * are not used now. */ - sbit_metrics->x_scale = 1 << 16; - sbit_metrics->y_scale = 1 << 16; + sbit_metrics->x_scale = 1 << 16; + sbit_metrics->y_scale = 1 << 16; #endif - sbit_metrics->ascender = strike->hori.ascender << 6; - sbit_metrics->descender = strike->hori.descender << 6; + sbit_metrics->ascender = strike->hori.ascender << 6; + sbit_metrics->descender = strike->hori.descender << 6; /* XXX: Is this correct? */ - sbit_metrics->height = sbit_metrics->ascender - - sbit_metrics->descender; + sbit_metrics->height = sbit_metrics->ascender - + sbit_metrics->descender; /* XXX: Is this correct? */ sbit_metrics->max_advance = ( strike->hori.min_origin_SB + strike->hori.max_width + strike->hori.min_advance_SB ) << 6; - size->strike_index = strike_index; + size->strike_index = (FT_UInt)strike_index; } else { @@ -862,4 +883,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/truetype/ttobjs.h b/src/libs/freetype2/truetype/ttobjs.h index d0ede02051..30cf1cb369 100644 --- a/src/libs/freetype2/truetype/ttobjs.h +++ b/src/libs/freetype2/truetype/ttobjs.h @@ -4,7 +4,7 @@ /* */ /* Objects manager (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -83,6 +83,10 @@ FT_BEGIN_HEADER FT_UnitVector projVector; FT_UnitVector freeVector; +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + FT_Bool both_x_axis; +#endif + FT_Long loop; FT_F26Dot6 minimum_distance; FT_Int round_state; @@ -212,7 +216,8 @@ FT_BEGIN_HEADER TT_Transform transform; /* transformation matrix */ - FT_Vector pp1, pp2; /* phantom points */ + FT_Vector pp1, pp2; /* phantom points (horizontal) */ + FT_Vector pp3, pp4; /* phantom points (vertical) */ } TT_SubGlyphRec, *TT_SubGlyph_Stack; @@ -311,7 +316,7 @@ FT_BEGIN_HEADER { FT_SizeRec root; - FT_Size_Metrics metrics; /* slightly different from the root metrics */ + FT_Size_Metrics metrics; /* slightly different from the root metrics */ TT_Size_Metrics ttmetrics; #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS @@ -420,4 +425,4 @@ FT_END_HEADER #endif /* __TTOBJS_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/truetype/ttpload.c b/src/libs/freetype2/truetype/ttpload.c index c6e65d768b..4066cd7c28 100644 --- a/src/libs/freetype2/truetype/ttpload.c +++ b/src/libs/freetype2/truetype/ttpload.c @@ -261,4 +261,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/truetype/ttpload.h b/src/libs/freetype2/truetype/ttpload.h index a8941736a4..3f8cd64ff7 100644 --- a/src/libs/freetype2/truetype/ttpload.h +++ b/src/libs/freetype2/truetype/ttpload.h @@ -45,4 +45,4 @@ FT_END_HEADER #endif /* __TTPLOAD_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/type1/descrip.mms b/src/libs/freetype2/type1/descrip.mms deleted file mode 100644 index 75a9c14689..0000000000 --- a/src/libs/freetype2/type1/descrip.mms +++ /dev/null @@ -1,23 +0,0 @@ -# -# FreeType 2 Type1 driver compilation rules for VMS -# - - -# Copyright 1996-2000, 2002 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. - - -CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.type1]) - -OBJS=type1.obj - -all : $(OBJS) - library [--.lib]freetype.olb $(OBJS) - -# EOF diff --git a/src/libs/freetype2/type1/module.mk b/src/libs/freetype2/type1/module.mk index 277bd7259c..82d9355ba3 100644 --- a/src/libs/freetype2/type1/module.mk +++ b/src/libs/freetype2/type1/module.mk @@ -19,4 +19,4 @@ add_type1_driver: $(OPEN_DRIVER)t1_driver_class$(CLOSE_DRIVER) $(ECHO_DRIVER)type1 $(ECHO_DRIVER_DESC)Postscript font files with extension *.pfa or *.pfb$(ECHO_DRIVER_DONE) -# EOF +# EOF diff --git a/src/libs/freetype2/type1/rules.mk b/src/libs/freetype2/type1/rules.mk index ba2f7c3d1d..15087b0304 100644 --- a/src/libs/freetype2/type1/rules.mk +++ b/src/libs/freetype2/type1/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2001 by +# Copyright 1996-2000, 2001, 2003 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -15,29 +15,28 @@ # Type1 driver directory # -T1_DIR := $(SRC_)type1 -T1_DIR_ := $(T1_DIR)$(SEP) +T1_DIR := $(SRC_DIR)/type1 # compilation flags for the driver # -T1_COMPILE := $(FT_COMPILE) $I$(T1_DIR) +T1_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(T1_DIR)) # Type1 driver sources (i.e., C files) # -T1_DRV_SRC := $(T1_DIR_)t1parse.c \ - $(T1_DIR_)t1load.c \ - $(T1_DIR_)t1driver.c \ - $(T1_DIR_)t1afm.c \ - $(T1_DIR_)t1gload.c \ - $(T1_DIR_)t1objs.c +T1_DRV_SRC := $(T1_DIR)/t1parse.c \ + $(T1_DIR)/t1load.c \ + $(T1_DIR)/t1driver.c \ + $(T1_DIR)/t1afm.c \ + $(T1_DIR)/t1gload.c \ + $(T1_DIR)/t1objs.c # Type1 driver headers # T1_DRV_H := $(T1_DRV_SRC:%.c=%.h) \ - $(T1_DIR_)t1tokens.h \ - $(T1_DIR_)t1errors.h + $(T1_DIR)/t1tokens.h \ + $(T1_DIR)/t1errors.h # Type1 driver object(s) @@ -45,24 +44,24 @@ T1_DRV_H := $(T1_DRV_SRC:%.c=%.h) \ # T1_DRV_OBJ_M is used during `multi' builds # T1_DRV_OBJ_S is used during `single' builds # -T1_DRV_OBJ_M := $(T1_DRV_SRC:$(T1_DIR_)%.c=$(OBJ_)%.$O) -T1_DRV_OBJ_S := $(OBJ_)type1.$O +T1_DRV_OBJ_M := $(T1_DRV_SRC:$(T1_DIR)/%.c=$(OBJ_DIR)/%.$O) +T1_DRV_OBJ_S := $(OBJ_DIR)/type1.$O # Type1 driver source file for single build # -T1_DRV_SRC_S := $(T1_DIR_)type1.c +T1_DRV_SRC_S := $(T1_DIR)/type1.c # Type1 driver - single object # $(T1_DRV_OBJ_S): $(T1_DRV_SRC_S) $(T1_DRV_SRC) $(FREETYPE_H) $(T1_DRV_H) - $(T1_COMPILE) $T$@ $(T1_DRV_SRC_S) + $(T1_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(T1_DRV_SRC_S)) # Type1 driver - multiple objects # -$(OBJ_)%.$O: $(T1_DIR_)%.c $(FREETYPE_H) $(T1_DRV_H) - $(T1_COMPILE) $T$@ $< +$(OBJ_DIR)/%.$O: $(T1_DIR)/%.c $(FREETYPE_H) $(T1_DRV_H) + $(T1_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) # update main driver object lists @@ -70,4 +69,5 @@ $(OBJ_)%.$O: $(T1_DIR_)%.c $(FREETYPE_H) $(T1_DRV_H) DRV_OBJS_S += $(T1_DRV_OBJ_S) DRV_OBJS_M += $(T1_DRV_OBJ_M) -# EOF + +# EOF diff --git a/src/libs/freetype2/type1/t1afm.c b/src/libs/freetype2/type1/t1afm.c index adfb084037..9945ebdf6d 100644 --- a/src/libs/freetype2/type1/t1afm.c +++ b/src/libs/freetype2/type1/t1afm.c @@ -4,7 +4,7 @@ /* */ /* AFM support for Type 1 fonts (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -148,7 +148,7 @@ FT_ULong index2 = KERN_INDEX( pair2->glyph1, pair2->glyph2 ); - return ( index1 - index2 ); + return (int)( index1 - index2 ); } @@ -279,4 +279,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/type1/t1afm.h b/src/libs/freetype2/type1/t1afm.h index 2e46efea45..77cc6a6e95 100644 --- a/src/libs/freetype2/type1/t1afm.h +++ b/src/libs/freetype2/type1/t1afm.h @@ -63,4 +63,4 @@ FT_END_HEADER #endif /* __T1AFM_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/type1/t1driver.c b/src/libs/freetype2/type1/t1driver.c index 682b4fa3ec..fd201db8e3 100644 --- a/src/libs/freetype2/type1/t1driver.c +++ b/src/libs/freetype2/type1/t1driver.c @@ -4,7 +4,7 @@ /* */ /* Type 1 driver interface (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -29,8 +29,13 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_POSTSCRIPT_NAMES_H +#include FT_SERVICE_MULTIPLE_MASTERS_H +#include FT_SERVICE_GLYPH_DICT_H +#include FT_SERVICE_XFREE86_NAME_H +#include FT_SERVICE_POSTSCRIPT_NAME_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H +#include FT_SERVICE_POSTSCRIPT_INFO_H /*************************************************************************/ /* */ @@ -41,6 +46,10 @@ #undef FT_COMPONENT #define FT_COMPONENT trace_t1driver + /* + * GLYPH DICT SERVICE + * + */ static FT_Error t1_get_glyph_name( T1_Face face, @@ -69,23 +78,6 @@ } - /*************************************************************************/ - /* */ - /* */ - /* t1_get_name_index */ - /* */ - /* */ - /* Uses the Type 1 font's `glyph_names' table to find a given glyph */ - /* name's glyph index. */ - /* */ - /* */ - /* face :: A handle to the source face object. */ - /* */ - /* glyph_name :: The glyph name. */ - /* */ - /* */ - /* Glyph index. 0 means `undefined character code'. */ - /* */ static FT_UInt t1_get_name_index( T1_Face face, FT_String* glyph_name ) @@ -105,6 +97,17 @@ return 0; } + static const FT_Service_GlyphDictRec t1_service_glyph_dict = + { + (FT_GlyphDict_GetNameFunc) t1_get_glyph_name, + (FT_GlyphDict_NameIndexFunc)t1_get_name_index + }; + + + /* + * POSTSCRIPT NAME SERVICE + * + */ static const char* t1_get_ps_name( T1_Face face ) @@ -112,61 +115,82 @@ return (const char*) face->type1.font_name; } + static const FT_Service_PsFontNameRec t1_service_ps_name = + { + (FT_PsName_GetFunc)t1_get_ps_name + }; + + + /* + * MULTIPLE MASTERS SERVICE + * + */ + +#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT + static const FT_Service_MultiMastersRec t1_service_multi_masters = + { + (FT_Get_MM_Func) T1_Get_Multi_Master, + (FT_Set_MM_Design_Func)T1_Set_MM_Design, + (FT_Set_MM_Blend_Func) T1_Set_MM_Blend + }; +#endif + + + /* + * POSTSCRIPT INFO SERVICE + * + */ + + static FT_Error + t1_ps_get_font_info( FT_Face face, + PS_FontInfoRec* afont_info ) + { + *afont_info = ((T1_Face)face)->type1.font_info; + return 0; + } + + + static FT_Int + t1_ps_has_glyph_names( FT_Face face ) + { + FT_UNUSED( face ); + return 1; + } + + + static const FT_Service_PsInfoRec t1_service_ps_info = + { + (PS_GetFontInfoFunc) t1_ps_get_font_info, + (PS_HasGlyphNamesFunc)t1_ps_has_glyph_names + }; + + + /* + * SERVICE LIST + * + */ + + static const FT_ServiceDescRec t1_services[] = + { + { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &t1_service_ps_name }, + { FT_SERVICE_ID_GLYPH_DICT, &t1_service_glyph_dict }, + { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TYPE_1 }, + { FT_SERVICE_ID_POSTSCRIPT_INFO, &t1_service_ps_info }, + +#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT + { FT_SERVICE_ID_MULTI_MASTERS, &t1_service_multi_masters }, +#endif + { NULL, NULL } + }; + - /*************************************************************************/ - /* */ - /* */ - /* Get_Interface */ - /* */ - /* */ - /* Each driver can provide one or more extensions to the base */ - /* FreeType API. These can be used to access format specific */ - /* features (e.g., all TrueType/OpenType resources share a common */ - /* file structure and common tables which can be accessed through the */ - /* `sfnt' interface), or more simply generic ones (e.g., the */ - /* `postscript names' interface which can be used to retrieve the */ - /* PostScript name of a given glyph index). */ - /* */ - /* */ - /* driver :: A handle to a driver object. */ - /* */ - /* */ - /* t1_interface :: A string designing the interface. Examples are */ - /* `sfnt', `post_names', `charmaps', etc. */ - /* */ - /* */ - /* A typeless pointer to the extension's interface (normally a table */ - /* of function pointers). Returns NULL if the requested extension */ - /* isn't available (i.e., wasn't compiled in the driver at build */ - /* time). */ - /* */ static FT_Module_Interface Get_Interface( FT_Driver driver, const FT_String* t1_interface ) { FT_UNUSED( driver ); - FT_UNUSED( t1_interface ); - if ( ft_strcmp( (const char*)t1_interface, "glyph_name" ) == 0 ) - return (FT_Module_Interface)t1_get_glyph_name; - - if ( ft_strcmp( (const char*)t1_interface, "name_index" ) == 0 ) - return (FT_Module_Interface)t1_get_name_index; - - if ( ft_strcmp( (const char*)t1_interface, "postscript_name" ) == 0 ) - return (FT_Module_Interface)t1_get_ps_name; - -#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT - if ( ft_strcmp( (const char*)t1_interface, "get_mm" ) == 0 ) - return (FT_Module_Interface)T1_Get_Multi_Master; - - if ( ft_strcmp( (const char*)t1_interface, "set_mm_design") == 0 ) - return (FT_Module_Interface)T1_Set_MM_Design; - - if ( ft_strcmp( (const char*)t1_interface, "set_mm_blend") == 0 ) - return (FT_Module_Interface)T1_Set_MM_Blend; -#endif - return 0; + return ft_service_list_lookup( t1_services, t1_interface ); } @@ -227,15 +251,13 @@ #endif /* T1_CONFIG_OPTION_NO_AFM */ - - FT_CALLBACK_TABLE_DEF const FT_Driver_ClassRec t1_driver_class = { { - ft_module_font_driver | - ft_module_driver_scalable | - ft_module_driver_has_hinter, + FT_MODULE_FONT_DRIVER | + FT_MODULE_DRIVER_SCALABLE | + FT_MODULE_DRIVER_HAS_HINTER, sizeof( FT_DriverRec ), @@ -276,4 +298,4 @@ }; -/* END */ +/* END */ diff --git a/src/libs/freetype2/type1/t1driver.h b/src/libs/freetype2/type1/t1driver.h index 9ede430483..ad429440de 100644 --- a/src/libs/freetype2/type1/t1driver.h +++ b/src/libs/freetype2/type1/t1driver.h @@ -35,4 +35,4 @@ FT_END_HEADER #endif /* __T1DRIVER_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/type1/t1errors.h b/src/libs/freetype2/type1/t1errors.h index 05fe9bf4a9..81221c343d 100644 --- a/src/libs/freetype2/type1/t1errors.h +++ b/src/libs/freetype2/type1/t1errors.h @@ -37,4 +37,4 @@ #endif /* __T1ERRORS_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/type1/t1gload.c b/src/libs/freetype2/type1/t1gload.c index 2f95163434..98f8194b97 100644 --- a/src/libs/freetype2/type1/t1gload.c +++ b/src/libs/freetype2/type1/t1gload.c @@ -4,7 +4,7 @@ /* */ /* Type 1 Glyph Loader (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -81,7 +81,7 @@ /* For ordinary fonts get the character data stored in the face record. */ { char_string->pointer = type1->charstrings[glyph_index]; - char_string->length = type1->charstrings_len[glyph_index]; + char_string->length = (FT_Int)type1->charstrings_len[glyph_index]; } if ( !error ) @@ -97,9 +97,10 @@ { FT_Incremental_MetricsRec metrics; + metrics.bearing_x = decoder->builder.left_bearing.x; - metrics.bearing_y = decoder->builder.left_bearing.y; - metrics.advance = decoder->builder.advance.x; + metrics.bearing_y = decoder->builder.left_bearing.y; + metrics.advance = decoder->builder.advance.x; error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( face->root.internal->incremental_interface->object, glyph_index, FALSE, &metrics ); @@ -111,7 +112,7 @@ #endif /* FT_CONFIG_OPTION_INCREMENTAL */ - return error; + return error; } @@ -120,21 +121,23 @@ FT_UInt glyph_index ) { FT_Data glyph_data; - FT_Error error = T1_Parse_Glyph_And_Get_Char_String( + FT_Error error = T1_Parse_Glyph_And_Get_Char_String( decoder, glyph_index, &glyph_data ); #ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( !error ) { T1_Face face = (T1_Face)decoder->builder.face; - if ( face->root.internal->incremental_interface ) + if ( face->root.internal->incremental_interface ) face->root.internal->incremental_interface->funcs->free_glyph_data( face->root.internal->incremental_interface->object, &glyph_data ); } + #endif /* FT_CONFIG_OPTION_INCREMENTAL */ return error; @@ -143,7 +146,7 @@ FT_LOCAL_DEF( FT_Error ) T1_Compute_Max_Advance( T1_Face face, - FT_Int* max_advance ) + FT_Pos* max_advance ) { FT_Error error; T1_DecoderRec decoder; @@ -184,8 +187,8 @@ error = T1_Parse_Glyph( &decoder, glyph_index ); if ( glyph_index == 0 || decoder.builder.advance.x > *max_advance ) *max_advance = decoder.builder.advance.x; - - /* ignore the error if one occured - skip to next glyph */ + + /* ignore the error if one occurred - skip to next glyph */ } return T1_Err_Ok; @@ -226,7 +229,9 @@ FT_Matrix font_matrix; FT_Vector font_offset; FT_Data glyph_data; +#ifdef FT_CONFIG_OPTION_INCREMENTAL FT_Bool glyph_data_loaded = 0; +#endif if ( load_flags & FT_LOAD_NO_RECURSE ) @@ -250,7 +255,7 @@ (FT_Byte**)type1->glyph_names, face->blend, FT_BOOL( hinting ), - FT_LOAD_TARGET_MODE(load_flags), + FT_LOAD_TARGET_MODE( load_flags ), T1_Parse_Glyph ); if ( error ) goto Exit; @@ -267,7 +272,9 @@ &glyph_data ); if ( error ) goto Exit; +#ifdef FT_CONFIG_OPTION_INCREMENTAL glyph_data_loaded = 1; +#endif font_matrix = decoder.font_matrix; font_offset = decoder.font_offset; @@ -300,6 +307,7 @@ { FT_BBox cbox; FT_Glyph_Metrics* metrics = &glyph->root.metrics; + FT_Vector advance; /* copy the _unscaled_ advance width */ @@ -326,6 +334,15 @@ FT_Outline_Translate( &glyph->root.outline, font_offset.x, font_offset.y ); + + advance.x = metrics->horiAdvance; + advance.y = 0; + FT_Vector_Transform( &advance, &font_matrix ); + metrics->horiAdvance = advance.x + font_offset.x; + advance.x = 0; + advance.y = metrics->vertAdvance; + FT_Vector_Transform( &advance, &font_matrix ); + metrics->vertAdvance = advance.y + font_offset.y; #endif if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) @@ -357,11 +374,11 @@ if ( hinting ) { - metrics->horiAdvance = ( metrics->horiAdvance + 32 ) & -64; - metrics->vertAdvance = ( metrics->vertAdvance + 32 ) & -64; + metrics->horiAdvance = FT_PIX_ROUND( metrics->horiAdvance ); + metrics->vertAdvance = FT_PIX_ROUND( metrics->vertAdvance ); - metrics->vertBearingX = ( metrics->vertBearingX + 32 ) & -64; - metrics->vertBearingY = ( metrics->vertBearingY + 32 ) & -64; + metrics->vertBearingX = FT_PIX_ROUND( metrics->vertBearingX ); + metrics->vertBearingY = FT_PIX_ROUND( metrics->vertBearingY ); } } @@ -371,10 +388,10 @@ /* grid fit the bounding box if necessary */ if ( hinting ) { - cbox.xMin &= -64; - cbox.yMin &= -64; - cbox.xMax = ( cbox.xMax+63 ) & -64; - cbox.yMax = ( cbox.yMax+63 ) & -64; + cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); + cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); + cbox.xMax = FT_PIX_CEIL( cbox.xMax ); + cbox.yMax = FT_PIX_CEIL( cbox.yMax ); } metrics->width = cbox.xMax - cbox.xMin; @@ -411,4 +428,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/type1/t1gload.h b/src/libs/freetype2/type1/t1gload.h index ccce3c0824..de87896dc0 100644 --- a/src/libs/freetype2/type1/t1gload.h +++ b/src/libs/freetype2/type1/t1gload.h @@ -4,7 +4,7 @@ /* */ /* Type 1 Glyph Loader (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -29,7 +29,7 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) T1_Compute_Max_Advance( T1_Face face, - FT_Int* max_advance ); + FT_Pos* max_advance ); FT_LOCAL( FT_Error ) T1_Load_Glyph( T1_GlyphSlot glyph, @@ -43,4 +43,4 @@ FT_END_HEADER #endif /* __T1GLOAD_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/type1/t1load.c b/src/libs/freetype2/type1/t1load.c index 3d6e139318..16a0341554 100644 --- a/src/libs/freetype2/type1/t1load.c +++ b/src/libs/freetype2/type1/t1load.c @@ -4,7 +4,7 @@ /* */ /* Type 1 font loader (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -41,11 +41,10 @@ /* */ /* All other common cases are handled very simply. The matching rules */ /* are defined in the file `t1tokens.h' through the use of several */ - /* macros calls PARSE_XXX. */ - /* */ - /* This file is included twice here; the first time to generate parsing */ - /* callback functions, the second to generate a table of keywords (with */ - /* pointers to the associated callback). */ + /* macros calls PARSE_XXX. This file is included twice here; the first */ + /* time to generate parsing callback functions, the second time to */ + /* generate a table of keywords (with pointers to the associated */ + /* callback functions). */ /* */ /* The function `parse_dict' simply scans *linearly* a given dictionary */ /* (either the top-level or private one) and calls the appropriate */ @@ -71,7 +70,6 @@ #include "t1errors.h" - /*************************************************************************/ /* */ /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ @@ -100,7 +98,7 @@ { PS_Blend blend; FT_Memory memory = face->root.memory; - FT_Error error = 0; + FT_Error error = T1_Err_Ok; blend = face->blend; @@ -174,7 +172,7 @@ return error; Fail: - error = -1; + error = T1_Err_Invalid_File_Format; goto Exit; } @@ -205,8 +203,10 @@ axis->minimum = map->design_points[0]; axis->maximum = map->design_points[map->num_points - 1]; } - error = 0; + + error = T1_Err_Ok; } + return error; } @@ -253,6 +253,7 @@ error = T1_Err_Ok; } + return error; } @@ -289,7 +290,7 @@ FT_Fixed p_design = designs[p]; - /* exact match ? */ + /* exact match? */ if ( design == p_design ) { the_blend = blends[p]; @@ -305,7 +306,7 @@ before = p; } - /* now, interpolate if needed */ + /* now interpolate if necessary */ if ( before < 0 ) the_blend = blends[0]; @@ -386,9 +387,9 @@ parse_blend_axis_types( T1_Face face, T1_Loader loader ) { - T1_TokenRec axis_tokens[ T1_MAX_MM_AXIS ]; + T1_TokenRec axis_tokens[T1_MAX_MM_AXIS]; FT_Int n, num_axis; - FT_Error error = 0; + FT_Error error = T1_Err_Ok; PS_Blend blend; FT_Memory memory; @@ -396,7 +397,12 @@ /* take an array of objects */ T1_ToTokenArray( &loader->parser, axis_tokens, T1_MAX_MM_AXIS, &num_axis ); - if ( num_axis <= 0 || num_axis > T1_MAX_MM_AXIS ) + if ( num_axis < 0 ) + { + error = T1_Err_Ignore; + goto Exit; + } + if ( num_axis == 0 || num_axis > T1_MAX_MM_AXIS ) { FT_ERROR(( "parse_blend_axis_types: incorrect number of axes: %d\n", num_axis )); @@ -425,7 +431,7 @@ token->start++; len = token->limit - token->start; - if ( len <= 0 ) + if ( len == 0 ) { error = T1_Err_Invalid_File_Format; goto Exit; @@ -448,18 +454,24 @@ parse_blend_design_positions( T1_Face face, T1_Loader loader ) { - T1_TokenRec design_tokens[ T1_MAX_MM_DESIGNS ]; + T1_TokenRec design_tokens[T1_MAX_MM_DESIGNS]; FT_Int num_designs; FT_Int num_axis; T1_Parser parser = &loader->parser; - FT_Error error = 0; + FT_Error error = T1_Err_Ok; PS_Blend blend; - /* get the array of design tokens - compute number of designs */ - T1_ToTokenArray( parser, design_tokens, T1_MAX_MM_DESIGNS, &num_designs ); - if ( num_designs <= 0 || num_designs > T1_MAX_MM_DESIGNS ) + /* get the array of design tokens -- compute number of designs */ + T1_ToTokenArray( parser, design_tokens, + T1_MAX_MM_DESIGNS, &num_designs ); + if ( num_designs < 0 ) + { + error = T1_Err_Ignore; + goto Exit; + } + if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS ) { FT_ERROR(( "parse_blend_design_positions:" )); FT_ERROR(( " incorrect number of designs: %d\n", @@ -471,23 +483,23 @@ { FT_Byte* old_cursor = parser->root.cursor; FT_Byte* old_limit = parser->root.limit; - FT_UInt n; + FT_Int n; blend = face->blend; num_axis = 0; /* make compiler happy */ - for ( n = 0; n < (FT_UInt)num_designs; n++ ) + for ( n = 0; n < num_designs; n++ ) { - T1_TokenRec axis_tokens[ T1_MAX_MM_DESIGNS ]; + T1_TokenRec axis_tokens[T1_MAX_MM_DESIGNS]; T1_Token token; FT_Int axis, n_axis; /* read axis/coordinates tokens */ token = design_tokens + n; - parser->root.cursor = token->start - 1; - parser->root.limit = token->limit + 1; + parser->root.cursor = token->start; + parser->root.limit = token->limit; T1_ToTokenArray( parser, axis_tokens, T1_MAX_MM_AXIS, &n_axis ); if ( n == 0 ) @@ -505,7 +517,7 @@ goto Exit; } - /* now, read each axis token into the design position */ + /* now read each axis token into the design position */ for ( axis = 0; axis < n_axis; axis++ ) { T1_Token token2 = axis_tokens + axis; @@ -530,7 +542,7 @@ parse_blend_design_map( T1_Face face, T1_Loader loader ) { - FT_Error error = 0; + FT_Error error = T1_Err_Ok; T1_Parser parser = &loader->parser; PS_Blend blend; T1_TokenRec axis_tokens[T1_MAX_MM_AXIS]; @@ -540,14 +552,21 @@ FT_Memory memory = face->root.memory; - T1_ToTokenArray( parser, axis_tokens, T1_MAX_MM_AXIS, &num_axis ); - if ( num_axis <= 0 || num_axis > T1_MAX_MM_AXIS ) + T1_ToTokenArray( parser, axis_tokens, + T1_MAX_MM_AXIS, &num_axis ); + if ( num_axis < 0 ) + { + error = T1_Err_Ignore; + goto Exit; + } + if ( num_axis == 0 || num_axis > T1_MAX_MM_AXIS ) { FT_ERROR(( "parse_blend_design_map: incorrect number of axes: %d\n", num_axis )); error = T1_Err_Invalid_File_Format; goto Exit; } + old_cursor = parser->root.cursor; old_limit = parser->root.limit; @@ -556,29 +575,22 @@ goto Exit; blend = face->blend; - /* now, read each axis design map */ + /* now read each axis design map */ for ( n = 0; n < num_axis; n++ ) { PS_DesignMap map = blend->design_map + n; - T1_Token token; + T1_Token axis_token; + T1_TokenRec point_tokens[T1_MAX_MM_MAP_POINTS]; FT_Int p, num_points; - token = axis_tokens + n; - parser->root.cursor = token->start; - parser->root.limit = token->limit; + axis_token = axis_tokens + n; - /* count the number of map points */ - { - FT_Byte* ptr = token->start; - FT_Byte* limit = token->limit; + parser->root.cursor = axis_token->start; + parser->root.limit = axis_token->limit; + T1_ToTokenArray( parser, point_tokens, + T1_MAX_MM_MAP_POINTS, &num_points ); - - num_points = 0; - for ( ; ptr < limit; ptr++ ) - if ( ptr[0] == '[' ) - num_points++; - } if ( num_points <= 0 || num_points > T1_MAX_MM_MAP_POINTS ) { FT_ERROR(( "parse_blend_design_map: incorrect table\n" )); @@ -594,6 +606,15 @@ for ( p = 0; p < num_points; p++ ) { + T1_Token point_token; + + + point_token = point_tokens + p; + + /* don't include delimiting brackets */ + parser->root.cursor = point_token->start + 1; + parser->root.limit = point_token->limit - 1; + map->design_points[p] = T1_ToInt( parser ); map->blend_points [p] = T1_ToFixed( parser, 0 ); } @@ -611,26 +632,46 @@ parse_weight_vector( T1_Face face, T1_Loader loader ) { - FT_Error error = 0; + T1_TokenRec design_tokens[T1_MAX_MM_DESIGNS]; + FT_Int num_designs; + FT_Error error = T1_Err_Ok; T1_Parser parser = &loader->parser; PS_Blend blend = face->blend; - T1_TokenRec master; - FT_UInt n; + T1_Token token; + FT_Int n; FT_Byte* old_cursor; FT_Byte* old_limit; - if ( !blend || blend->num_designs == 0 ) + T1_ToTokenArray( parser, design_tokens, + T1_MAX_MM_DESIGNS, &num_designs ); + if ( num_designs < 0 ) { - FT_ERROR(( "parse_weight_vector: too early!\n" )); + error = T1_Err_Ignore; + goto Exit; + } + if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS ) + { + FT_ERROR(( "parse_weight_vector:" )); + FT_ERROR(( " incorrect number of designs: %d\n", + num_designs )); error = T1_Err_Invalid_File_Format; goto Exit; } - T1_ToToken( parser, &master ); - if ( master.type != T1_TOKEN_TYPE_ARRAY ) + if ( !blend || !blend->num_designs ) { - FT_ERROR(( "parse_weight_vector: incorrect format!\n" )); + error = t1_allocate_blend( face, num_designs, 0 ); + if ( error ) + goto Exit; + blend = face->blend; + } + else if ( blend->num_designs != (FT_UInt)num_designs ) + { + FT_ERROR(( "parse_weight_vector:" + " /BlendDesignPosition and /WeightVector have\n" )); + FT_ERROR(( " " + " different number of elements!\n" )); error = T1_Err_Invalid_File_Format; goto Exit; } @@ -638,11 +679,12 @@ old_cursor = parser->root.cursor; old_limit = parser->root.limit; - parser->root.cursor = master.start; - parser->root.limit = master.limit; - - for ( n = 0; n < blend->num_designs; n++ ) + for ( n = 0; n < num_designs; n++ ) { + token = design_tokens + n; + parser->root.cursor = token->start; + parser->root.limit = token->limit; + blend->default_weight_vector[n] = blend->weight_vector[n] = T1_ToFixed( parser, 0 ); } @@ -655,26 +697,11 @@ } - /* the keyword `/shareddict' appears in some multiple master fonts */ - /* with a lot of Postscript garbage behind it (that's completely out */ - /* of spec!); we detect it and terminate the parsing */ - /* */ - static void - parse_shared_dict( T1_Face face, - T1_Loader loader ) - { - T1_Parser parser = &loader->parser; - - FT_UNUSED( face ); - - - parser->root.cursor = parser->root.limit; - parser->root.error = 0; - } - #endif /* T1_CONFIG_OPTION_NO_MM_SUPPORT */ + + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -683,19 +710,10 @@ /*************************************************************************/ /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* First of all, define the token field static variables. This is a set */ - /* of T1_FieldRec variables used later. */ - /* */ - /*************************************************************************/ - - static FT_Error - t1_load_keyword( T1_Face face, - T1_Loader loader, - T1_Field field ) + t1_load_keyword( T1_Face face, + T1_Loader loader, + const T1_Field field ) { FT_Error error; void* dummy_object; @@ -774,32 +792,12 @@ static int is_space( FT_Byte c ) { - return ( c == ' ' || c == '\t' || c == '\r' || c == '\n' ); + return ( c == ' ' || c == '\t' || + c == '\r' || c == '\n' || c == '\f' || + c == '\0' ); } - static int - is_name_char( FT_Byte c ) - { - /* Note: PostScript allows any non-delimiting, non-whitespace */ - /* in a name (PS Ref Manual, 3rd Ed, p31) */ - /* PostScript delimiters include (,),<,>,[,],{,},/ and % */ - - return ( c != '(' && - c != ')' && - c != '<' && - c != '>' && - c != '[' && - c != ']' && - c != '{' && - c != '}' && - c != '/' && - c != '%' && - ! is_space( c ) - ); - } - - static int read_binary_data( T1_Parser parser, FT_Long* size, @@ -809,20 +807,21 @@ FT_Byte* limit = parser->root.limit; - /* the binary data has the following format */ - /* */ - /* `size' [white*] RD white ....... ND */ - /* */ + /* the binary data has one of the following formats */ + /* */ + /* `size' [white*] RD white ....... ND */ + /* `size' [white*] -| white ....... |- */ + /* */ T1_Skip_Spaces( parser ); + cur = parser->root.cursor; - if ( cur < limit && (FT_Byte)( *cur - '0' ) < 10 ) + if ( cur < limit && ft_isdigit( *cur ) ) { *size = T1_ToInt( parser ); - T1_Skip_Spaces( parser ); - T1_Skip_Alpha ( parser ); /* `RD' or `-|' or something else */ + T1_Skip_PS_Token( parser ); /* `RD' or `-|' or something else */ /* there is only one whitespace char after the */ /* `RD' or `-|' token */ @@ -838,74 +837,8 @@ } - /* we will now define the routines used to handle */ - /* the `/Encoding', `/Subrs', and `/CharStrings' */ - /* dictionaries */ - - static void - parse_font_name( T1_Face face, - T1_Loader loader ) - { - T1_Parser parser = &loader->parser; - FT_Error error; - FT_Memory memory = parser->root.memory; - FT_PtrDist len; - FT_Byte* cur; - FT_Byte* cur2; - FT_Byte* limit; - - - if ( face->type1.font_name ) - /* with synthetic fonts, it's possible we get here twice */ - return; - - T1_Skip_Spaces( parser ); - - cur = parser->root.cursor; - limit = parser->root.limit; - - if ( cur >= limit - 1 || *cur != '/' ) - return; - - cur++; - cur2 = cur; - while ( cur2 < limit && is_name_char( *cur2 ) ) - cur2++; - - len = cur2 - cur; - if ( len > 0 ) - { - if ( FT_ALLOC( face->type1.font_name, len + 1 ) ) - { - parser->root.error = error; - return; - } - - FT_MEM_COPY( face->type1.font_name, cur, len ); - face->type1.font_name[len] = '\0'; - } - parser->root.cursor = cur2; - } - - -#if 0 - static void - parse_font_bbox( T1_Face face, - T1_Loader loader ) - { - T1_Parser parser = &loader->parser; - FT_Fixed temp[4]; - FT_BBox* bbox = &face->type1.font_bbox; - - - (void)T1_ToFixedArray( parser, 4, temp, 0 ); - bbox->xMin = FT_RoundFix( temp[0] ); - bbox->yMin = FT_RoundFix( temp[1] ); - bbox->xMax = FT_RoundFix( temp[2] ); - bbox->yMax = FT_RoundFix( temp[3] ); - } -#endif - + /* We now define the routines to handle the `/Encoding', `/Subrs', */ + /* and `/CharStrings' dictionaries. */ static void parse_font_matrix( T1_Face face, @@ -919,13 +852,9 @@ FT_Fixed temp_scale; - if ( matrix->xx || matrix->yx ) - /* with synthetic fonts, it's possible we get here twice */ - return; - (void)T1_ToFixedArray( parser, 6, temp, 3 ); - temp_scale = ABS( temp[3] ); + temp_scale = FT_ABS( temp[3] ); /* Set Units per EM based on FontMatrix values. We set the value to */ /* 1000 / temp_scale, because temp_scale was already multiplied by */ @@ -951,8 +880,8 @@ matrix->yy = temp[3]; /* note that the offsets must be expressed in integer font units */ - offset->x = temp[4] >> 16; - offset->y = temp[5] >> 16; + offset->x = temp[4] >> 16; + offset->y = temp[5] >> 16; } @@ -960,49 +889,52 @@ parse_encoding( T1_Face face, T1_Loader loader ) { - T1_Parser parser = &loader->parser; - FT_Byte* cur = parser->root.cursor; - FT_Byte* limit = parser->root.limit; + T1_Parser parser = &loader->parser; + FT_Byte* cur; + FT_Byte* limit = parser->root.limit; - PSAux_Service psaux = (PSAux_Service)face->psaux; + PSAux_Service psaux = (PSAux_Service)face->psaux; - /* skip whitespace */ - while ( is_space( *cur ) ) + T1_Skip_Spaces( parser ); + cur = parser->root.cursor; + if ( cur >= limit ) { - cur++; - if ( cur >= limit ) - { - FT_ERROR(( "parse_encoding: out of bounds!\n" )); - parser->root.error = T1_Err_Invalid_File_Format; - return; - } + FT_ERROR(( "parse_encoding: out of bounds!\n" )); + parser->root.error = T1_Err_Invalid_File_Format; + return; } - /* if we have a number, then the encoding is an array, */ - /* and we must load it now */ - if ( (FT_Byte)( *cur - '0' ) < 10 ) + /* if we have a number or `[', the encoding is an array, */ + /* and we must load it now */ + if ( ft_isdigit( *cur ) || *cur == '[' ) { - T1_Encoding encode = &face->type1.encoding; + T1_Encoding encode = &face->type1.encoding; FT_Int count, n; - PS_Table char_table = &loader->encoding_table; - FT_Memory memory = parser->root.memory; + PS_Table char_table = &loader->encoding_table; + FT_Memory memory = parser->root.memory; FT_Error error; + FT_Bool only_immediates = 0; - if ( encode->char_index ) - /* with synthetic fonts, it's possible we get here twice */ - return; + /* read the number of entries in the encoding; should be 256 */ + if ( *cur == '[' ) + { + count = 256; + only_immediates = 1; + parser->root.cursor++; + } + else + count = (FT_Int)T1_ToInt( parser ); - /* read the number of entries in the encoding, should be 256 */ - count = (FT_Int)T1_ToInt( parser ); - if ( parser->root.error ) + T1_Skip_Spaces( parser ); + if ( parser->root.cursor >= limit ) return; /* we use a T1_Table to store our charnames */ loader->num_chars = encode->num_chars = count; - if ( FT_NEW_ARRAY( encode->char_index, count ) || - FT_NEW_ARRAY( encode->char_name, count ) || + if ( FT_NEW_ARRAY( encode->char_index, count ) || + FT_NEW_ARRAY( encode->char_name, count ) || FT_SET_ERROR( psaux->ps_table_funcs->init( char_table, count, memory ) ) ) { @@ -1019,8 +951,11 @@ T1_Add_Table( char_table, n, notdef, 8 ); } - /* Now, we will need to read a record of the form */ - /* ... charcode /charname ... for each entry in our table */ + /* Now we need to read records of the form */ + /* */ + /* ... charcode /charname ... */ + /* */ + /* for each entry in our table. */ /* */ /* We simply look for a number followed by an immediate */ /* name. Note that this ignores correctly the sequence */ @@ -1030,75 +965,85 @@ /* */ /* used to clean the encoding array before anything else. */ /* */ - /* We stop when we encounter a `def'. */ + /* Alternatively, if the array is directly given as */ + /* */ + /* /Encoding [ ... ] */ + /* */ + /* we only read immediates. */ - cur = parser->root.cursor; - limit = parser->root.limit; - n = 0; + n = 0; + T1_Skip_Spaces( parser ); - for ( ; cur < limit; ) + while ( parser->root.cursor < limit ) { - FT_Byte c; + cur = parser->root.cursor; - - c = *cur; - - /* we stop when we encounter a `def' */ - if ( c == 'd' && cur + 3 < limit ) + /* we stop when we encounter a `def' or `]' */ + if ( *cur == 'd' && cur + 3 < limit ) { - if ( cur[1] == 'e' && - cur[2] == 'f' && - is_space( cur[-1] ) && - is_space( cur[3] ) ) + if ( cur[1] == 'e' && + cur[2] == 'f' && + is_space( cur[3] ) ) { FT_TRACE6(( "encoding end\n" )); + cur += 3; break; } } + if ( *cur == ']' ) + { + FT_TRACE6(( "encoding end\n" )); + cur++; + break; + } - /* otherwise, we must find a number before anything else */ - if ( (FT_Byte)( c - '0' ) < 10 ) + /* check whether we've found an entry */ + if ( ft_isdigit( *cur ) || only_immediates ) { FT_Int charcode; - parser->root.cursor = cur; - charcode = (FT_Int)T1_ToInt( parser ); - cur = parser->root.cursor; - - /* skip whitespace */ - while ( cur < limit && is_space( *cur ) ) - cur++; - - if ( cur < limit && *cur == '/' ) + if ( only_immediates ) + charcode = n; + else + { + charcode = (FT_Int)T1_ToInt( parser ); + T1_Skip_Spaces( parser ); + } + + cur = parser->root.cursor; + + if ( *cur == '/' && cur + 2 < limit && n < count ) { - /* bingo, we have an immediate name -- it must be a */ - /* character name */ - FT_Byte* cur2 = cur + 1; FT_PtrDist len; - while ( cur2 < limit && is_name_char( *cur2 ) ) - cur2++; + cur++; - len = cur2 - cur - 1; + parser->root.cursor = cur; + T1_Skip_PS_Token( parser ); + + len = parser->root.cursor - cur; parser->root.error = T1_Add_Table( char_table, charcode, - cur + 1, len + 1 ); - char_table->elements[charcode][len] = '\0'; + cur, len + 1 ); if ( parser->root.error ) return; + char_table->elements[charcode][len] = '\0'; - cur = cur2; + n++; } } else - cur++; + T1_Skip_PS_Token( parser ); + + T1_Skip_Spaces( parser ); } face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY; parser->root.cursor = cur; } + /* Otherwise, we should have either `StandardEncoding', */ /* `ExpertEncoding', or `ISOLatin1Encoding' */ else @@ -1116,10 +1061,7 @@ face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1; else - { - FT_ERROR(( "parse_encoding: invalid token!\n" )); - parser->root.error = T1_Err_Invalid_File_Format; - } + parser->root.error = T1_Err_Ignore; } } @@ -1128,46 +1070,49 @@ parse_subrs( T1_Face face, T1_Loader loader ) { - T1_Parser parser = &loader->parser; - PS_Table table = &loader->subrs; - FT_Memory memory = parser->root.memory; - FT_Error error; - FT_Int n; + T1_Parser parser = &loader->parser; + PS_Table table = &loader->subrs; + FT_Memory memory = parser->root.memory; + FT_Error error; + FT_Int n, num_subrs; PSAux_Service psaux = (PSAux_Service)face->psaux; - if ( loader->num_subrs ) - /* with synthetic fonts, it's possible we get here twice */ - return; + T1_Skip_Spaces( parser ); - if ( parser->root.cursor + 2 > parser->root.limit && - parser->root.cursor[0] == '[' && - parser->root.cursor[1] == ']' ) + /* test for empty array */ + if ( parser->root.cursor < parser->root.limit && + *parser->root.cursor == '[' ) { - /* empty array */ + T1_Skip_PS_Token( parser ); + T1_Skip_Spaces ( parser ); + if ( parser->root.cursor >= parser->root.limit || + *parser->root.cursor != ']' ) + parser->root.error = T1_Err_Invalid_File_Format; return; } - loader->num_subrs = (FT_Int)T1_ToInt( parser ); - if ( parser->root.error ) - return; + num_subrs = (FT_Int)T1_ToInt( parser ); /* position the parser right before the `dup' of the first subr */ - T1_Skip_Spaces( parser ); - T1_Skip_Alpha( parser ); /* `array' */ - T1_Skip_Spaces( parser ); + T1_Skip_PS_Token( parser ); /* `array' */ + T1_Skip_Spaces ( parser ); - /* initialize subrs array */ - error = psaux->ps_table_funcs->init( table, loader->num_subrs, memory ); - if ( error ) - goto Fail; + /* initialize subrs array -- with synthetic fonts it is possible */ + /* we get here twice */ + if ( !loader->num_subrs ) + { + error = psaux->ps_table_funcs->init( table, num_subrs, memory ); + if ( error ) + goto Fail; + } /* the format is simple: */ /* */ /* `index' + binary data */ /* */ - for ( n = 0; n < loader->num_subrs; n++ ) + for ( n = 0; n < num_subrs; n++ ) { FT_Long idx, size; FT_Byte* base; @@ -1178,6 +1123,8 @@ if ( ft_strncmp( (char*)parser->root.cursor, "dup", 3 ) != 0 ) break; + T1_Skip_PS_Token( parser ); /* `dup' */ + idx = T1_ToInt( parser ); if ( !read_binary_data( parser, &size, &base ) ) @@ -1187,16 +1134,19 @@ /* (bound to `noaccess put') or by two separate tokens: */ /* `noaccess' & `put'. We position the parser right */ /* before the next `dup', if any. */ - T1_Skip_Spaces( parser ); - T1_Skip_Alpha( parser ); /* `NP' or `I' or `noaccess' */ - T1_Skip_Spaces( parser ); + T1_Skip_PS_Token( parser ); /* `NP' or `|' or `noaccess' */ + T1_Skip_Spaces ( parser ); if ( ft_strncmp( (char*)parser->root.cursor, "put", 3 ) == 0 ) { - T1_Skip_Alpha( parser ); /* skip `put' */ - T1_Skip_Spaces( parser ); + T1_Skip_PS_Token( parser ); /* skip `put' */ + T1_Skip_Spaces ( parser ); } + /* with synthetic fonts it is possible we get here twice */ + if ( loader->num_subrs ) + continue; + /* some fonts use a value of -1 for lenIV to indicate that */ /* the charstrings are unencoded */ /* */ @@ -1213,15 +1163,19 @@ FT_MEM_COPY( temp, base, size ); psaux->t1_decrypt( temp, size, 4330 ); size -= face->type1.private_dict.lenIV; - error = T1_Add_Table( table, idx, + error = T1_Add_Table( table, (FT_Int)idx, temp + face->type1.private_dict.lenIV, size ); FT_FREE( temp ); } else - error = T1_Add_Table( table, idx, base, size ); + error = T1_Add_Table( table, (FT_Int)idx, base, size ); if ( error ) goto Fail; } + + if ( !loader->num_subrs ) + loader->num_subrs = num_subrs; + return; Fail: @@ -1229,6 +1183,9 @@ } +#define TABLE_EXTEND 5 + + static void parse_charstrings( T1_Face face, T1_Loader loader ) @@ -1244,41 +1201,43 @@ FT_Byte* cur; FT_Byte* limit = parser->root.limit; - FT_Int n; + FT_Int n, num_glyphs; FT_UInt notdef_index = 0; FT_Byte notdef_found = 0; - if ( loader->num_glyphs ) - /* with synthetic fonts, it's possible we get here twice */ + num_glyphs = (FT_Int)T1_ToInt( parser ); + /* some fonts like Optima-Oblique not only define the /CharStrings */ + /* array but access it also */ + if ( num_glyphs == 0 || parser->root.error ) return; - loader->num_glyphs = (FT_Int)T1_ToInt( parser ); - if ( parser->root.error ) - return; + /* initialize tables, leaving space for addition of .notdef, */ + /* if necessary, and a few other glyphs to handle buggy */ + /* fonts which have more glyphs than specified. */ - /* initialize tables (leaving room for addition of .notdef, */ - /* if necessary). */ + /* for some non-standard fonts like `Optima' which provides */ + /* different outlines depending on the resolution it is */ + /* possible to get here twice */ + if ( !loader->num_glyphs ) + { + error = psaux->ps_table_funcs->init( + code_table, num_glyphs + 1 + TABLE_EXTEND, memory ); + if ( error ) + goto Fail; - error = psaux->ps_table_funcs->init( code_table, - loader->num_glyphs + 1, - memory ); - if ( error ) - goto Fail; + error = psaux->ps_table_funcs->init( + name_table, num_glyphs + 1 + TABLE_EXTEND, memory ); + if ( error ) + goto Fail; - error = psaux->ps_table_funcs->init( name_table, - loader->num_glyphs + 1, - memory ); - if ( error ) - goto Fail; + /* Initialize table for swapping index notdef_index and */ + /* index 0 names and codes (if necessary). */ - /* Initialize table for swapping index notdef_index and */ - /* index 0 names and codes (if necessary). */ - - error = psaux->ps_table_funcs->init( swap_table, 4, memory ); - - if ( error ) - goto Fail; + error = psaux->ps_table_funcs->init( swap_table, 4, memory ); + if ( error ) + goto Fail; + } n = 0; @@ -1288,11 +1247,9 @@ FT_Byte* base; - /* the format is simple: */ - /* `/glyphname' + binary data */ - /* */ - /* note that we stop when we find a `def' */ - /* */ + /* the format is simple: */ + /* `/glyphname' + binary data */ + T1_Skip_Spaces( parser ); cur = parser->root.cursor; @@ -1300,50 +1257,62 @@ break; /* we stop when we find a `def' or `end' keyword */ - if ( *cur == 'd' && - cur + 3 < limit && - cur[1] == 'e' && - cur[2] == 'f' ) - break; - - if ( *cur == 'e' && - cur + 3 < limit && - cur[1] == 'n' && - cur[2] == 'd' ) - break; - - if ( *cur != '/' ) - T1_Skip_Alpha( parser ); - else + if ( cur + 3 < limit && is_space( cur[3] ) ) + { + if ( cur[0] == 'd' && + cur[1] == 'e' && + cur[2] == 'f' ) + break; + + if ( cur[0] == 'e' && + cur[1] == 'n' && + cur[2] == 'd' ) + break; + } + + T1_Skip_PS_Token( parser ); + + if ( *cur == '/' ) { - FT_Byte* cur2 = cur + 1; FT_PtrDist len; - while ( cur2 < limit && is_name_char( *cur2 ) ) - cur2++; - len = cur2 - cur - 1; + if ( cur + 1 >= limit ) + { + error = T1_Err_Invalid_File_Format; + goto Fail; + } - error = T1_Add_Table( name_table, n, cur + 1, len + 1 ); + cur++; /* skip `/' */ + len = parser->root.cursor - cur; + + if ( !read_binary_data( parser, &size, &base ) ) + return; + + /* for some non-standard fonts like `Optima' which provides */ + /* different outlines depending on the resolution it is */ + /* possible to get here twice */ + if ( loader->num_glyphs ) + continue; + + error = T1_Add_Table( name_table, n, cur, len + 1 ); if ( error ) goto Fail; /* add a trailing zero to the name table */ name_table->elements[n][len] = '\0'; - /* record index of /.notdef */ - if ( ft_strcmp( (const char*)".notdef", + /* record index of /.notdef */ + if ( *cur == '.' && + ft_strcmp( ".notdef", (const char*)(name_table->elements[n]) ) == 0 ) { notdef_index = n; notdef_found = 1; } - parser->root.cursor = cur2; - if ( !read_binary_data( parser, &size, &base ) ) - return; - - if ( face->type1.private_dict.lenIV >= 0 ) + if ( face->type1.private_dict.lenIV >= 0 && + n < num_glyphs + TABLE_EXTEND ) { FT_Byte* temp; @@ -1364,23 +1333,24 @@ goto Fail; n++; - if ( n >= loader->num_glyphs ) - break; } } - loader->num_glyphs = n; + if ( loader->num_glyphs ) + return; + else + loader->num_glyphs = n; - /* if /.notdef is found but does not occupy index 0, do our magic. */ + /* if /.notdef is found but does not occupy index 0, do our magic. */ if ( ft_strcmp( (const char*)".notdef", (const char*)name_table->elements[0] ) && notdef_found ) { - /* Swap glyph in index 0 with /.notdef glyph. First, add index 0 */ - /* name and code entries to swap_table. Then place notdef_index name */ - /* and code entries into swap_table. Then swap name and code */ - /* entries at indices notdef_index and 0 using values stored in */ - /* swap_table. */ + /* Swap glyph in index 0 with /.notdef glyph. First, add index 0 */ + /* name and code entries to swap_table. Then place notdef_index */ + /* name and code entries into swap_table. Then swap name and code */ + /* entries at indices notdef_index and 0 using values stored in */ + /* swap_table. */ /* Index 0 name */ error = T1_Add_Table( swap_table, 0, @@ -1442,7 +1412,7 @@ /* We take index 0 and add it to the end of the table(s) */ /* and add our own /.notdef glyph to index 0. */ - /* 0 333 hsbw endchar */ + /* 0 333 hsbw endchar */ FT_Byte notdef_glyph[] = {0x8B, 0xF7, 0xE1, 0x0D, 0x0E}; char* notdef_name = (char *)".notdef"; @@ -1491,6 +1461,14 @@ } + /*************************************************************************/ + /* */ + /* Define the token field static variables. This is a set of */ + /* T1_FieldRec variables. */ + /* */ + /*************************************************************************/ + + static const T1_FieldRec t1_keywords[] = { @@ -1498,10 +1476,6 @@ #include "t1tokens.h" /* now add the special functions... */ - T1_FIELD_CALLBACK( "FontName", parse_font_name ) -#if 0 - T1_FIELD_CALLBACK( "FontBBox", parse_font_bbox ) -#endif T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix ) T1_FIELD_CALLBACK( "Encoding", parse_encoding ) T1_FIELD_CALLBACK( "Subrs", parse_subrs ) @@ -1512,126 +1486,208 @@ T1_FIELD_CALLBACK( "BlendDesignMap", parse_blend_design_map ) T1_FIELD_CALLBACK( "BlendAxisTypes", parse_blend_axis_types ) T1_FIELD_CALLBACK( "WeightVector", parse_weight_vector ) - T1_FIELD_CALLBACK( "shareddict", parse_shared_dict ) #endif { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0 } }; +#define T1_FIELD_COUNT \ + ( sizeof ( t1_keywords ) / sizeof ( t1_keywords[0] ) ) + + static FT_Error parse_dict( T1_Face face, T1_Loader loader, FT_Byte* base, - FT_Long size ) + FT_Long size, + FT_Byte* keyword_flags ) { T1_Parser parser = &loader->parser; + FT_Byte *limit, *start_binary = NULL; + FT_Bool have_integer = 0; parser->root.cursor = base; parser->root.limit = base + size; - parser->root.error = 0; + parser->root.error = T1_Err_Ok; + limit = parser->root.limit; + + T1_Skip_Spaces( parser ); + + while ( parser->root.cursor < limit ) { - FT_Byte* cur = base; - FT_Byte* limit = cur + size; + FT_Byte* cur; - for ( ; cur < limit; cur++ ) + cur = parser->root.cursor; + + /* look for `FontDirectory' which causes problems for some fonts */ + if ( *cur == 'F' && cur + 25 < limit && + ft_strncmp( (char*)cur, "FontDirectory", 13 ) == 0 ) { - /* look for `FontDirectory', which causes problems on some fonts */ - if ( *cur == 'F' && cur + 25 < limit && - ft_strncmp( (char*)cur, "FontDirectory", 13 ) == 0 ) + FT_Byte* cur2; + + + /* skip the `FontDirectory' keyword */ + T1_Skip_PS_Token( parser ); + T1_Skip_Spaces ( parser ); + cur = cur2 = parser->root.cursor; + + /* look up the `known' keyword */ + while ( cur < limit ) { - FT_Byte* cur2; + if ( *cur == 'k' && cur + 5 < limit && + ft_strncmp( (char*)cur, "known", 5 ) == 0 ) + break; - - /* skip the `FontDirectory' keyword */ - cur += 13; - cur2 = cur; - - /* lookup the `known' keyword */ - while ( cur < limit && *cur != 'k' && - ft_strncmp( (char*)cur, "known", 5 ) ) - cur++; - - if ( cur < limit ) - { - T1_TokenRec token; - - - /* skip the `known' keyword and the token following it */ - cur += 5; - loader->parser.root.cursor = cur; - T1_ToToken( &loader->parser, &token ); - - /* if the last token was an array, skip it! */ - if ( token.type == T1_TOKEN_TYPE_ARRAY ) - cur2 = parser->root.cursor; - } - cur = cur2; + T1_Skip_PS_Token( parser ); + T1_Skip_Spaces ( parser ); + cur = parser->root.cursor; } - /* look for immediates */ - else if ( *cur == '/' && cur + 2 < limit ) + + if ( cur < limit ) { - FT_Byte* cur2; - FT_PtrDist len; + T1_TokenRec token; - cur++; - cur2 = cur; - while ( cur2 < limit && is_name_char( *cur2 ) ) - cur2++; + /* skip the `known' keyword and the token following it */ + T1_Skip_PS_Token( parser ); + T1_ToToken( parser, &token ); - len = cur2 - cur; - if ( len > 0 && len < 22 ) - { - { - /* now, compare the immediate name to the keyword table */ - T1_Field keyword = (T1_Field)t1_keywords; - - - for (;;) - { - FT_Byte* name; - - - name = (FT_Byte*)keyword->ident; - if ( !name ) - break; - - if ( cur[0] == name[0] && - len == ft_strlen( (const char*)name ) ) - { - FT_PtrDist n; - - - for ( n = 1; n < len; n++ ) - if ( cur[n] != name[n] ) - break; - - if ( n >= len ) - { - /* we found it -- run the parsing callback! */ - parser->root.cursor = cur2; - T1_Skip_Spaces( parser ); - parser->root.error = t1_load_keyword( face, - loader, - keyword ); - if ( parser->root.error ) - return parser->root.error; - - cur = parser->root.cursor; - break; - } - } - keyword++; - } - } - } + /* if the last token was an array, skip it! */ + if ( token.type == T1_TOKEN_TYPE_ARRAY ) + cur2 = parser->root.cursor; } + parser->root.cursor = cur2; + have_integer = 0; } + + /* look for `eexec' */ + else if ( *cur == 'e' && cur + 5 < limit && + ft_strncmp( (char*)cur, "eexec", 5 ) == 0 ) + break; + + /* look for `closefile' which ends the eexec section */ + else if ( *cur == 'c' && cur + 9 < limit && + ft_strncmp( (char*)cur, "closefile", 9 ) == 0 ) + break; + + /* check whether we have an integer */ + else if ( ft_isdigit( *cur ) ) + { + start_binary = cur; + T1_Skip_PS_Token( parser ); + have_integer = 1; + } + + /* in valid Type 1 fonts we don't see `RD' or `-|' directly */ + /* since those tokens are handled by parse_subrs and */ + /* parse_charstrings */ + else if ( *cur == 'R' && cur + 6 < limit && *(cur + 1) == 'D' && + have_integer ) + { + FT_Long s; + FT_Byte* b; + + + parser->root.cursor = start_binary; + if ( !read_binary_data( parser, &s, &b ) ) + return T1_Err_Invalid_File_Format; + have_integer = 0; + } + + else if ( *cur == '-' && cur + 6 < limit && *(cur + 1) == '|' && + have_integer ) + { + FT_Long s; + FT_Byte* b; + + + parser->root.cursor = start_binary; + if ( !read_binary_data( parser, &s, &b ) ) + return T1_Err_Invalid_File_Format; + have_integer = 0; + } + + /* look for immediates */ + else if ( *cur == '/' && cur + 2 < limit ) + { + FT_PtrDist len; + + + cur++; + + parser->root.cursor = cur; + T1_Skip_PS_Token( parser ); + + len = parser->root.cursor - cur; + + if ( len > 0 && len < 22 && parser->root.cursor < limit ) + { + /* now compare the immediate name to the keyword table */ + T1_Field keyword = (T1_Field)t1_keywords; + FT_Byte* keyword_flag = keyword_flags; + + + for (;;) + { + FT_Byte* name; + + + name = (FT_Byte*)keyword->ident; + if ( !name ) + break; + + if ( cur[0] == name[0] && + len == ft_strlen( (const char *)name ) && + ft_memcmp( cur, name, len ) == 0 ) + { + /* We found it -- run the parsing callback! */ + /* We only record the first instance of any */ + /* field to deal adequately with synthetic */ + /* fonts; /Subrs and /CharStrings are */ + /* handled specially. */ + if ( keyword_flag[0] == 0 || + ft_strcmp( (const char*)name, "Subrs" ) == 0 || + ft_strcmp( (const char*)name, "CharStrings") == 0 ) + { + parser->root.error = t1_load_keyword( face, + loader, + keyword ); + if ( parser->root.error == T1_Err_Ok ) + keyword_flag[0] = 1; + else + { + if ( FT_ERROR_BASE( parser->root.error ) == FT_Err_Ignore ) + parser->root.error = T1_Err_Ok; + else + return parser->root.error; + } + } + break; + } + + keyword++; + keyword_flag++; + } + } + + have_integer = 0; + } + else + { + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + goto Exit; + have_integer = 0; + } + + T1_Skip_Spaces( parser ); } + + Exit: return parser->root.error; } @@ -1680,18 +1736,21 @@ T1_LoaderRec loader; T1_Parser parser; T1_Font type1 = &face->type1; + PS_Private priv = &type1->private_dict; FT_Error error; + FT_Byte keyword_flags[T1_FIELD_COUNT]; PSAux_Service psaux = (PSAux_Service)face->psaux; t1_init_loader( &loader, face ); - /* default lenIV */ - type1->private_dict.lenIV = 4; - - /* default blue fuzz, we put it there since 0 is a valid value */ - type1->private_dict.blue_fuzz = 1; + /* default values */ + priv->blue_shift = 7; + priv->blue_fuzz = 1; + priv->lenIV = 4; + priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L ); + priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 ); parser = &loader.parser; error = T1_New_Parser( parser, @@ -1701,7 +1760,16 @@ if ( error ) goto Exit; - error = parse_dict( face, &loader, parser->base_dict, parser->base_len ); + { + FT_UInt n; + + + for ( n = 0; n < T1_FIELD_COUNT; n++ ) + keyword_flags[n] = 0; + } + + error = parse_dict( face, &loader, parser->base_dict, parser->base_len, + keyword_flags ); if ( error ) goto Exit; @@ -1710,10 +1778,35 @@ goto Exit; error = parse_dict( face, &loader, parser->private_dict, - parser->private_len ); + parser->private_len, + keyword_flags ); if ( error ) goto Exit; +#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT + + /* the following can happen for MM instances; we then treat the */ + /* font as a normal PS font */ + if ( face->blend && + ( !face->blend->num_designs || !face->blend->num_axis ) ) + T1_Done_Blend( face ); + + /* another safety check */ + if ( face->blend ) + { + FT_UInt i; + + + for ( i = 0; i < face->blend->num_axis; i++ ) + if ( !face->blend->design_map[i].num_points ) + { + T1_Done_Blend( face ); + break; + } + } + +#endif /* T1_CONFIG_OPTION_NO_MM_SUPPORT */ + /* now, propagate the subrs, charstrings, and glyphnames tables */ /* to the Type1 data */ type1->num_glyphs = loader.num_glyphs; @@ -1732,7 +1825,7 @@ #endif if ( !loader.charstrings.init ) { - FT_ERROR(( "T1_Open_Face: no charstrings array in face!\n" )); + FT_ERROR(( "T1_Open_Face: no `/CharStrings' array in face!\n" )); error = T1_Err_Invalid_File_Format; } @@ -1786,13 +1879,27 @@ if ( ft_strcmp( (const char*)".notdef", (const char*)glyph_name ) != 0 ) { - if ( charcode < min_char ) min_char = charcode; - if ( charcode > max_char ) max_char = charcode; + if ( charcode < min_char ) + min_char = charcode; + if ( charcode > max_char ) + max_char = charcode; } break; } } } + + /* + * Yes, this happens: Certain PDF-embedded fonts have only a + * `.notdef' glyph defined! + */ + + if ( min_char > max_char ) + { + min_char = 0; + max_char = loader.encoding_table.max_elems; + } + type1->encoding.code_first = min_char; type1->encoding.code_last = max_char; type1->encoding.num_chars = loader.num_chars; @@ -1804,4 +1911,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/type1/t1load.h b/src/libs/freetype2/type1/t1load.h index f7635fd50f..804a010450 100644 --- a/src/libs/freetype2/type1/t1load.h +++ b/src/libs/freetype2/type1/t1load.h @@ -81,4 +81,4 @@ FT_END_HEADER #endif /* __T1LOAD_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/type1/t1objs.c b/src/libs/freetype2/type1/t1objs.c index 27f44dd642..a832ee0002 100644 --- a/src/libs/freetype2/type1/t1objs.c +++ b/src/libs/freetype2/type1/t1objs.c @@ -4,7 +4,7 @@ /* */ /* Type 1 objects manager (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,6 +19,7 @@ #include #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_IDS_H #include "t1gload.h" #include "t1load.h" @@ -29,7 +30,7 @@ #include "t1afm.h" #endif -#include FT_INTERNAL_POSTSCRIPT_NAMES_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H #include FT_INTERNAL_POSTSCRIPT_AUX_H @@ -118,9 +119,9 @@ if ( funcs ) error = funcs->set_scale( (PSH_Globals)size->root.internal, - size->root.metrics.x_scale, - size->root.metrics.y_scale, - 0, 0 ); + size->root.metrics.x_scale, + size->root.metrics.y_scale, + 0, 0 ); return error; } @@ -275,10 +276,11 @@ FT_Int num_params, FT_Parameter* params ) { - FT_Error error; - PSNames_Service psnames; - PSAux_Service psaux; - PSHinter_Service pshinter; + FT_Error error; + FT_Service_PsCMaps psnames; + PSAux_Service psaux; + T1_Font type1 = &face->type1; + PS_FontInfo info = &type1->font_info; FT_UNUSED( num_params ); FT_UNUSED( params ); @@ -288,9 +290,8 @@ face->root.num_faces = 1; - face->psnames = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), - "psnames" ); - psnames = (PSNames_Service)face->psnames; + FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); + face->psnames = psnames; face->psaux = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), "psaux" ); @@ -298,9 +299,8 @@ face->pshinter = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), "pshinter" ); - pshinter = (PSHinter_Service)face->pshinter; - /* open the tokenizer, this will also check the font format */ + /* open the tokenizer; this will also check the font format */ error = T1_Open_Face( face ); if ( error ) goto Exit; @@ -317,22 +317,23 @@ goto Exit; } - /* Now, load the font program into the face object */ + /* now load the font program into the face object */ - /* Init the face object fields */ - /* Now set up root face fields */ + /* initialize the face object fields */ + + /* set up root face fields */ { FT_Face root = (FT_Face)&face->root; - root->num_glyphs = face->type1.num_glyphs; + root->num_glyphs = type1->num_glyphs; root->face_index = face_index; - root->face_flags = FT_FACE_FLAG_SCALABLE; + root->face_flags = FT_FACE_FLAG_SCALABLE; root->face_flags |= FT_FACE_FLAG_HORIZONTAL; root->face_flags |= FT_FACE_FLAG_GLYPH_NAMES; - if ( face->type1.font_info.is_fixed_pitch ) + if ( info->is_fixed_pitch ) root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; if ( face->blend ) @@ -342,45 +343,55 @@ /* get style name -- be careful, some broken fonts only */ /* have a `/FontName' dictionary entry! */ - root->family_name = face->type1.font_info.family_name; + root->family_name = info->family_name; + /* assume "Regular" style if we don't know better */ + root->style_name = (char *)"Regular"; if ( root->family_name ) { - char* full = face->type1.font_info.full_name; + char* full = info->full_name; char* family = root->family_name; if ( full ) { - while ( *family && *full == *family ) + while ( *full ) { - family++; - full++; + if ( *full == *family ) + { + family++; + full++; + } + else + { + if ( *full == ' ' || *full == '-' ) + full++; + else if ( *family == ' ' || *family == '-' ) + family++; + else + { + if ( !*family ) + root->style_name = full; + break; + } + } } - - root->style_name = ( *full == ' ' ? full + 1 - : (char *)"Regular" ); } - else - root->style_name = (char *)"Regular"; } else { /* do we have a `/FontName'? */ - if ( face->type1.font_name ) - { - root->family_name = face->type1.font_name; - root->style_name = (char *)"Regular"; - } + if ( type1->font_name ) + root->family_name = type1->font_name; } /* compute style flags */ root->style_flags = 0; - if ( face->type1.font_info.italic_angle ) + if ( info->italic_angle ) root->style_flags |= FT_STYLE_FLAG_ITALIC; - if ( face->type1.font_info.weight ) + if ( info->weight ) { - if ( !ft_strcmp( face->type1.font_info.weight, "Bold" ) || - !ft_strcmp( face->type1.font_info.weight, "Black" ) ) + if ( !ft_strcmp( info->weight, "Bold" ) || + !ft_strcmp( info->weight, "Black" ) ) root->style_flags |= FT_STYLE_FLAG_BOLD; } @@ -388,10 +399,10 @@ root->num_fixed_sizes = 0; root->available_sizes = 0; - root->bbox.xMin = face->type1.font_bbox.xMin >> 16; - root->bbox.yMin = face->type1.font_bbox.yMin >> 16; - root->bbox.xMax = ( face->type1.font_bbox.xMax + 0xFFFFU ) >> 16; - root->bbox.yMax = ( face->type1.font_bbox.yMax + 0xFFFFU ) >> 16; + root->bbox.xMin = type1->font_bbox.xMin >> 16; + root->bbox.yMin = type1->font_bbox.yMin >> 16; + root->bbox.xMax = ( type1->font_bbox.xMax + 0xFFFFU ) >> 16; + root->bbox.yMax = ( type1->font_bbox.yMax + 0xFFFFU ) >> 16; /* Set units_per_EM if we didn't set it in parse_font_matrix. */ if ( !root->units_per_EM ) @@ -400,13 +411,13 @@ root->ascender = (FT_Short)( root->bbox.yMax ); root->descender = (FT_Short)( root->bbox.yMin ); root->height = (FT_Short)( - ( ( root->ascender - root->descender ) * 12 ) / 10 ); + ( ( root->ascender - root->descender ) * 12 ) / 10 ); /* now compute the maximum advance width */ root->max_advance_width = (FT_Short)( root->bbox.xMax ); { - FT_Int max_advance; + FT_Pos max_advance; error = T1_Compute_Max_Advance( face, &max_advance ); @@ -420,8 +431,8 @@ root->max_advance_height = root->height; - root->underline_position = face->type1.font_info.underline_position; - root->underline_thickness = face->type1.font_info.underline_thickness; + root->underline_position = (FT_Short)info->underline_position; + root->underline_thickness = (FT_Short)info->underline_thickness; root->internal->max_points = 0; root->internal->max_contours = 0; @@ -451,29 +462,29 @@ charmap.platform_id = 7; clazz = NULL; - switch ( face->type1.encoding_type ) + switch ( type1->encoding_type ) { case T1_ENCODING_TYPE_STANDARD: charmap.encoding = FT_ENCODING_ADOBE_STANDARD; - charmap.encoding_id = 0; + charmap.encoding_id = TT_ADOBE_ID_STANDARD; clazz = cmap_classes->standard; break; case T1_ENCODING_TYPE_EXPERT: charmap.encoding = FT_ENCODING_ADOBE_EXPERT; - charmap.encoding_id = 1; + charmap.encoding_id = TT_ADOBE_ID_EXPERT; clazz = cmap_classes->expert; break; case T1_ENCODING_TYPE_ARRAY: charmap.encoding = FT_ENCODING_ADOBE_CUSTOM; - charmap.encoding_id = 2; + charmap.encoding_id = TT_ADOBE_ID_CUSTOM; clazz = cmap_classes->custom; break; case T1_ENCODING_TYPE_ISOLATIN1: charmap.encoding = FT_ENCODING_ADOBE_LATIN_1; - charmap.encoding_id = 3; + charmap.encoding_id = TT_ADOBE_ID_LATIN_1; clazz = cmap_classes->unicode; break; @@ -538,4 +549,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/type1/t1objs.h b/src/libs/freetype2/type1/t1objs.h index 5435da0ca7..9aeb10dd22 100644 --- a/src/libs/freetype2/type1/t1objs.h +++ b/src/libs/freetype2/type1/t1objs.h @@ -167,4 +167,4 @@ FT_END_HEADER #endif /* __T1OBJS_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/type1/t1parse.c b/src/libs/freetype2/type1/t1parse.c index 294409a8f2..544aa093f8 100644 --- a/src/libs/freetype2/type1/t1parse.c +++ b/src/libs/freetype2/type1/t1parse.c @@ -4,7 +4,7 @@ /* */ /* Type 1 parser (body). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -65,53 +65,30 @@ /*************************************************************************/ -#define IS_T1_WHITESPACE( c ) ( (c) == ' ' || (c) == '\t' ) -#define IS_T1_LINESPACE( c ) ( (c) == '\r' || (c) == '\n' ) - -#define IS_T1_SPACE( c ) ( IS_T1_WHITESPACE( c ) || IS_T1_LINESPACE( c ) ) - - - typedef struct PFB_Tag_ + static FT_Error + read_pfb_tag( FT_Stream stream, + FT_UShort *atag, + FT_Long *asize ) { + FT_Error error; FT_UShort tag; FT_Long size; - } PFB_Tag; + *atag = 0; + *asize = 0; -#undef FT_STRUCTURE -#define FT_STRUCTURE PFB_Tag - - - static - const FT_Frame_Field pfb_tag_fields[] = - { - FT_FRAME_START( 6 ), - FT_FRAME_USHORT ( tag ), - FT_FRAME_LONG_LE( size ), - FT_FRAME_END - }; - - - static FT_Error - read_pfb_tag( FT_Stream stream, - FT_UShort* tag, - FT_Long* size ) - { - FT_Error error; - PFB_Tag head; - - - *tag = 0; - *size = 0; - if ( !FT_STREAM_READ_FIELDS( pfb_tag_fields, &head ) ) + if ( !FT_READ_USHORT( tag ) ) { - if ( head.tag == 0x8001U || head.tag == 0x8002U ) + if ( tag == 0x8001U || tag == 0x8002U ) { - *tag = head.tag; - *size = head.size; + if ( !FT_READ_LONG_LE( size ) ) + *asize = size; } + + *atag = tag; } + return error; } @@ -127,7 +104,7 @@ FT_Long size; - psaux->ps_parser_funcs->init( &parser->root,0, 0, memory ); + psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); parser->stream = stream; parser->base_len = 0; @@ -242,36 +219,13 @@ } - /* return the value of an hexadecimal digit */ - static int - hexa_value( char c ) - { - unsigned int d; - - - d = (unsigned int)( c - '0' ); - if ( d <= 9 ) - return (int)d; - - d = (unsigned int)( c - 'a' ); - if ( d <= 5 ) - return (int)( d + 10 ); - - d = (unsigned int)( c - 'A' ); - if ( d <= 5 ) - return (int)( d + 10 ); - - return -1; - } - - FT_LOCAL_DEF( FT_Error ) T1_Get_Private_Dict( T1_Parser parser, PSAux_Service psaux ) { FT_Stream stream = parser->stream; FT_Memory memory = parser->root.memory; - FT_Error error = 0; + FT_Error error = T1_Err_Ok; FT_Long size; @@ -325,7 +279,8 @@ break; } - if ( FT_STREAM_READ( parser->private_dict + parser->private_len, size ) ) + if ( FT_STREAM_READ( parser->private_dict + parser->private_len, + size ) ) goto Fail; parser->private_len += size; @@ -333,9 +288,9 @@ } else { - /* we have already `loaded' the whole PFA font file into memory; */ + /* We have already `loaded' the whole PFA font file into memory; */ /* if this is a memory resource, allocate a new block to hold */ - /* the private dict. Otherwise, simply overwrite into the base */ + /* the private dict. Otherwise, simply overwrite into the base */ /* dictionary block in the heap. */ /* first of all, look at the `eexec' keyword */ @@ -344,24 +299,18 @@ FT_Byte c; + Again: for (;;) { c = cur[0]; if ( c == 'e' && cur + 9 < limit ) /* 9 = 5 letters for `eexec' + */ /* newline + 4 chars */ { - if ( cur[1] == 'e' && cur[2] == 'x' && - cur[3] == 'e' && cur[4] == 'c' ) - { - cur += 6; /* we skip the newling after the `eexec' */ - - /* XXX: Some fonts use DOS-linefeeds, i.e. \r\n; we need to */ - /* skip the extra \n if we find it */ - if ( cur[0] == '\n' ) - cur++; - + if ( cur[1] == 'e' && + cur[2] == 'x' && + cur[3] == 'e' && + cur[4] == 'c' ) break; - } } cur++; if ( cur >= limit ) @@ -373,10 +322,57 @@ } } + /* check whether `eexec' was real -- it could be in a comment */ + /* or string (as e.g. in u003043t.gsf from ghostscript) */ + + parser->root.cursor = parser->base_dict; + parser->root.limit = cur + 9; + + cur = parser->root.cursor; + limit = parser->root.limit; + + while ( cur < limit ) + { + if ( *cur == 'e' && ft_strncmp( (char*)cur, "eexec", 5 ) == 0 ) + goto Found; + + T1_Skip_PS_Token( parser ); + T1_Skip_Spaces ( parser ); + cur = parser->root.cursor; + } + + /* we haven't found the correct `eexec'; go back and continue */ + /* searching */ + + cur = limit; + limit = parser->base_dict + parser->base_len; + goto Again; + /* now determine where to write the _encrypted_ binary private */ /* dictionary. We overwrite the base dictionary for disk-based */ /* resources and allocate a new block otherwise */ + Found: + parser->root.limit = parser->base_dict + parser->base_len; + + T1_Skip_PS_Token( parser ); + cur = parser->root.cursor; + if ( *cur == '\r' ) + { + cur++; + if ( *cur == '\n' ) + cur++; + } + else if ( *cur == '\n' ) + cur++; + else + { + FT_ERROR(( "T1_Get_Private_Dict:" )); + FT_ERROR(( " `eexec' not properly terminated\n" )); + error = T1_Err_Invalid_File_Format; + goto Exit; + } + size = (FT_Long)( parser->base_len - ( cur - parser->base_dict ) ); if ( parser->in_memory ) @@ -402,51 +398,38 @@ /* the `eexec' keyword); if they all are hexadecimal digits, then */ /* we have a case of ASCII storage */ - if ( ( hexa_value( cur[0] ) | hexa_value( cur[1] ) | - hexa_value( cur[2] ) | hexa_value( cur[3] ) ) < 0 ) - - /* binary encoding -- `simply' copy the private dict */ - FT_MEM_COPY( parser->private_dict, cur, size ); - - else + if ( ft_isxdigit( cur[0] ) && ft_isxdigit( cur[1] ) && + ft_isxdigit( cur[2] ) && ft_isxdigit( cur[3] ) ) { /* ASCII hexadecimal encoding */ - - FT_Byte* write; - FT_Int count; + FT_Long len; - write = parser->private_dict; - count = 0; - - for ( ;cur < limit; cur++ ) - { - int hex1; - - - /* check for newline */ - if ( cur[0] == '\r' || cur[0] == '\n' ) - continue; - - /* exit if we have a non-hexadecimal digit that isn't a newline */ - hex1 = hexa_value( cur[0] ); - if ( hex1 < 0 || cur + 1 >= limit ) - break; - - /* otherwise, store byte */ - *write++ = (FT_Byte)( ( hex1 << 4 ) | hexa_value( cur[1] ) ); - count++; - cur++; - } + parser->root.cursor = cur; + (void)psaux->ps_parser_funcs->to_bytes( &parser->root, + parser->private_dict, + parser->private_len, + &len, + 0 ); + parser->private_len = len; /* put a safeguard */ - parser->private_len = write - parser->private_dict; - *write++ = 0; + parser->private_dict[len] = '\0'; } + else + /* binary encoding -- copy the private dict */ + FT_MEM_MOVE( parser->private_dict, cur, size ); } /* we now decrypt the encoded binary private dictionary */ psaux->t1_decrypt( parser->private_dict, parser->private_len, 55665U ); + + /* replace the four random bytes at the beginning with whitespace */ + parser->private_dict[0] = ' '; + parser->private_dict[1] = ' '; + parser->private_dict[2] = ' '; + parser->private_dict[3] = ' '; + parser->root.base = parser->private_dict; parser->root.cursor = parser->private_dict; parser->root.limit = parser->root.cursor + parser->private_len; @@ -457,4 +440,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/type1/t1parse.h b/src/libs/freetype2/type1/t1parse.h index 2c8948d343..6fa4ca624a 100644 --- a/src/libs/freetype2/type1/t1parse.h +++ b/src/libs/freetype2/type1/t1parse.h @@ -4,7 +4,7 @@ /* */ /* Type 1 parser (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -69,9 +69,9 @@ FT_BEGIN_HEADER FT_Byte* private_dict; FT_Long private_len; - FT_Byte in_pfb; - FT_Byte in_memory; - FT_Byte single_block; + FT_Bool in_pfb; + FT_Bool in_memory; + FT_Bool single_block; } T1_ParserRec, *T1_Parser; @@ -91,8 +91,8 @@ FT_BEGIN_HEADER } while ( 0 ) -#define T1_Skip_Spaces( p ) (p)->root.funcs.skip_spaces( &(p)->root ) -#define T1_Skip_Alpha( p ) (p)->root.funcs.skip_alpha ( &(p)->root ) +#define T1_Skip_Spaces( p ) (p)->root.funcs.skip_spaces( &(p)->root ) +#define T1_Skip_PS_Token( p ) (p)->root.funcs.skip_PS_token( &(p)->root ) #define T1_ToInt( p ) (p)->root.funcs.to_int( &(p)->root ) #define T1_ToFixed( p, t ) (p)->root.funcs.to_fixed( &(p)->root, t ) @@ -132,4 +132,4 @@ FT_END_HEADER #endif /* __T1PARSE_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/type1/t1tokens.h b/src/libs/freetype2/type1/t1tokens.h index 3669713d16..a3cc952e00 100644 --- a/src/libs/freetype2/type1/t1tokens.h +++ b/src/libs/freetype2/type1/t1tokens.h @@ -4,7 +4,7 @@ /* */ /* Type 1 tokenizer (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,16 +21,17 @@ #undef T1CODE #define T1CODE T1_FIELD_LOCATION_FONT_INFO - T1_FIELD_STRING ( "version", version ) - T1_FIELD_STRING ( "Notice", notice ) - T1_FIELD_STRING ( "FullName", full_name ) - T1_FIELD_STRING ( "FamilyName", family_name ) - T1_FIELD_STRING ( "Weight", weight ) + T1_FIELD_STRING( "version", version ) + T1_FIELD_STRING( "Notice", notice ) + T1_FIELD_STRING( "FullName", full_name ) + T1_FIELD_STRING( "FamilyName", family_name ) + T1_FIELD_STRING( "Weight", weight ) - T1_FIELD_NUM ( "ItalicAngle", italic_angle ) - T1_FIELD_TYPE_BOOL( "isFixedPitch", is_fixed_pitch ) - T1_FIELD_NUM ( "UnderlinePosition", underline_position ) - T1_FIELD_NUM ( "UnderlineThickness", underline_thickness ) + /* we use pointers to detect modifications made by synthetic fonts */ + T1_FIELD_NUM ( "ItalicAngle", italic_angle ) + T1_FIELD_BOOL ( "isFixedPitch", is_fixed_pitch ) + T1_FIELD_NUM ( "UnderlinePosition", underline_position ) + T1_FIELD_NUM ( "UnderlineThickness", underline_thickness ) #undef FT_STRUCTURE @@ -43,7 +44,7 @@ T1_FIELD_NUM ( "LanguageGroup", language_group ) T1_FIELD_NUM ( "password", password ) - T1_FIELD_FIXED ( "BlueScale", blue_scale ) + T1_FIELD_FIXED_1000( "BlueScale", blue_scale ) T1_FIELD_NUM ( "BlueShift", blue_shift ) T1_FIELD_NUM ( "BlueFuzz", blue_fuzz ) @@ -59,15 +60,18 @@ T1_FIELD_NUM_TABLE ( "StemSnapH", snap_widths, 12 ) T1_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12 ) + T1_FIELD_FIXED ( "ExpansionFactor", expansion_factor ) + #undef FT_STRUCTURE #define FT_STRUCTURE T1_FontRec #undef T1CODE #define T1CODE T1_FIELD_LOCATION_FONT_DICT - T1_FIELD_NUM( "PaintType", paint_type ) - T1_FIELD_NUM( "FontType", font_type ) - T1_FIELD_NUM( "StrokeWidth", stroke_width ) + T1_FIELD_KEY ( "FontName", font_name ) + T1_FIELD_NUM ( "PaintType", paint_type ) + T1_FIELD_NUM ( "FontType", font_type ) + T1_FIELD_FIXED( "StrokeWidth", stroke_width ) #undef FT_STRUCTURE #define FT_STRUCTURE FT_BBox @@ -77,4 +81,4 @@ T1_FIELD_BBOX("FontBBox", xMin ) -/* END */ +/* END */ diff --git a/src/libs/freetype2/type1/type1.c b/src/libs/freetype2/type1/type1.c index 862729d05c..ccc12be103 100644 --- a/src/libs/freetype2/type1/type1.c +++ b/src/libs/freetype2/type1/type1.c @@ -30,4 +30,4 @@ #endif -/* END */ +/* END */ diff --git a/src/libs/freetype2/type42/descrip.mms b/src/libs/freetype2/type42/descrip.mms index 83062cc576..a52ba06fb0 100644 --- a/src/libs/freetype2/type42/descrip.mms +++ b/src/libs/freetype2/type42/descrip.mms @@ -20,4 +20,4 @@ OBJS=type42.obj all : $(OBJS) library [--.lib]freetype.olb $(OBJS) -# EOF +# EOF diff --git a/src/libs/freetype2/type42/module.mk b/src/libs/freetype2/type42/module.mk index a2c02988b4..ceaea41b08 100644 --- a/src/libs/freetype2/type42/module.mk +++ b/src/libs/freetype2/type42/module.mk @@ -19,4 +19,4 @@ add_type42_driver: $(OPEN_DRIVER)t42_driver_class$(CLOSE_DRIVER) $(ECHO_DRIVER)type42 $(ECHO_DRIVER_DESC)Type 42 font files with no known extension$(ECHO_DRIVER_DONE) -# EOF +# EOF diff --git a/src/libs/freetype2/type42/rules.mk b/src/libs/freetype2/type42/rules.mk index 82be9d7a62..5563061955 100644 --- a/src/libs/freetype2/type42/rules.mk +++ b/src/libs/freetype2/type42/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2002 by +# Copyright 2002, 2003 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -15,25 +15,24 @@ # Type42 driver directory # -T42_DIR := $(SRC_)type42 -T42_DIR_ := $(T42_DIR)$(SEP) +T42_DIR := $(SRC_DIR)/type42 # compilation flags for the driver # -T42_COMPILE := $(FT_COMPILE) $I$(T42_DIR) +T42_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(T42_DIR)) # Type42 driver source # -T42_DRV_SRC := $(T42_DIR_)t42objs.c \ - $(T42_DIR_)t42parse.c \ - $(T42_DIR_)t42drivr.c +T42_DRV_SRC := $(T42_DIR)/t42objs.c \ + $(T42_DIR)/t42parse.c \ + $(T42_DIR)/t42drivr.c # Type42 driver headers # T42_DRV_H := $(T42_DRV_SRC:%.c=%.h) \ - $(T42_DIR_)t42error.h + $(T42_DIR)/t42error.h # Type42 driver object(s) @@ -41,24 +40,24 @@ T42_DRV_H := $(T42_DRV_SRC:%.c=%.h) \ # T42_DRV_OBJ_M is used during `multi' builds # T42_DRV_OBJ_S is used during `single' builds # -T42_DRV_OBJ_M := $(T42_DRV_SRC:$(T42_DIR_)%.c=$(OBJ_)%.$O) -T42_DRV_OBJ_S := $(OBJ_)type42.$O +T42_DRV_OBJ_M := $(T42_DRV_SRC:$(T42_DIR)/%.c=$(OBJ_DIR)/%.$O) +T42_DRV_OBJ_S := $(OBJ_DIR)/type42.$O # Type42 driver source file for single build # -T42_DRV_SRC_S := $(T42_DIR_)type42.c +T42_DRV_SRC_S := $(T42_DIR)/type42.c # Type42 driver - single object # $(T42_DRV_OBJ_S): $(T42_DRV_SRC_S) $(T42_DRV_SRC) $(FREETYPE_H) $(T42_DRV_H) - $(T42_COMPILE) $T$@ $(T42_DRV_SRC_S) + $(T42_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(T42_DRV_SRC_S)) # Type42 driver - multiple objects # -$(OBJ_)%.$O: $(T42_DIR_)%.c $(FREETYPE_H) $(T42_DRV_H) - $(T42_COMPILE) $T$@ $< +$(OBJ_DIR)/%.$O: $(T42_DIR)/%.c $(FREETYPE_H) $(T42_DRV_H) + $(T42_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) # update main driver object lists @@ -66,4 +65,5 @@ $(OBJ_)%.$O: $(T42_DIR_)%.c $(FREETYPE_H) $(T42_DRV_H) DRV_OBJS_S += $(T42_DRV_OBJ_S) DRV_OBJS_M += $(T42_DRV_OBJ_M) -# EOF + +# EOF diff --git a/src/libs/freetype2/type42/t42drivr.c b/src/libs/freetype2/type42/t42drivr.c index 0466a34b1b..2afe2db84b 100644 --- a/src/libs/freetype2/type42/t42drivr.c +++ b/src/libs/freetype2/type42/t42drivr.c @@ -4,7 +4,7 @@ /* */ /* High-level Type 42 driver interface (body). */ /* */ -/* Copyright 2002 by Roberto Alameda. */ +/* Copyright 2002, 2003, 2004 by Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -24,10 +24,9 @@ /* 2) Incremental fonts making use of the GlyphDirectory keyword */ /* will be loaded, but the rendering will be using the TrueType */ /* tables. */ - /* 3) The sfnts array is expected to be ASCII, not binary. */ - /* 4) As for Type1 fonts, CDevProc is not supported. */ - /* 5) The Metrics dictionary is not supported. */ - /* 6) AFM metrics are not supported. */ + /* 3) As for Type1 fonts, CDevProc is not supported. */ + /* 4) The Metrics dictionary is not supported. */ + /* 5) AFM metrics are not supported. */ /* */ /* In other words, this driver supports Type42 fonts derived from */ /* TrueType fonts in a non-CID manner, as done by usual conversion */ @@ -41,11 +40,21 @@ #include "t42error.h" #include FT_INTERNAL_DEBUG_H +#include FT_SERVICE_XFREE86_NAME_H +#include FT_SERVICE_GLYPH_DICT_H +#include FT_SERVICE_POSTSCRIPT_NAME_H +#include FT_SERVICE_POSTSCRIPT_INFO_H #undef FT_COMPONENT #define FT_COMPONENT trace_t42 + /* + * + * GLYPH DICT SERVICE + * + */ + static FT_Error t42_get_glyph_name( T42_Face face, FT_UInt glyph_index, @@ -73,13 +82,6 @@ } - static const char* - t42_get_ps_name( T42_Face face ) - { - return (const char*)face->type1.font_name; - } - - static FT_UInt t42_get_name_index( T42_Face face, FT_String* glyph_name ) @@ -93,40 +95,102 @@ gname = face->type1.glyph_names[i]; if ( !ft_strcmp( glyph_name, gname ) ) - return ft_atoi( (const char *)face->type1.charstrings[i] ); + return (FT_UInt)ft_atol( (const char *)face->type1.charstrings[i] ); } return 0; } + static const FT_Service_GlyphDictRec t42_service_glyph_dict = + { + (FT_GlyphDict_GetNameFunc) t42_get_glyph_name, + (FT_GlyphDict_NameIndexFunc)t42_get_name_index + }; + + + /* + * + * POSTSCRIPT NAME SERVICE + * + */ + + static const char* + t42_get_ps_font_name( T42_Face face ) + { + return (const char*)face->type1.font_name; + } + + + static const FT_Service_PsFontNameRec t42_service_ps_font_name = + { + (FT_PsName_GetFunc)t42_get_ps_font_name + }; + + + /* + * + * POSTSCRIPT INFO SERVICE + * + */ + + static FT_Error + t42_ps_get_font_info( FT_Face face, + PS_FontInfoRec* afont_info ) + { + *afont_info = ((T42_Face)face)->type1.font_info; + return 0; + } + + + static FT_Int + t42_ps_has_glyph_names( FT_Face face ) + { + FT_UNUSED( face ); + return 1; + } + + + static const FT_Service_PsInfoRec t42_service_ps_info = + { + (PS_GetFontInfoFunc) t42_ps_get_font_info, + (PS_HasGlyphNamesFunc)t42_ps_has_glyph_names + }; + + + /* + * + * SERVICE LIST + * + */ + + static const FT_ServiceDescRec t42_services[] = + { + { FT_SERVICE_ID_GLYPH_DICT, &t42_service_glyph_dict }, + { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &t42_service_ps_font_name }, + { FT_SERVICE_ID_POSTSCRIPT_INFO, &t42_service_ps_info }, + { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TYPE_42 }, + { NULL, NULL } + }; + + static FT_Module_Interface T42_Get_Interface( FT_Driver driver, const FT_String* t42_interface ) { FT_UNUSED( driver ); - /* Any additional interface are defined here */ - if (ft_strcmp( (const char*)t42_interface, "glyph_name" ) == 0 ) - return (FT_Module_Interface)t42_get_glyph_name; - - if ( ft_strcmp( (const char*)t42_interface, "name_index" ) == 0 ) - return (FT_Module_Interface)t42_get_name_index; - - if ( ft_strcmp( (const char*)t42_interface, "postscript_name" ) == 0 ) - return (FT_Module_Interface)t42_get_ps_name; - - return 0; + return ft_service_list_lookup( t42_services, t42_interface ); } const FT_Driver_ClassRec t42_driver_class = { { - ft_module_font_driver | - ft_module_driver_scalable | + FT_MODULE_FONT_DRIVER | + FT_MODULE_DRIVER_SCALABLE | #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - ft_module_driver_has_hinter, + FT_MODULE_DRIVER_HAS_HINTER, #else 0, #endif @@ -166,4 +230,4 @@ }; -/* END */ +/* END */ diff --git a/src/libs/freetype2/type42/t42drivr.h b/src/libs/freetype2/type42/t42drivr.h index 69f80447ae..98b7410b67 100644 --- a/src/libs/freetype2/type42/t42drivr.h +++ b/src/libs/freetype2/type42/t42drivr.h @@ -35,4 +35,4 @@ FT_END_HEADER #endif /* __T42DRIVR_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/type42/t42error.h b/src/libs/freetype2/type42/t42error.h index e1dc4e5161..b230910012 100644 --- a/src/libs/freetype2/type42/t42error.h +++ b/src/libs/freetype2/type42/t42error.h @@ -4,7 +4,7 @@ /* */ /* Type 42 error codes (specification only). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -30,11 +30,11 @@ #undef __FTERRORS_H__ #define FT_ERR_PREFIX T42_Err_ -#define FT_ERR_BASE FT_Mod_Err_T42 +#define FT_ERR_BASE FT_Mod_Err_Type42 #include FT_ERRORS_H #endif /* __T42ERROR_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/type42/t42objs.c b/src/libs/freetype2/type42/t42objs.c index cbe2f34aaa..8837136ff2 100644 --- a/src/libs/freetype2/type42/t42objs.c +++ b/src/libs/freetype2/type42/t42objs.c @@ -4,7 +4,7 @@ /* */ /* Type 42 objects manager (body). */ /* */ -/* Copyright 2002 by Roberto Alameda. */ +/* Copyright 2002, 2003, 2004 by Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -53,7 +53,8 @@ if ( error ) goto Exit; - error = t42_parse_dict( face, &loader, parser->base_dict, parser->base_len ); + error = t42_parse_dict( face, &loader, + parser->base_dict, parser->base_len ); if ( type1->font_type != 42 ) { @@ -65,7 +66,8 @@ /* to the Type1 data */ type1->num_glyphs = loader.num_glyphs; - if ( !loader.charstrings.init ) { + if ( !loader.charstrings.init ) + { FT_ERROR(( "T42_Open_Face: no charstrings array in face!\n" )); error = T42_Err_Invalid_File_Format; } @@ -121,8 +123,10 @@ if ( ft_strcmp( (const char*)".notdef", (const char*)glyph_name ) != 0 ) { - if ( charcode < min_char ) min_char = charcode; - if ( charcode > max_char ) max_char = charcode; + if ( charcode < min_char ) + min_char = charcode; + if ( charcode > max_char ) + max_char = charcode; } break; } @@ -149,10 +153,12 @@ FT_Int num_params, FT_Parameter* params ) { - FT_Error error; - PSNames_Service psnames; - PSAux_Service psaux; - FT_Face root = (FT_Face)&face->root; + FT_Error error; + FT_Service_PsCMaps psnames; + PSAux_Service psaux; + FT_Face root = (FT_Face)&face->root; + T1_Font type1 = &face->type1; + PS_FontInfo info = &type1->font_info; FT_UNUSED( num_params ); FT_UNUSED( params ); @@ -163,9 +169,8 @@ face->ttf_face = NULL; face->root.num_faces = 1; - face->psnames = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), - "psnames" ); - psnames = (PSNames_Service)face->psnames; + FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); + face->psnames = psnames; face->psaux = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), "psaux" ); @@ -188,12 +193,12 @@ goto Exit; } - /* Now, load the font program into the face object */ + /* Now load the font program into the face object */ /* Init the face object fields */ /* Now set up root face fields */ - root->num_glyphs = face->type1.num_glyphs; + root->num_glyphs = type1->num_glyphs; root->num_charmaps = 0; root->face_index = face_index; @@ -201,42 +206,52 @@ root->face_flags |= FT_FACE_FLAG_HORIZONTAL; root->face_flags |= FT_FACE_FLAG_GLYPH_NAMES; - if ( face->type1.font_info.is_fixed_pitch ) + if ( info->is_fixed_pitch ) root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; /* XXX: TODO -- add kerning with .afm support */ /* get style name -- be careful, some broken fonts only */ /* have a `/FontName' dictionary entry! */ - root->family_name = face->type1.font_info.family_name; + root->family_name = info->family_name; + /* assume "Regular" style if we don't know better */ + root->style_name = (char *)"Regular"; if ( root->family_name ) { - char* full = face->type1.font_info.full_name; + char* full = info->full_name; char* family = root->family_name; if ( full ) { - while ( *family && *full == *family ) + while ( *full ) { - family++; - full++; + if ( *full == *family ) + { + family++; + full++; + } + else + { + if ( *full == ' ' || *full == '-' ) + full++; + else if ( *family == ' ' || *family == '-' ) + family++; + else + { + if ( !*family ) + root->style_name = full; + break; + } + } } - - root->style_name = ( *full == ' ' ? full + 1 - : (char *)"Regular" ); } - else - root->style_name = (char *)"Regular"; } else { /* do we have a `/FontName'? */ - if ( face->type1.font_name ) - { - root->family_name = face->type1.font_name; - root->style_name = (char *)"Regular"; - } + if ( type1->font_name ) + root->family_name = type1->font_name; } /* no embedded bitmap support */ @@ -266,15 +281,15 @@ root->max_advance_width = face->ttf_face->max_advance_width; root->max_advance_height = face->ttf_face->max_advance_height; - root->underline_position = face->type1.font_info.underline_position; - root->underline_thickness = face->type1.font_info.underline_thickness; + root->underline_position = (FT_Short)info->underline_position; + root->underline_thickness = (FT_Short)info->underline_thickness; root->internal->max_points = 0; root->internal->max_contours = 0; /* compute style flags */ root->style_flags = 0; - if ( face->type1.font_info.italic_angle ) + if ( info->italic_angle ) root->style_flags |= FT_STYLE_FLAG_ITALIC; if ( face->ttf_face->style_flags & FT_STYLE_FLAG_BOLD ) @@ -304,7 +319,7 @@ charmap.platform_id = 7; clazz = NULL; - switch ( face->type1.encoding_type ) + switch ( type1->encoding_type ) { case T1_ENCODING_TYPE_STANDARD: charmap.encoding = FT_ENCODING_ADOBE_STANDARD; @@ -339,7 +354,7 @@ #if 0 /* Select default charmap */ - if (root->num_charmaps) + if ( root->num_charmaps ) root->charmap = root->charmaps[0]; #endif } @@ -438,8 +453,6 @@ } - - FT_LOCAL_DEF( FT_Error ) T42_Size_Init( T42_Size size ) { @@ -532,7 +545,7 @@ T42_Face t42face = (T42_Face)face; - FT_Activate_Size(size->ttsize); + FT_Activate_Size( size->ttsize ); return FT_Set_Char_Size( t42face->ttf_face, char_width, @@ -551,7 +564,7 @@ T42_Face t42face = (T42_Face)face; - FT_Activate_Size(size->ttsize); + FT_Activate_Size( size->ttsize ); return FT_Set_Pixel_Sizes( t42face->ttf_face, pixel_width, @@ -587,7 +600,7 @@ FT_LOCAL_DEF( FT_Error ) T42_GlyphSlot_Load( FT_GlyphSlot glyph, FT_Size size, - FT_Int glyph_index, + FT_UInt glyph_index, FT_Int32 load_flags ) { FT_Error error; @@ -627,4 +640,4 @@ } -/* END */ +/* END */ diff --git a/src/libs/freetype2/type42/t42objs.h b/src/libs/freetype2/type42/t42objs.h index ab16b34621..623809573e 100644 --- a/src/libs/freetype2/type42/t42objs.h +++ b/src/libs/freetype2/type42/t42objs.h @@ -4,7 +4,7 @@ /* */ /* Type 42 objects manager (specification). */ /* */ -/* Copyright 2002 by Roberto Alameda. */ +/* Copyright 2002, 2003 by Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -22,10 +22,10 @@ #include FT_FREETYPE_H #include FT_TYPE1_TABLES_H #include FT_INTERNAL_TYPE1_TYPES_H -#include FT_INTERNAL_TYPE42_TYPES_H +#include "t42types.h" #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DRIVER_H -#include FT_INTERNAL_POSTSCRIPT_NAMES_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H #include FT_INTERNAL_POSTSCRIPT_HINTS_H @@ -102,7 +102,7 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) T42_GlyphSlot_Load( FT_GlyphSlot glyph, FT_Size size, - FT_Int glyph_index, + FT_UInt glyph_index, FT_Int32 load_flags ); FT_LOCAL( void ) @@ -123,4 +123,4 @@ FT_END_HEADER #endif /* __T42OBJS_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/type42/t42parse.c b/src/libs/freetype2/type42/t42parse.c index ab286ad7ff..ff53a3eb44 100644 --- a/src/libs/freetype2/type42/t42parse.c +++ b/src/libs/freetype2/type42/t42parse.c @@ -4,7 +4,7 @@ /* */ /* Type 42 font parser (body). */ /* */ -/* Copyright 2002 by Roberto Alameda. */ +/* Copyright 2002, 2003, 2004 by Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -33,25 +33,17 @@ #define FT_COMPONENT trace_t42 - static void - t42_parse_font_name( T42_Face face, - T42_Loader loader ); - - static void - t42_parse_font_bbox( T42_Face face, - T42_Loader loader ); - static void t42_parse_font_matrix( T42_Face face, T42_Loader loader ); static void t42_parse_encoding( T42_Face face, T42_Loader loader ); - + static void t42_parse_charstrings( T42_Face face, T42_Loader loader ); - + static void t42_parse_sfnts( T42_Face face, T42_Loader loader ); @@ -65,27 +57,33 @@ #undef T1CODE #define T1CODE T1_FIELD_LOCATION_FONT_INFO - T1_FIELD_STRING ( "version", version ) - T1_FIELD_STRING ( "Notice", notice ) - T1_FIELD_STRING ( "FullName", full_name ) - T1_FIELD_STRING ( "FamilyName", family_name ) - T1_FIELD_STRING ( "Weight", weight ) - T1_FIELD_NUM ( "ItalicAngle", italic_angle ) - T1_FIELD_TYPE_BOOL( "isFixedPitch", is_fixed_pitch ) - T1_FIELD_NUM ( "UnderlinePosition", underline_position ) - T1_FIELD_NUM ( "UnderlineThickness", underline_thickness ) + T1_FIELD_STRING( "version", version ) + T1_FIELD_STRING( "Notice", notice ) + T1_FIELD_STRING( "FullName", full_name ) + T1_FIELD_STRING( "FamilyName", family_name ) + T1_FIELD_STRING( "Weight", weight ) + T1_FIELD_NUM ( "ItalicAngle", italic_angle ) + T1_FIELD_BOOL ( "isFixedPitch", is_fixed_pitch ) + T1_FIELD_NUM ( "UnderlinePosition", underline_position ) + T1_FIELD_NUM ( "UnderlineThickness", underline_thickness ) #undef FT_STRUCTURE #define FT_STRUCTURE T1_FontRec #undef T1CODE #define T1CODE T1_FIELD_LOCATION_FONT_DICT - T1_FIELD_NUM( "PaintType", paint_type ) - T1_FIELD_NUM( "FontType", font_type ) - T1_FIELD_NUM( "StrokeWidth", stroke_width ) + T1_FIELD_KEY ( "FontName", font_name ) + T1_FIELD_NUM ( "PaintType", paint_type ) + T1_FIELD_NUM ( "FontType", font_type ) + T1_FIELD_FIXED( "StrokeWidth", stroke_width ) + +#undef FT_STRUCTURE +#define FT_STRUCTURE FT_BBox +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_BBOX + + T1_FIELD_BBOX("FontBBox", xMin ) - T1_FIELD_CALLBACK( "FontName", t42_parse_font_name ) - T1_FIELD_CALLBACK( "FontBBox", t42_parse_font_bbox ) T1_FIELD_CALLBACK( "FontMatrix", t42_parse_font_matrix ) T1_FIELD_CALLBACK( "Encoding", t42_parse_encoding ) T1_FIELD_CALLBACK( "CharStrings", t42_parse_charstrings ) @@ -109,20 +107,18 @@ (p)->funcs.release( p ); \ } while ( 0 ) -#define T1_Skip_Spaces( p ) (p)->root.funcs.skip_spaces( &(p)->root ) -#define T1_Skip_Alpha( p ) (p)->root.funcs.skip_alpha ( &(p)->root ) +#define T1_Skip_Spaces( p ) (p)->root.funcs.skip_spaces( &(p)->root ) +#define T1_Skip_PS_Token( p ) (p)->root.funcs.skip_PS_token( &(p)->root ) -#define T1_ToInt( p ) (p)->root.funcs.to_int( &(p)->root ) -#define T1_ToFixed( p, t ) (p)->root.funcs.to_fixed( &(p)->root, t ) +#define T1_ToInt( p ) \ + (p)->root.funcs.to_int( &(p)->root ) +#define T1_ToBytes( p, b, m, n, d ) \ + (p)->root.funcs.to_bytes( &(p)->root, b, m, n, d ) -#define T1_ToCoordArray( p, m, c ) \ - (p)->root.funcs.to_coord_array( &(p)->root, m, c ) #define T1_ToFixedArray( p, m, f, t ) \ (p)->root.funcs.to_fixed_array( &(p)->root, m, f, t ) #define T1_ToToken( p, t ) \ (p)->root.funcs.to_token( &(p)->root, t ) -#define T1_ToTokenArray( p, t, m, c ) \ - (p)->root.funcs.to_token_array( &(p)->root, t, m, c ) #define T1_Load_Field( p, f, o, m, pf ) \ (p)->root.funcs.load_field( &(p)->root, f, o, m, pf ) @@ -156,8 +152,8 @@ /* When creating a new Type 42 parser, we try to locate and load */ /* the base dictionary, loading the whole font into memory. */ /* */ - /* When `loading' the base dictionary, we only setup pointers in */ - /* the case of a memory-based stream. Otherwise, we allocate */ + /* When `loading' the base dictionary, we only set up pointers */ + /* in the case of a memory-based stream. Otherwise, we allocate */ /* and load the base dictionary in it. */ /* */ /* parser->in_memory is set if we have a memory stream. */ @@ -193,9 +189,9 @@ } /* Now check font format; we must see `%!PS-TrueTypeFont' */ - if (size <= 17 || - ( ft_strncmp( (const char*)parser->base_dict, - "%!PS-TrueTypeFont", 17) ) ) + if ( size <= 17 || + ( ft_strncmp( (const char*)parser->base_dict, + "%!PS-TrueTypeFont", 17 ) ) ) error = T42_Err_Unknown_File_Format; else { @@ -226,81 +222,12 @@ } - static int - t42_is_alpha( FT_Byte c ) - { - /* Note: we must accept "+" as a valid character, as it is used in */ - /* embedded type1 fonts in PDF documents. */ - /* */ - return ( ft_isalnum( c ) || - c == '.' || - c == '_' || - c == '-' || - c == '+' ); - } - - static int t42_is_space( FT_Byte c ) { - return ( c == ' ' || c == '\t' || c == '\r' || c == '\n' ); - } - - - static void - t42_parse_font_name( T42_Face face, - T42_Loader loader ) - { - T42_Parser parser = &loader->parser; - FT_Error error; - FT_Memory memory = parser->root.memory; - FT_Int len; - FT_Byte* cur; - FT_Byte* cur2; - FT_Byte* limit; - - - T1_Skip_Spaces( parser ); - - cur = parser->root.cursor; - limit = parser->root.limit; - - if ( cur >= limit - 1 || - ( *cur != '/' && *cur != '(') ) - return; - - cur++; - cur2 = cur; - while ( cur2 < limit && t42_is_alpha( *cur2 ) ) - cur2++; - - len = (FT_Int)( cur2 - cur ); - if ( len > 0 ) - { - if ( FT_ALLOC( face->type1.font_name, len + 1 ) ) - { - parser->root.error = error; - return; - } - - FT_MEM_COPY( face->type1.font_name, cur, len ); - face->type1.font_name[len] = '\0'; - } - parser->root.cursor = cur2; - } - - - static void - t42_parse_font_bbox( T42_Face face, - T42_Loader loader ) - { - T42_Parser parser = &loader->parser; - FT_BBox* bbox = &face->type1.font_bbox; - - bbox->xMin = T1_ToInt( parser ); - bbox->yMin = T1_ToInt( parser ); - bbox->xMax = T1_ToInt( parser ); - bbox->yMax = T1_ToInt( parser ); + return ( c == ' ' || c == '\t' || + c == '\r' || c == '\n' || c == '\f' || + c == '\0' ); } @@ -318,7 +245,7 @@ (void)T1_ToFixedArray( parser, 6, temp, 3 ); - temp_scale = ABS( temp[3] ); + temp_scale = FT_ABS( temp[3] ); /* Set Units per EM based on FontMatrix values. We set the value to */ /* 1000 / temp_scale, because temp_scale was already multiplied by */ @@ -343,8 +270,8 @@ matrix->yy = temp[3]; /* note that the offsets must be expressed in integer font units */ - offset->x = temp[4] >> 16; - offset->y = temp[5] >> 16; + offset->x = temp[4] >> 16; + offset->y = temp[5] >> 16; } @@ -352,45 +279,52 @@ t42_parse_encoding( T42_Face face, T42_Loader loader ) { - T42_Parser parser = &loader->parser; - FT_Byte* cur = parser->root.cursor; - FT_Byte* limit = parser->root.limit; + T42_Parser parser = &loader->parser; + FT_Byte* cur; + FT_Byte* limit = parser->root.limit; PSAux_Service psaux = (PSAux_Service)face->psaux; - /* skip whitespace */ - while ( t42_is_space( *cur ) ) + T1_Skip_Spaces( parser ); + cur = parser->root.cursor; + if ( cur >= limit ) { - cur++; - if ( cur >= limit ) - { - FT_ERROR(( "t42_parse_encoding: out of bounds!\n" )); - parser->root.error = T42_Err_Invalid_File_Format; - return; - } + FT_ERROR(( "t42_parse_encoding: out of bounds!\n" )); + parser->root.error = T42_Err_Invalid_File_Format; + return; } - /* if we have a number, then the encoding is an array, */ - /* and we must load it now */ - if ( (FT_Byte)( *cur - '0' ) < 10 ) + /* if we have a number or `[', the encoding is an array, */ + /* and we must load it now */ + if ( ft_isdigit( *cur ) || *cur == '[' ) { - T1_Encoding encode = &face->type1.encoding; - FT_Int count, n; - PS_Table char_table = &loader->encoding_table; - FT_Memory memory = parser->root.memory; + T1_Encoding encode = &face->type1.encoding; + FT_UInt count, n; + PS_Table char_table = &loader->encoding_table; + FT_Memory memory = parser->root.memory; FT_Error error; + FT_Bool only_immediates = 0; - /* read the number of entries in the encoding, should be 256 */ - count = T1_ToInt( parser ); - if ( parser->root.error ) + /* read the number of entries in the encoding; should be 256 */ + if ( *cur == '[' ) + { + count = 256; + only_immediates = 1; + parser->root.cursor++; + } + else + count = (FT_UInt)T1_ToInt( parser ); + + T1_Skip_Spaces( parser ); + if ( parser->root.cursor >= limit ) return; /* we use a T1_Table to store our charnames */ loader->num_chars = encode->num_chars = count; - if ( FT_NEW_ARRAY( encode->char_index, count ) || - FT_NEW_ARRAY( encode->char_name, count ) || + if ( FT_NEW_ARRAY( encode->char_index, count ) || + FT_NEW_ARRAY( encode->char_name, count ) || FT_SET_ERROR( psaux->ps_table_funcs->init( char_table, count, memory ) ) ) { @@ -407,86 +341,99 @@ T1_Add_Table( char_table, n, notdef, 8 ); } - /* Now, we will need to read a record of the form */ - /* ... charcode /charname ... for each entry in our table */ + /* Now we need to read records of the form */ + /* */ + /* ... charcode /charname ... */ + /* */ + /* for each entry in our table. */ /* */ /* We simply look for a number followed by an immediate */ /* name. Note that this ignores correctly the sequence */ - /* that is often seen in type1 fonts: */ + /* that is often seen in type42 fonts: */ /* */ /* 0 1 255 { 1 index exch /.notdef put } for dup */ /* */ /* used to clean the encoding array before anything else. */ /* */ - /* We stop when we encounter a `def'. */ + /* Alternatively, if the array is directly given as */ + /* */ + /* /Encoding [ ... ] */ + /* */ + /* we only read immediates. */ - cur = parser->root.cursor; - limit = parser->root.limit; - n = 0; + n = 0; + T1_Skip_Spaces( parser ); - for ( ; cur < limit; ) + while ( parser->root.cursor < limit ) { - FT_Byte c; + cur = parser->root.cursor; - - c = *cur; - - /* we stop when we encounter a `def' */ - if ( c == 'd' && cur + 3 < limit ) + /* we stop when we encounter `def' or `]' */ + if ( *cur == 'd' && cur + 3 < limit ) { - if ( cur[1] == 'e' && - cur[2] == 'f' && - t42_is_space( cur[-1] ) && - t42_is_space( cur[3] ) ) + if ( cur[1] == 'e' && + cur[2] == 'f' && + t42_is_space( cur[3] ) ) { FT_TRACE6(( "encoding end\n" )); + cur += 3; break; } } + if ( *cur == ']' ) + { + FT_TRACE6(( "encoding end\n" )); + cur++; + break; + } - /* otherwise, we must find a number before anything else */ - if ( (FT_Byte)( c - '0' ) < 10 ) + /* check whether we've found an entry */ + if ( ft_isdigit( *cur ) || only_immediates ) { FT_Int charcode; - parser->root.cursor = cur; - charcode = T1_ToInt( parser ); - cur = parser->root.cursor; + if ( only_immediates ) + charcode = n; + else + { + charcode = (FT_Int)T1_ToInt( parser ); + T1_Skip_Spaces( parser ); + } + + cur = parser->root.cursor; + + if ( *cur == '/' && cur + 2 < limit && n < count ) + { + FT_PtrDist len; + - /* skip whitespace */ - while ( cur < limit && t42_is_space( *cur ) ) cur++; - if ( cur < limit && *cur == '/' ) - { - /* bingo, we have an immediate name -- it must be a */ - /* character name */ - FT_Byte* cur2 = cur + 1; - FT_Int len; + parser->root.cursor = cur; + T1_Skip_PS_Token( parser ); - - while ( cur2 < limit && t42_is_alpha( *cur2 ) ) - cur2++; - - len = (FT_Int)( cur2 - cur - 1 ); + len = parser->root.cursor - cur; parser->root.error = T1_Add_Table( char_table, charcode, - cur + 1, len + 1 ); + cur, len + 1 ); char_table->elements[charcode][len] = '\0'; if ( parser->root.error ) return; - cur = cur2; + n++; } } else - cur++; + T1_Skip_PS_Token( parser ); + + T1_Skip_Spaces( parser ); } face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY; parser->root.cursor = cur; } + /* Otherwise, we should have either `StandardEncoding', */ /* `ExpertEncoding', or `ISOLatin1Encoding' */ else @@ -503,7 +450,8 @@ ft_strncmp( (const char*)cur, "ISOLatin1Encoding", 17 ) == 0 ) face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1; - else { + else + { FT_ERROR(( "t42_parse_encoding: invalid token!\n" )); parser->root.error = T42_Err_Invalid_File_Format; } @@ -511,34 +459,13 @@ } - static FT_UInt - t42_hexval( FT_Byte v ) + typedef enum { - FT_UInt d; - - d = (FT_UInt)( v - 'A' ); - if ( d < 6 ) - { - d += 10; - goto Exit; - } - - d = (FT_UInt)( v - 'a' ); - if ( d < 6 ) - { - d += 10; - goto Exit; - } - - d = (FT_UInt)( v - '0' ); - if ( d < 10 ) - goto Exit; - - d = 0; - - Exit: - return d; - } + BEFORE_START, + BEFORE_TABLE_DIR, + OTHER_TABLES + + } T42_Load_Status; static void @@ -547,154 +474,177 @@ { T42_Parser parser = &loader->parser; FT_Memory memory = parser->root.memory; - FT_Byte* cur = parser->root.cursor; + FT_Byte* cur; FT_Byte* limit = parser->root.limit; FT_Error error; - FT_Int num_tables = 0, status; - FT_ULong count, ttf_size = 0, string_size = 0; - FT_Bool in_string = 0; - FT_Byte v = 0; + FT_Int num_tables = 0; + FT_ULong count, ttf_size = 0; + + FT_Long n, string_size, old_string_size, real_size; + FT_Byte* string_buf = NULL; + FT_Bool alloc = 0; + + T42_Load_Status status; - /* The format is `/sfnts [ <...> <...> ... ] def' */ + /* The format is */ + /* */ + /* /sfnts [ ... ] def */ + /* */ + /* or */ + /* */ + /* /sfnts [ */ + /* RD */ + /* RD */ + /* ... */ + /* ] def */ + /* */ + /* with exactly one space after the `RD' token. */ - while ( t42_is_space( *cur ) ) - cur++; + T1_Skip_Spaces( parser ); - if (*cur++ == '[') - { - status = 0; - count = 0; - } - else + if ( parser->root.cursor >= limit || *parser->root.cursor++ != '[' ) { FT_ERROR(( "t42_parse_sfnts: can't find begin of sfnts vector!\n" )); error = T42_Err_Invalid_File_Format; goto Fail; } - while ( cur < limit - 2 ) + T1_Skip_Spaces( parser ); + status = BEFORE_START; + string_size = 0; + old_string_size = 0; + count = 0; + + while ( parser->root.cursor < limit ) { - while ( t42_is_space( *cur ) ) - cur++; + cur = parser->root.cursor; - switch ( *cur ) + if ( *cur == ']' ) { - case ']': - parser->root.cursor = cur++; - return; - - case '<': - in_string = 1; - string_size = 0; - cur++; - continue; - - case '>': - if ( !in_string ) - { - FT_ERROR(( "t42_parse_sfnts: found unpaired `>'!\n" )); - error = T42_Err_Invalid_File_Format; - goto Fail; - } - - /* A string can have, as a last byte, */ - /* a zero byte for padding. If so, ignore it */ - if ( ( v == 0 ) && ( string_size % 2 == 1 ) ) - count--; - in_string = 0; - cur++; - continue; - - case '%': - if ( !in_string ) - { - /* Comment found; skip till end of line */ - while ( *cur != '\n' ) - cur++; - continue; - } - else - { - FT_ERROR(( "t42_parse_sfnts: found `%' in string!\n" )); - error = T42_Err_Invalid_File_Format; - goto Fail; - } - - default: - if ( !ft_xdigit( *cur ) || !ft_xdigit( *(cur + 1) ) ) - { - FT_ERROR(( "t42_parse_sfnts: found non-hex characters in string" )); - error = T42_Err_Invalid_File_Format; - goto Fail; - } - - v = (FT_Byte)( 16 * t42_hexval( cur[0] ) + t42_hexval( cur[1] ) ); - cur += 2; - string_size++; + parser->root.cursor++; + goto Exit; } - switch ( status ) + else if ( *cur == '<' ) { - case 0: /* The '[' was read, so load offset table, 12 bytes */ - if ( count < 12 ) + T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + goto Exit; + + /* don't include delimiters */ + string_size = (FT_Long)( ( parser->root.cursor - cur - 2 + 1 ) / 2 ); + if ( FT_REALLOC( string_buf, old_string_size, string_size ) ) + goto Fail; + + alloc = 1; + + parser->root.cursor = cur; + (void)T1_ToBytes( parser, string_buf, string_size, &real_size, 1 ); + old_string_size = string_size; + string_size = real_size; + } + + else if ( ft_isdigit( *cur ) ) + { + string_size = T1_ToInt( parser ); + + T1_Skip_PS_Token( parser ); /* `RD' */ + + string_buf = parser->root.cursor + 1; /* one space after `RD' */ + + parser->root.cursor += string_size + 1; + if ( parser->root.cursor >= limit ) { - face->ttf_data[count++] = v; - continue; + FT_ERROR(( "t42_parse_sfnts: too many binary data!\n" )); + error = T42_Err_Invalid_File_Format; + goto Fail; } - else + } + + /* A string can have a trailing zero byte for padding. Ignore it. */ + if ( string_buf[string_size - 1] == 0 && ( string_size % 2 == 1 ) ) + string_size--; + + for ( n = 0; n < string_size; n++ ) + { + switch ( status ) { - num_tables = 16 * face->ttf_data[4] + face->ttf_data[5]; - status = 1; - ttf_size = 12 + 16 * num_tables; - - if ( FT_REALLOC( face->ttf_data, 12, ttf_size ) ) - goto Fail; - } - /* No break, fall-through */ - - case 1: /* The offset table is read; read now the table directory */ - if ( count < ttf_size ) - { - face->ttf_data[count++] = v; - continue; - } - else - { - int i; - FT_ULong len; - - - for ( i = 0; i < num_tables; i++ ) + case BEFORE_START: + /* load offset table, 12 bytes */ + if ( count < 12 ) { - FT_Byte* p = face->ttf_data + 12 + 16*i + 12; - - len = FT_PEEK_ULONG( p ); - - /* Pad to a 4-byte boundary length */ - ttf_size += ( len + 3 ) & ~3; + face->ttf_data[count++] = string_buf[n]; + continue; } + else + { + num_tables = 16 * face->ttf_data[4] + face->ttf_data[5]; + status = BEFORE_TABLE_DIR; + ttf_size = 12 + 16 * num_tables; - status = 2; - face->ttf_size = ttf_size; + if ( FT_REALLOC( face->ttf_data, 12, ttf_size ) ) + goto Fail; + } + /* fall through */ - if ( FT_REALLOC( face->ttf_data, 12 + 16 * num_tables, - ttf_size + 1 ) ) + case BEFORE_TABLE_DIR: + /* the offset table is read; read the table directory */ + if ( count < ttf_size ) + { + face->ttf_data[count++] = string_buf[n]; + continue; + } + else + { + int i; + FT_ULong len; + + + for ( i = 0; i < num_tables; i++ ) + { + FT_Byte* p = face->ttf_data + 12 + 16 * i + 12; + + + len = FT_PEEK_ULONG( p ); + + /* Pad to a 4-byte boundary length */ + ttf_size += ( len + 3 ) & ~3; + } + + status = OTHER_TABLES; + face->ttf_size = ttf_size; + + if ( FT_REALLOC( face->ttf_data, 12 + 16 * num_tables, + ttf_size + 1 ) ) + goto Fail; + } + /* fall through */ + + case OTHER_TABLES: + /* all other tables are just copied */ + if ( count >= ttf_size ) + { + FT_ERROR(( "t42_parse_sfnts: too many binary data!\n" )); + error = T42_Err_Invalid_File_Format; goto Fail; + } + face->ttf_data[count++] = string_buf[n]; } - /* No break, fall-through */ - - case 2: /* We are reading normal tables; just swallow them */ - face->ttf_data[count++] = v; - } + + T1_Skip_Spaces( parser ); } - /* If control reaches this point, the format was not valid */ + /* if control reaches this point, the format was not valid */ error = T42_Err_Invalid_File_Format; Fail: parser->root.error = error; + + Exit: + if ( alloc ) + FT_FREE( string_buf ); } @@ -702,22 +652,75 @@ t42_parse_charstrings( T42_Face face, T42_Loader loader ) { - T42_Parser parser = &loader->parser; - PS_Table code_table = &loader->charstrings; - PS_Table name_table = &loader->glyph_names; - FT_Memory memory = parser->root.memory; + T42_Parser parser = &loader->parser; + PS_Table code_table = &loader->charstrings; + PS_Table name_table = &loader->glyph_names; + PS_Table swap_table = &loader->swap_table; + FT_Memory memory = parser->root.memory; FT_Error error; - PSAux_Service psaux = (PSAux_Service)face->psaux; + PSAux_Service psaux = (PSAux_Service)face->psaux; FT_Byte* cur; - FT_Byte* limit = parser->root.limit; - FT_Int n; + FT_Byte* limit = parser->root.limit; + FT_UInt n; + FT_UInt notdef_index = 0; + FT_Byte notdef_found = 0; - loader->num_glyphs = T1_ToInt( parser ); - if ( parser->root.error ) - return; + T1_Skip_Spaces( parser ); + + if ( parser->root.cursor >= limit ) + { + FT_ERROR(( "t42_parse_charstrings: out of bounds!\n" )); + error = T42_Err_Invalid_File_Format; + goto Fail; + } + + if ( ft_isdigit( *parser->root.cursor ) ) + { + loader->num_glyphs = (FT_UInt)T1_ToInt( parser ); + if ( parser->root.error ) + return; + } + else if ( *parser->root.cursor == '<' ) + { + /* We have `<< ... >>'. Count the number of `/' in the dictionary */ + /* to get its size. */ + FT_UInt count = 0; + + + T1_Skip_PS_Token( parser ); + T1_Skip_Spaces( parser ); + cur = parser->root.cursor; + + while ( parser->root.cursor < limit ) + { + if ( *parser->root.cursor == '/' ) + count++; + else if ( *parser->root.cursor == '>' ) + { + loader->num_glyphs = count; + parser->root.cursor = cur; /* rewind */ + break; + } + T1_Skip_PS_Token( parser ); + T1_Skip_Spaces( parser ); + } + } + else + { + FT_ERROR(( "t42_parse_charstrings: invalid token!\n" )); + error = T42_Err_Invalid_File_Format; + goto Fail; + } + + if ( parser->root.cursor >= limit ) + { + FT_ERROR(( "t42_parse_charstrings: out of bounds!\n" )); + error = T42_Err_Invalid_File_Format; + goto Fail; + } /* initialize tables */ @@ -733,57 +736,82 @@ if ( error ) goto Fail; + /* Initialize table for swapping index notdef_index and */ + /* index 0 names and codes (if necessary). */ + + error = psaux->ps_table_funcs->init( swap_table, 4, memory ); + if ( error ) + goto Fail; + n = 0; for (;;) { - /* the format is simple: */ - /* `/glyphname' + index + def */ - /* */ - /* note that we stop when we find an `end' */ - /* */ + /* The format is simple: */ + /* `/glyphname' + index [+ def] */ + T1_Skip_Spaces( parser ); cur = parser->root.cursor; if ( cur >= limit ) break; - /* we stop when we find an `end' keyword */ - if ( *cur == 'e' && - cur + 3 < limit && - cur[1] == 'n' && - cur[2] == 'd' ) + /* We stop when we find an `end' keyword or '>' */ + if ( *cur == 'e' && + cur + 3 < limit && + cur[1] == 'n' && + cur[2] == 'd' && + t42_is_space( cur[3] ) ) + break; + if ( *cur == '>' ) break; - if ( *cur != '/' ) - T1_Skip_Alpha( parser ); - else + T1_Skip_PS_Token( parser ); + + if ( *cur == '/' ) { - FT_Byte* cur2 = cur + 1; - FT_Int len; + FT_PtrDist len; - while ( cur2 < limit && t42_is_alpha( *cur2 ) ) - cur2++; - len = (FT_Int)( cur2 - cur - 1 ); + if ( cur + 1 >= limit ) + { + FT_ERROR(( "t42_parse_charstrings: out of bounds!\n" )); + error = T42_Err_Invalid_File_Format; + goto Fail; + } - error = T1_Add_Table( name_table, n, cur + 1, len + 1 ); + cur++; /* skip `/' */ + len = parser->root.cursor - cur; + + error = T1_Add_Table( name_table, n, cur, len + 1 ); if ( error ) goto Fail; /* add a trailing zero to the name table */ name_table->elements[n][len] = '\0'; - parser->root.cursor = cur2; + /* record index of /.notdef */ + if ( *cur == '.' && + ft_strcmp( ".notdef", + (const char*)(name_table->elements[n]) ) == 0 ) + { + notdef_index = n; + notdef_found = 1; + } + T1_Skip_Spaces( parser ); - cur2 = cur = parser->root.cursor; - if ( cur >= limit ) - break; + cur = parser->root.cursor; - while ( cur2 < limit && t42_is_alpha( *cur2 ) ) - cur2++; - len = (FT_Int)( cur2 - cur ); + (void)T1_ToInt( parser ); + if ( parser->root.cursor >= limit ) + { + FT_ERROR(( "t42_parse_charstrings: out of bounds!\n" )); + error = T42_Err_Invalid_File_Format; + goto Fail; + } + + len = parser->root.cursor - cur; error = T1_Add_Table( code_table, n, cur, len + 1 ); if ( error ) @@ -797,15 +825,79 @@ } } - /* Index 0 must be a .notdef element */ - if ( ft_strcmp( (char *)name_table->elements[0], ".notdef" ) ) + loader->num_glyphs = n; + + if ( !notdef_found ) { - FT_ERROR(( "t42_parse_charstrings: Index 0 is not `.notdef'!\n" )); + FT_ERROR(( "t42_parse_charstrings: no /.notdef glyph!\n" )); error = T42_Err_Invalid_File_Format; goto Fail; } - loader->num_glyphs = n; + /* if /.notdef does not occupy index 0, do our magic. */ + if ( ft_strcmp( (const char*)".notdef", + (const char*)name_table->elements[0] ) ) + { + /* Swap glyph in index 0 with /.notdef glyph. First, add index 0 */ + /* name and code entries to swap_table. Then place notdef_index */ + /* name and code entries into swap_table. Then swap name and code */ + /* entries at indices notdef_index and 0 using values stored in */ + /* swap_table. */ + + /* Index 0 name */ + error = T1_Add_Table( swap_table, 0, + name_table->elements[0], + name_table->lengths [0] ); + if ( error ) + goto Fail; + + /* Index 0 code */ + error = T1_Add_Table( swap_table, 1, + code_table->elements[0], + code_table->lengths [0] ); + if ( error ) + goto Fail; + + /* Index notdef_index name */ + error = T1_Add_Table( swap_table, 2, + name_table->elements[notdef_index], + name_table->lengths [notdef_index] ); + if ( error ) + goto Fail; + + /* Index notdef_index code */ + error = T1_Add_Table( swap_table, 3, + code_table->elements[notdef_index], + code_table->lengths [notdef_index] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( name_table, notdef_index, + swap_table->elements[0], + swap_table->lengths [0] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( code_table, notdef_index, + swap_table->elements[1], + swap_table->lengths [1] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( name_table, 0, + swap_table->elements[2], + swap_table->lengths [2] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( code_table, 0, + swap_table->elements[3], + swap_table->lengths [3] ); + if ( error ) + goto Fail; + + } + return; Fail: @@ -825,26 +917,32 @@ /* if the keyword has a dedicated callback, call it */ - if ( field->type == T1_FIELD_TYPE_CALLBACK ) { + if ( field->type == T1_FIELD_TYPE_CALLBACK ) + { field->reader( (FT_Face)face, loader ); error = loader->parser.root.error; goto Exit; } - /* now, the keyword is either a simple field, or a table of fields; */ - /* we are now going to take care of it */ + /* now the keyword is either a simple field or a table of fields; */ + /* we are now going to take care of it */ + switch ( field->location ) { case T1_FIELD_LOCATION_FONT_INFO: dummy_object = &face->type1.font_info; - objects = &dummy_object; + break; + + case T1_FIELD_LOCATION_BBOX: + dummy_object = &face->type1.font_bbox; break; default: dummy_object = &face->type1; - objects = &dummy_object; } + objects = &dummy_object; + if ( field->type == T1_FIELD_TYPE_INTEGER_ARRAY || field->type == T1_FIELD_TYPE_FIXED_ARRAY ) error = T1_Load_Field_Table( &loader->parser, field, @@ -864,20 +962,28 @@ FT_Byte* base, FT_Long size ) { - T42_Parser parser = &loader->parser; - FT_Byte* cur = base; - FT_Byte* limit = cur + size; - FT_UInt n_keywords = sizeof ( t42_keywords ) / - sizeof ( t42_keywords[0] ); + T42_Parser parser = &loader->parser; + FT_Byte* limit; + FT_Int n_keywords = (FT_Int)( sizeof ( t42_keywords ) / + sizeof ( t42_keywords[0] ) ); parser->root.cursor = base; parser->root.limit = base + size; - parser->root.error = 0; + parser->root.error = T42_Err_Ok; - for ( ; cur < limit; cur++ ) + limit = parser->root.limit; + + T1_Skip_Spaces( parser ); + + while ( parser->root.cursor < limit ) { - /* look for `FontDirectory', which causes problems on some fonts */ + FT_Byte* cur; + + + cur = parser->root.cursor; + + /* look for `FontDirectory' which causes problems for some fonts */ if ( *cur == 'F' && cur + 25 < limit && ft_strncmp( (char*)cur, "FontDirectory", 13 ) == 0 ) { @@ -885,13 +991,21 @@ /* skip the `FontDirectory' keyword */ - cur += 13; - cur2 = cur; + T1_Skip_PS_Token( parser ); + T1_Skip_Spaces ( parser ); + cur = cur2 = parser->root.cursor; - /* lookup the `known' keyword */ - while ( cur < limit && *cur != 'k' && - ft_strncmp( (char*)cur, "known", 5 ) ) - cur++; + /* look up the `known' keyword */ + while ( cur < limit ) + { + if ( *cur == 'k' && cur + 5 < limit && + ft_strncmp( (char*)cur, "known", 5 ) == 0 ) + break; + + T1_Skip_PS_Token( parser ); + T1_Skip_Spaces ( parser ); + cur = parser->root.cursor; + } if ( cur < limit ) { @@ -899,34 +1013,37 @@ /* skip the `known' keyword and the token following it */ - cur += 5; - loader->parser.root.cursor = cur; - T1_ToToken( &loader->parser, &token ); + T1_Skip_PS_Token( parser ); + T1_ToToken( parser, &token ); /* if the last token was an array, skip it! */ if ( token.type == T1_TOKEN_TYPE_ARRAY ) cur2 = parser->root.cursor; } - cur = cur2; + parser->root.cursor = cur2; } + /* look for immediates */ else if ( *cur == '/' && cur + 2 < limit ) { - FT_Byte* cur2; - FT_UInt i, len; + FT_PtrDist len; cur++; - cur2 = cur; - while ( cur2 < limit && t42_is_alpha( *cur2 ) ) - cur2++; - len = (FT_UInt)( cur2 - cur ); - if ( len > 0 && len < 22 ) /* XXX What shall it this 22? */ + parser->root.cursor = cur; + T1_Skip_PS_Token( parser ); + + len = parser->root.cursor - cur; + + if ( len > 0 && len < 22 && parser->root.cursor < limit ) { - /* now, compare the immediate name to the keyword table */ + int i; - /* Loop through all known keywords */ + + /* now compare the immediate name to the keyword table */ + + /* loop through all known keywords */ for ( i = 0; i < n_keywords; i++ ) { T1_Field keyword = (T1_Field)&t42_keywords[i]; @@ -936,24 +1053,27 @@ if ( !name ) continue; - if ( ( len == ft_strlen( (const char *)name ) ) && - ( ft_memcmp( cur, name, len ) == 0 ) ) + if ( cur[0] == name[0] && + len == ft_strlen( (const char *)name ) && + ft_memcmp( cur, name, len ) == 0 ) { /* we found it -- run the parsing callback! */ - parser->root.cursor = cur2; - T1_Skip_Spaces( parser ); - parser->root.error = t42_load_keyword(face, - loader, - keyword ); + parser->root.error = t42_load_keyword( face, + loader, + keyword ); if ( parser->root.error ) return parser->root.error; - cur = parser->root.cursor; break; } } } } + else + T1_Skip_PS_Token( parser ); + + T1_Skip_Spaces( parser ); } + return parser->root.error; } @@ -985,10 +1105,11 @@ T1_Release_Table( &loader->encoding_table ); T1_Release_Table( &loader->charstrings ); T1_Release_Table( &loader->glyph_names ); + T1_Release_Table( &loader->swap_table ); /* finalize parser */ t42_parser_done( parser ); } -/* END */ +/* END */ diff --git a/src/libs/freetype2/type42/t42parse.h b/src/libs/freetype2/type42/t42parse.h index 8f45209cce..f77ec4af4f 100644 --- a/src/libs/freetype2/type42/t42parse.h +++ b/src/libs/freetype2/type42/t42parse.h @@ -4,7 +4,7 @@ /* */ /* Type 42 font parser (specification). */ /* */ -/* Copyright 2002 by Roberto Alameda. */ +/* Copyright 2002, 2003 by Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -31,9 +31,9 @@ FT_BEGIN_HEADER FT_Stream stream; FT_Byte* base_dict; - FT_Int base_len; + FT_Long base_len; - FT_Byte in_memory; + FT_Bool in_memory; } T42_ParserRec, *T42_Parser; @@ -42,13 +42,14 @@ FT_BEGIN_HEADER { T42_ParserRec parser; /* parser used to read the stream */ - FT_Int num_chars; /* number of characters in encoding */ + FT_UInt num_chars; /* number of characters in encoding */ PS_TableRec encoding_table; /* PS_Table used to store the */ /* encoding character names */ - FT_Int num_glyphs; + FT_UInt num_glyphs; PS_TableRec glyph_names; PS_TableRec charstrings; + PS_TableRec swap_table; /* For moving .notdef glyph to index 0. */ } T42_LoaderRec, *T42_Loader; @@ -86,4 +87,4 @@ FT_END_HEADER #endif /* __T42PARSE_H__ */ -/* END */ +/* END */ diff --git a/headers/libs/freetype2/freetype/internal/t42types.h b/src/libs/freetype2/type42/t42types.h similarity index 94% rename from headers/libs/freetype2/freetype/internal/t42types.h rename to src/libs/freetype2/type42/t42types.h index 765ff43371..d44ac4e671 100644 --- a/headers/libs/freetype2/freetype/internal/t42types.h +++ b/src/libs/freetype2/type42/t42types.h @@ -4,7 +4,7 @@ /* */ /* Type 42 font data types (specification only). */ /* */ -/* Copyright 2002 by Roberto Alameda. */ +/* Copyright 2002, 2003 by Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ @@ -23,7 +23,6 @@ #include FT_FREETYPE_H #include FT_TYPE1_TABLES_H #include FT_INTERNAL_TYPE1_TYPES_H -#include FT_INTERNAL_POSTSCRIPT_NAMES_H #include FT_INTERNAL_POSTSCRIPT_HINTS_H @@ -52,4 +51,4 @@ FT_END_HEADER #endif /* __T1TYPES_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/type42/type42.c b/src/libs/freetype2/type42/type42.c index f70d9d24ed..d13df56b10 100644 --- a/src/libs/freetype2/type42/type42.c +++ b/src/libs/freetype2/type42/type42.c @@ -22,4 +22,4 @@ #include "t42parse.c" #include "t42drivr.c" -/* END */ +/* END */ diff --git a/src/libs/freetype2/winfonts/descrip.mms b/src/libs/freetype2/winfonts/descrip.mms index a0d03c52e4..475cdbb6bd 100644 --- a/src/libs/freetype2/winfonts/descrip.mms +++ b/src/libs/freetype2/winfonts/descrip.mms @@ -20,4 +20,4 @@ OBJS=winfnt.obj all : $(OBJS) library [--.lib]freetype.olb $(OBJS) -# EOF +# EOF diff --git a/src/libs/freetype2/winfonts/fnterrs.h b/src/libs/freetype2/winfonts/fnterrs.h index 61563c8a02..ea80909715 100644 --- a/src/libs/freetype2/winfonts/fnterrs.h +++ b/src/libs/freetype2/winfonts/fnterrs.h @@ -38,4 +38,4 @@ #endif /* __FNTERRS_H__ */ -/* END */ +/* END */ diff --git a/src/libs/freetype2/winfonts/module.mk b/src/libs/freetype2/winfonts/module.mk index cdff1c1bbf..99be845c19 100644 --- a/src/libs/freetype2/winfonts/module.mk +++ b/src/libs/freetype2/winfonts/module.mk @@ -18,4 +18,4 @@ make_module_list: add_windows_driver add_windows_driver: $(OPEN_DRIVER)winfnt_driver_class$(CLOSE_DRIVER) $(ECHO_DRIVER)winfnt $(ECHO_DRIVER_DESC)Windows bitmap fonts with extension *.fnt or *.fon$(ECHO_DRIVER_DONE) - + diff --git a/src/libs/freetype2/winfonts/rules.mk b/src/libs/freetype2/winfonts/rules.mk index daf07883aa..71a7df2d8a 100644 --- a/src/libs/freetype2/winfonts/rules.mk +++ b/src/libs/freetype2/winfonts/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2000, 2001 by +# Copyright 1996-2000, 2001, 2003 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -15,21 +15,20 @@ # Windows driver directory # -FNT_DIR := $(SRC_)winfonts -FNT_DIR_ := $(FNT_DIR)$(SEP) +FNT_DIR := $(SRC_DIR)/winfonts -FNT_COMPILE := $(FT_COMPILE) $I$(FNT_DIR) +FNT_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(FNT_DIR)) # Windows driver sources (i.e., C files) # -FNT_DRV_SRC := $(FNT_DIR_)winfnt.c +FNT_DRV_SRC := $(FNT_DIR)/winfnt.c # Windows driver headers # FNT_DRV_H := $(FNT_DRV_SRC:%.c=%.h) \ - $(FNT_DIR_)fnterrs.h + $(FNT_DIR)/fnterrs.h # Windows driver object(s) @@ -37,24 +36,24 @@ FNT_DRV_H := $(FNT_DRV_SRC:%.c=%.h) \ # FNT_DRV_OBJ_M is used during `multi' builds # FNT_DRV_OBJ_S is used during `single' builds # -FNT_DRV_OBJ_M := $(FNT_DRV_SRC:$(FNT_DIR_)%.c=$(OBJ_)%.$O) -FNT_DRV_OBJ_S := $(OBJ_)winfnt.$O +FNT_DRV_OBJ_M := $(FNT_DRV_SRC:$(FNT_DIR)/%.c=$(OBJ_DIR)/%.$O) +FNT_DRV_OBJ_S := $(OBJ_DIR)/winfnt.$O # Windows driver source file for single build # -FNT_DRV_SRC_S := $(FNT_DIR_)winfnt.c +FNT_DRV_SRC_S := $(FNT_DIR)/winfnt.c # Windows driver - single object # $(FNT_DRV_OBJ_S): $(FNT_DRV_SRC_S) $(FNT_DRV_SRC) $(FREETYPE_H) $(FNT_DRV_H) - $(FNT_COMPILE) $T$@ $(FNT_DRV_SRC_S) + $(FNT_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(FNT_DRV_SRC_S)) # Windows driver - multiple objects # -$(OBJ_)%.$O: $(FNT_DIR_)%.c $(FREETYPE_H) $(FNT_DRV_H) - $(FNT_COMPILE) $T$@ $< +$(OBJ_DIR)/%.$O: $(FNT_DIR)/%.c $(FREETYPE_H) $(FNT_DRV_H) + $(FNT_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<) # update main driver object lists @@ -62,4 +61,5 @@ $(OBJ_)%.$O: $(FNT_DIR_)%.c $(FREETYPE_H) $(FNT_DRV_H) DRV_OBJS_S += $(FNT_DRV_OBJ_S) DRV_OBJS_M += $(FNT_DRV_OBJ_M) -# EOF + +# EOF diff --git a/src/libs/freetype2/winfonts/winfnt.c b/src/libs/freetype2/winfonts/winfnt.c index c110b7bffd..26e4930654 100644 --- a/src/libs/freetype2/winfonts/winfnt.c +++ b/src/libs/freetype2/winfonts/winfnt.c @@ -4,7 +4,7 @@ /* */ /* FreeType font driver for Windows FNT/FON files */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,12 +21,11 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_FNT_TYPES_H #include "winfnt.h" - #include "fnterrs.h" - +#include FT_SERVICE_WINFNT_H +#include FT_SERVICE_XFREE86_NAME_H /*************************************************************************/ /* */ @@ -38,8 +37,7 @@ #define FT_COMPONENT trace_winfnt - static - const FT_Frame_Field winmz_header_fields[] = + static const FT_Frame_Field winmz_header_fields[] = { #undef FT_STRUCTURE #define FT_STRUCTURE WinMZ_HeaderRec @@ -51,8 +49,7 @@ FT_FRAME_END }; - static - const FT_Frame_Field winne_header_fields[] = + static const FT_Frame_Field winne_header_fields[] = { #undef FT_STRUCTURE #define FT_STRUCTURE WinNE_HeaderRec @@ -65,13 +62,12 @@ FT_FRAME_END }; - static - const FT_Frame_Field winfnt_header_fields[] = + static const FT_Frame_Field winfnt_header_fields[] = { #undef FT_STRUCTURE #define FT_STRUCTURE FT_WinFNT_HeaderRec - FT_FRAME_START( 146 ), + FT_FRAME_START( 148 ), FT_FRAME_USHORT_LE( version ), FT_FRAME_ULONG_LE ( file_size ), FT_FRAME_BYTES ( copyright, 60 ), @@ -106,21 +102,29 @@ FT_FRAME_USHORT_LE( A_space ), FT_FRAME_USHORT_LE( B_space ), FT_FRAME_USHORT_LE( C_space ), - FT_FRAME_USHORT_LE( color_table_offset ), + FT_FRAME_ULONG_LE ( color_table_offset ), FT_FRAME_BYTES ( reserved1, 16 ), FT_FRAME_END }; static void - fnt_font_done( FNT_Font font, - FT_Stream stream ) + fnt_font_done( FNT_Face face ) { + FT_Memory memory = FT_FACE( face )->memory; + FT_Stream stream = FT_FACE( face )->stream; + FNT_Font font = face->font; + + + if ( !font ) + return; + if ( font->fnt_frame ) FT_FRAME_RELEASE( font->fnt_frame ); + FT_FREE( font->family_name ); - font->fnt_size = 0; - font->fnt_frame = 0; + FT_FREE( font ); + face->font = 0; } @@ -130,10 +134,12 @@ { FT_Error error; FT_WinFNT_Header header = &font->header; + FT_Bool new_format; + FT_UInt size; /* first of all, read the FNT header */ - if ( FT_STREAM_SEEK( font->offset ) || + if ( FT_STREAM_SEEK( font->offset ) || FT_STREAM_READ_FIELDS( winfnt_header_fields, header ) ) goto Exit; @@ -146,6 +152,16 @@ goto Exit; } + new_format = FT_BOOL( font->header.version == 0x300 ); + size = new_format ? 148 : 118; + + if ( header->file_size < size ) + { + FT_TRACE2(( "[not a valid FNT file]\n" )); + error = FNT_Err_Unknown_File_Format; + goto Exit; + } + /* Version 2 doesn't have these fields */ if ( header->version == 0x200 ) { @@ -164,11 +180,7 @@ goto Exit; } - /* small fixup -- some fonts have the `pixel_width' field set to 0 */ - if ( header->pixel_width == 0 ) - header->pixel_width = header->pixel_height; - - /* this is a FNT file/table, we now extract its frame */ + /* this is a FNT file/table; extract its frame */ if ( FT_STREAM_SEEK( font->offset ) || FT_FRAME_EXTRACT( header->file_size, font->fnt_frame ) ) goto Exit; @@ -178,25 +190,9 @@ } - static void - fnt_face_done_fonts( FNT_Face face ) - { - FT_Memory memory = FT_FACE( face )->memory; - FT_Stream stream = FT_FACE( face )->stream; - FNT_Font cur = face->fonts; - FNT_Font limit = cur + face->num_fonts; - - - for ( ; cur < limit; cur++ ) - fnt_font_done( cur, stream ); - - FT_FREE( face->fonts ); - face->num_fonts = 0; - } - - static FT_Error - fnt_face_get_dll_fonts( FNT_Face face ) + fnt_face_get_dll_font( FNT_Face face, + FT_Int face_index ) { FT_Error error; FT_Stream stream = FT_FACE( face )->stream; @@ -204,38 +200,36 @@ WinMZ_HeaderRec mz_header; - face->fonts = 0; - face->num_fonts = 0; + face->font = 0; - /* does it begin with a MZ header? */ - if ( FT_STREAM_SEEK( 0 ) || + /* does it begin with an MZ header? */ + if ( FT_STREAM_SEEK( 0 ) || FT_STREAM_READ_FIELDS( winmz_header_fields, &mz_header ) ) goto Exit; error = FNT_Err_Unknown_File_Format; if ( mz_header.magic == WINFNT_MZ_MAGIC ) { - /* yes, now look for a NE header in the file */ + /* yes, now look for an NE header in the file */ WinNE_HeaderRec ne_header; - if ( FT_STREAM_SEEK( mz_header.lfanew ) || + if ( FT_STREAM_SEEK( mz_header.lfanew ) || FT_STREAM_READ_FIELDS( winne_header_fields, &ne_header ) ) goto Exit; error = FNT_Err_Unknown_File_Format; if ( ne_header.magic == WINFNT_NE_MAGIC ) { - /* good, now look in the resource table for each FNT resource */ - FT_ULong res_offset = mz_header.lfanew + - ne_header.resource_tab_offset; - + /* good, now look into the resource table for each FNT resource */ + FT_ULong res_offset = mz_header.lfanew + + ne_header.resource_tab_offset; FT_UShort size_shift; FT_UShort font_count = 0; FT_ULong font_offset = 0; - if ( FT_STREAM_SEEK( res_offset ) || + if ( FT_STREAM_SEEK( res_offset ) || FT_FRAME_ENTER( ne_header.rname_tab_offset - ne_header.resource_tab_offset ) ) goto Exit; @@ -253,7 +247,7 @@ count = FT_GET_USHORT_LE(); - if ( type_id == 0x8008 ) + if ( type_id == 0x8008U ) { font_count = count; font_offset = (FT_ULong)( FT_STREAM_POS() + 4 + @@ -263,6 +257,7 @@ stream->cursor += 4 + count * 12; } + FT_FRAME_EXIT(); if ( !font_count || !font_offset ) @@ -272,57 +267,42 @@ goto Exit; } - if ( FT_STREAM_SEEK( font_offset ) || - FT_NEW_ARRAY( face->fonts, font_count ) ) - goto Exit; + face->root.num_faces = font_count; - face->num_fonts = font_count; - - if ( FT_FRAME_ENTER( (FT_Long)font_count * 12 ) ) - goto Exit; - - /* now read the offset and position of each FNT font */ + if ( face_index >= font_count ) { - FNT_Font cur = face->fonts; - FNT_Font limit = cur + font_count; - - - for ( ; cur < limit; cur++ ) - { - cur->offset = (FT_ULong)FT_GET_USHORT_LE() << size_shift; - cur->fnt_size = (FT_ULong)FT_GET_USHORT_LE() << size_shift; - cur->size_shift = size_shift; - stream->cursor += 8; - } + error = FNT_Err_Bad_Argument; + goto Exit; } + + if ( FT_NEW( face->font ) ) + goto Exit; + + if ( FT_STREAM_SEEK( font_offset + face_index * 12 ) || + FT_FRAME_ENTER( 12 ) ) + goto Fail; + + face->font->offset = (FT_ULong)FT_GET_USHORT_LE() << size_shift; + face->font->fnt_size = (FT_ULong)FT_GET_USHORT_LE() << size_shift; + face->font->size_shift = size_shift; + + stream->cursor += 8; + FT_FRAME_EXIT(); - /* finally, try to load each font there */ - { - FNT_Font cur = face->fonts; - FNT_Font limit = cur + font_count; - - - for ( ; cur < limit; cur++ ) - { - error = fnt_font_load( cur, stream ); - if ( error ) - goto Fail; - } - } + error = fnt_font_load( face->font, stream ); } } Fail: if ( error ) - fnt_face_done_fonts( face ); + fnt_font_done( face ); Exit: return error; } - typedef struct FNT_CMapRec_ { FT_CMapRec cmap; @@ -336,7 +316,7 @@ fnt_cmap_init( FNT_CMap cmap ) { FNT_Face face = (FNT_Face)FT_CMAP_FACE( cmap ); - FNT_Font font = face->fonts; + FNT_Font font = face->font; cmap->first = (FT_UInt32) font->header.first_char; @@ -355,8 +335,8 @@ char_code -= cmap->first; if ( char_code < cmap->count ) - gindex = char_code + 1; - + gindex = char_code + 1; /* we artificially increase the glyph index; */ + /* FNT_Load_Glyph reverts to the right one */ return gindex; } @@ -390,7 +370,7 @@ } - static FT_CMap_ClassRec fnt_cmap_class_rec = + static const FT_CMap_ClassRec fnt_cmap_class_rec = { sizeof ( FNT_CMapRec ), @@ -400,8 +380,7 @@ (FT_CMap_CharNextFunc) fnt_cmap_char_next }; - static FT_CMap_Class fnt_cmap_class = &fnt_cmap_class_rec; - + static FT_CMap_Class const fnt_cmap_class = &fnt_cmap_class_rec; static void @@ -410,7 +389,7 @@ FT_Memory memory = FT_FACE_MEMORY( face ); - fnt_face_done_fonts( face ); + fnt_font_done( face ); FT_FREE( face->root.available_sizes ); face->root.num_fixed_sizes = 0; @@ -429,23 +408,22 @@ FT_UNUSED( num_params ); FT_UNUSED( params ); - FT_UNUSED( face_index ); - /* try to load several fonts from a DLL */ - error = fnt_face_get_dll_fonts( face ); + /* try to load font from a DLL */ + error = fnt_face_get_dll_font( face, face_index ); if ( error ) { - /* this didn't work, now try to load a single FNT font */ + /* this didn't work; try to load a single FNT font */ FNT_Font font; - if ( FT_NEW( face->fonts ) ) + if ( FT_NEW( face->font ) ) goto Exit; - face->num_fonts = 1; - font = face->fonts; + face->root.num_faces = 1; + font = face->font; font->offset = 0; font->fnt_size = stream->size; @@ -454,53 +432,64 @@ goto Fail; } - /* all right, one or more fonts were loaded; we now need to */ - /* fill the root FT_Face fields with relevant information */ + /* we now need to fill the root FT_Face fields */ + /* with relevant information */ { - FT_Face root = FT_FACE( face ); - FNT_Font fonts = face->fonts; - FNT_Font limit = fonts + face->num_fonts; - FNT_Font cur; + FT_Face root = FT_FACE( face ); + FNT_Font font = face->font; + FT_PtrDist family_size; - root->num_faces = 1; root->face_flags = FT_FACE_FLAG_FIXED_SIZES | FT_FACE_FLAG_HORIZONTAL; - if ( fonts->header.avg_width == fonts->header.max_width ) + if ( font->header.avg_width == font->header.max_width ) root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; - if ( fonts->header.italic ) + if ( font->header.italic ) root->style_flags |= FT_STYLE_FLAG_ITALIC; - if ( fonts->header.weight >= 800 ) + if ( font->header.weight >= 800 ) root->style_flags |= FT_STYLE_FLAG_BOLD; - /* Setup the `fixed_sizes' array */ - if ( FT_NEW_ARRAY( root->available_sizes, face->num_fonts ) ) + /* set up the `fixed_sizes' array */ + if ( FT_NEW_ARRAY( root->available_sizes, 1 ) ) goto Fail; - root->num_fixed_sizes = face->num_fonts; + root->num_fixed_sizes = 1; { - FT_Bitmap_Size* size = root->available_sizes; + FT_Bitmap_Size* bsize = root->available_sizes; - for ( cur = fonts; cur < limit; cur++, size++ ) - { - size->width = cur->header.pixel_width; - size->height = cur->header.pixel_height; - } + bsize->width = font->header.avg_width; + bsize->height = (FT_Short)( + font->header.pixel_height + font->header.external_leading ); + bsize->size = font->header.nominal_point_size << 6; + bsize->x_ppem = + (FT_Pos)( ( font->header.horizontal_resolution * bsize->size + 36 ) + / 72 ); + bsize->y_ppem = + (FT_Pos)( ( font->header.vertical_resolution* bsize->size + 36 ) + / 72 ); } { FT_CharMapRec charmap; - charmap.encoding = FT_ENCODING_UNICODE; - charmap.platform_id = 3; - charmap.encoding_id = 1; + + charmap.encoding = FT_ENCODING_NONE; + charmap.platform_id = 0; + charmap.encoding_id = 0; charmap.face = root; + if ( font->header.charset == FT_WinFNT_ID_MAC ) + { + charmap.encoding = FT_ENCODING_APPLE_ROMAN; + charmap.platform_id = 1; +/* charmap.encoding_id = 0; */ + } + error = FT_CMap_New( fnt_cmap_class, NULL, &charmap, @@ -514,11 +503,27 @@ } /* setup remaining flags */ - root->num_glyphs = fonts->header.last_char - - fonts->header.first_char + 1; - root->family_name = (FT_String*)fonts->fnt_frame + - fonts->header.face_name_offset; + /* reserve one slot for the .notdef glyph at index 0 */ + root->num_glyphs = font->header.last_char - + font->header.first_char + 1 + 1; + + /* Some broken fonts don't delimit the face name with a final */ + /* NULL byte -- the frame is erroneously one byte too small. */ + /* We thus allocate one more byte, setting it explicitly to */ + /* zero. */ + family_size = font->header.file_size - font->header.face_name_offset; + if ( FT_ALLOC( font->family_name, family_size + 1 ) ) + goto Fail; + FT_MEM_COPY( font->family_name, + font->fnt_frame + font->header.face_name_offset, + family_size ); + font->family_name[family_size] = '\0'; + if ( FT_REALLOC( font->family_name, + family_size, + ft_strlen( font->family_name ) + 1 ) ) + goto Fail; + root->family_name = font->family_name; root->style_name = (char *)"Regular"; if ( root->style_flags & FT_STYLE_FLAG_BOLD ) @@ -531,10 +536,10 @@ else if ( root->style_flags & FT_STYLE_FLAG_ITALIC ) root->style_name = (char *)"Italic"; } + goto Exit; Fail: - if ( error ) - FNT_Face_Done( face ); + FNT_Face_Done( face ); Exit: return error; @@ -542,69 +547,64 @@ static FT_Error - FNT_Size_Set_Pixels( FNT_Size size ) + FNT_Size_Set_Pixels( FT_Size size ) { - /* look up a font corresponding to the current pixel size */ - FNT_Face face = (FNT_Face)FT_SIZE_FACE( size ); - FNT_Font cur = face->fonts; - FNT_Font limit = cur + face->num_fonts; + FNT_Face face = (FNT_Face)FT_SIZE_FACE( size ); + FT_Face root = FT_FACE( face ); - size->font = 0; - for ( ; cur < limit; cur++ ) + if ( size->metrics.y_ppem == root->available_sizes->height ) { - /* we only compare the character height, as fonts used some strange */ - /* values */ - if ( cur->header.pixel_height == size->root.metrics.y_ppem ) - { - size->font = cur; + FNT_Font font = face->font; - size->root.metrics.ascender = cur->header.ascent * 64; - size->root.metrics.descender = ( cur->header.pixel_height - - cur->header.ascent ) * 64; - size->root.metrics.height = cur->header.pixel_height * 64; - break; - } + + size->metrics.ascender = font->header.ascent * 64; + size->metrics.descender = -( font->header.pixel_height - + font->header.ascent ) * 64; + size->metrics.height = font->header.pixel_height * 64; + size->metrics.max_advance = font->header.max_width * 64; + + return FNT_Err_Ok; } - - return ( size->font ? FNT_Err_Ok : FNT_Err_Invalid_Pixel_Size ); + else + return FNT_Err_Invalid_Pixel_Size; } static FT_Error FNT_Load_Glyph( FT_GlyphSlot slot, - FNT_Size size, + FT_Size size, FT_UInt glyph_index, FT_Int32 load_flags ) { - FNT_Font font = size->font; - FT_Error error = 0; + FNT_Face face = (FNT_Face)FT_SIZE_FACE( size ); + FNT_Font font = face->font; + FT_Error error = FNT_Err_Ok; FT_Byte* p; FT_Int len; FT_Bitmap* bitmap = &slot->bitmap; FT_ULong offset; FT_Bool new_format; - FT_UNUSED( slot ); FT_UNUSED( load_flags ); - if ( !font ) + if ( !face || !font ) { error = FNT_Err_Invalid_Argument; goto Exit; } if ( glyph_index > 0 ) - glyph_index--; + glyph_index--; /* revert to real index */ else - glyph_index = font->header.default_char - font->header.first_char; + glyph_index = font->header.default_char; /* the .notdef glyph */ new_format = FT_BOOL( font->header.version == 0x300 ); len = new_format ? 6 : 4; /* jump to glyph entry */ - p = font->fnt_frame + ( new_format ? 146 : 118 ) + len * glyph_index; + p = font->fnt_frame + ( new_format ? 148 : 118 ) + len * glyph_index; bitmap->width = FT_NEXT_SHORT_LE( p ); @@ -613,26 +613,49 @@ else offset = FT_NEXT_USHORT_LE( p ); + if ( offset >= font->header.file_size ) + { + FT_TRACE2(( "invalid FNT offset!\n" )); + error = FNT_Err_Invalid_File_Format; + goto Exit; + } + /* jump to glyph data */ p = font->fnt_frame + /* font->header.bits_offset */ + offset; /* allocate and build bitmap */ { + FT_Memory memory = FT_FACE_MEMORY( slot->face ); FT_Int pitch = ( bitmap->width + 7 ) >> 3; + FT_Byte* column; + FT_Byte* write; bitmap->pitch = pitch; bitmap->rows = font->header.pixel_height; bitmap->pixel_mode = FT_PIXEL_MODE_MONO; - /* note: we don't allocate a new buffer for the bitmap since we */ - /* already store the images in the FT_Face */ - ft_glyphslot_set_bitmap( slot, p ); + /* note: since glyphs are stored in columns and not in rows we */ + /* can't use ft_glyphslot_set_bitmap */ + if ( FT_ALLOC( bitmap->buffer, pitch * bitmap->rows ) ) + goto Exit; + + column = (FT_Byte*)bitmap->buffer; + + for ( ; pitch > 0; pitch--, column++ ) + { + FT_Byte* limit = p + bitmap->rows; + + + for ( write = column; p < limit; p++, write += bitmap->pitch ) + *write = *p; + } } - slot->bitmap_left = 0; - slot->bitmap_top = font->header.ascent; - slot->format = FT_GLYPH_FORMAT_BITMAP; + slot->internal->flags = FT_GLYPH_OWN_BITMAP; + slot->bitmap_left = 0; + slot->bitmap_top = font->header.ascent; + slot->format = FT_GLYPH_FORMAT_BITMAP; /* now set up metrics */ slot->metrics.horiAdvance = bitmap->width << 6; @@ -647,11 +670,55 @@ } + static FT_Error + winfnt_get_header( FT_Face face, + FT_WinFNT_HeaderRec *aheader ) + { + FNT_Font font = ((FNT_Face)face)->font; + + + *aheader = font->header; + + return 0; + } + + + static const FT_Service_WinFntRec winfnt_service_rec = + { + winfnt_get_header + }; + + /* + * SERVICE LIST + * + */ + + static const FT_ServiceDescRec winfnt_services[] = + { + { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_WINFNT }, + { FT_SERVICE_ID_WINFNT, &winfnt_service_rec }, + { NULL, NULL } + }; + + + static FT_Module_Interface + winfnt_get_service( FT_Driver driver, + const FT_String* service_id ) + { + FT_UNUSED( driver ); + + return ft_service_list_lookup( winfnt_services, service_id ); + } + + + + FT_CALLBACK_TABLE_DEF const FT_Driver_ClassRec winfnt_driver_class = { { - ft_module_font_driver, + FT_MODULE_FONT_DRIVER | + FT_MODULE_DRIVER_NO_OUTLINES, sizeof ( FT_DriverRec ), "winfonts", @@ -662,11 +729,11 @@ (FT_Module_Constructor)0, (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 + (FT_Module_Requester) winfnt_get_service }, sizeof( FNT_FaceRec ), - sizeof( FNT_SizeRec ), + sizeof( FT_SizeRec ), sizeof( FT_GlyphSlotRec ), (FT_Face_InitFunc) FNT_Face_Init, @@ -686,4 +753,4 @@ }; -/* END */ +/* END */ diff --git a/src/libs/freetype2/winfonts/winfnt.h b/src/libs/freetype2/winfonts/winfnt.h index 64e11ff84e..32ab6daf0a 100644 --- a/src/libs/freetype2/winfonts/winfnt.h +++ b/src/libs/freetype2/winfonts/winfnt.h @@ -4,7 +4,7 @@ /* */ /* FreeType font driver for Windows FNT/FON files */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,11 +21,79 @@ #include +#include FT_WINFONTS_H #include FT_INTERNAL_DRIVER_H FT_BEGIN_HEADER + typedef struct WinMZ_HeaderRec_ + { + FT_UShort magic; + /* skipped content */ + FT_UShort lfanew; + + } WinMZ_HeaderRec; + + + typedef struct WinNE_HeaderRec_ + { + FT_UShort magic; + /* skipped content */ + FT_UShort resource_tab_offset; + FT_UShort rname_tab_offset; + + } WinNE_HeaderRec; + + + typedef struct WinNameInfoRec_ + { + FT_UShort offset; + FT_UShort length; + FT_UShort flags; + FT_UShort id; + FT_UShort handle; + FT_UShort usage; + + } WinNameInfoRec; + + + typedef struct WinResourceInfoRec_ + { + FT_UShort type_id; + FT_UShort count; + + } WinResourceInfoRec; + + +#define WINFNT_MZ_MAGIC 0x5A4D +#define WINFNT_NE_MAGIC 0x454E + + + typedef struct FNT_FontRec_ + { + FT_ULong offset; + FT_Int size_shift; + + FT_WinFNT_HeaderRec header; + + FT_Byte* fnt_frame; + FT_ULong fnt_size; + FT_String* family_name; + + } FNT_FontRec, *FNT_Font; + + + typedef struct FNT_FaceRec_ + { + FT_FaceRec root; + FNT_Font font; + + FT_CharMap charmap_handle; + FT_CharMapRec charmap; /* a single charmap per face */ + + } FNT_FaceRec, *FNT_Face; + FT_EXPORT_VAR( const FT_Driver_ClassRec ) winfnt_driver_class; @@ -36,4 +104,4 @@ FT_END_HEADER #endif /* __WINFNT_H__ */ -/* END */ +/* END */