ReactOS  0.4.15-dev-499-g1f31905
ftccmap.c
Go to the documentation of this file.
1 /***************************************************************************/
2 /* */
3 /* ftccmap.c */
4 /* */
5 /* FreeType CharMap cache (body) */
6 /* */
7 /* Copyright 2000-2018 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
9 /* */
10 /* This file is part of the FreeType project, and may only be used, */
11 /* modified, and distributed under the terms of the FreeType project */
12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
13 /* this file you indicate that you have read the license and */
14 /* understand and accept it fully. */
15 /* */
16 /***************************************************************************/
17 
18 
19 #include <ft2build.h>
20 #include FT_FREETYPE_H
21 #include FT_CACHE_H
22 #include "ftcmanag.h"
23 #include FT_INTERNAL_MEMORY_H
24 #include FT_INTERNAL_OBJECTS_H
25 #include FT_INTERNAL_DEBUG_H
26 
27 #include "ftccback.h"
28 #include "ftcerror.h"
29 
30 #undef FT_COMPONENT
31 #define FT_COMPONENT trace_cache
32 
33 
34  /*************************************************************************/
35  /* */
36  /* Each FTC_CMapNode contains a simple array to map a range of character */
37  /* codes to equivalent glyph indices. */
38  /* */
39  /* For now, the implementation is very basic: Each node maps a range of */
40  /* 128 consecutive character codes to their corresponding glyph indices. */
41  /* */
42  /* We could do more complex things, but I don't think it is really very */
43  /* useful. */
44  /* */
45  /*************************************************************************/
46 
47 
48  /* number of glyph indices / character code per node */
49 #define FTC_CMAP_INDICES_MAX 128
50 
51  /* compute a query/node hash */
52 #define FTC_CMAP_HASH( faceid, index, charcode ) \
53  ( FTC_FACE_ID_HASH( faceid ) + 211 * (index) + \
54  ( (charcode) / FTC_CMAP_INDICES_MAX ) )
55 
56  /* the charmap query */
57  typedef struct FTC_CMapQueryRec_
58  {
61  FT_UInt32 char_code;
62 
64 
65 #define FTC_CMAP_QUERY( x ) ((FTC_CMapQuery)(x))
66 
67  /* the cmap cache node */
68  typedef struct FTC_CMapNodeRec_
69  {
73  FT_UInt32 first; /* first character in node */
74  FT_UInt16 indices[FTC_CMAP_INDICES_MAX]; /* array of glyph indices */
75 
77 
78 #define FTC_CMAP_NODE( x ) ( (FTC_CMapNode)( x ) )
79 
80  /* if (indices[n] == FTC_CMAP_UNKNOWN), we assume that the corresponding */
81  /* glyph indices haven't been queried through FT_Get_Glyph_Index() yet */
82 #define FTC_CMAP_UNKNOWN (FT_UInt16)~0
83 
84 
85  /*************************************************************************/
86  /*************************************************************************/
87  /***** *****/
88  /***** CHARMAP NODES *****/
89  /***** *****/
90  /*************************************************************************/
91  /*************************************************************************/
92 
93 
94  FT_CALLBACK_DEF( void )
97  {
98  FTC_CMapNode node = (FTC_CMapNode)ftcnode;
99  FT_Memory memory = cache->memory;
100 
101 
102  FT_FREE( node );
103  }
104 
105 
106  /* initialize a new cmap node */
109  FT_Pointer ftcquery,
110  FTC_Cache cache )
111  {
112  FTC_CMapNode *anode = (FTC_CMapNode*)ftcanode;
113  FTC_CMapQuery query = (FTC_CMapQuery)ftcquery;
114  FT_Error error;
115  FT_Memory memory = cache->memory;
117  FT_UInt nn;
118 
119 
120  if ( !FT_NEW( node ) )
121  {
122  node->face_id = query->face_id;
123  node->cmap_index = query->cmap_index;
124  node->first = (query->char_code / FTC_CMAP_INDICES_MAX) *
126 
127  for ( nn = 0; nn < FTC_CMAP_INDICES_MAX; nn++ )
128  node->indices[nn] = FTC_CMAP_UNKNOWN;
129  }
130 
131  *anode = node;
132  return error;
133  }
134 
135 
136  /* compute the weight of a given cmap node */
139  FTC_Cache cache )
140  {
141  FT_UNUSED( cnode );
142  FT_UNUSED( cache );
143 
144  return sizeof ( *cnode );
145  }
146 
147 
148  /* compare a cmap node to a given query */
151  FT_Pointer ftcquery,
153  FT_Bool* list_changed )
154  {
155  FTC_CMapNode node = (FTC_CMapNode)ftcnode;
156  FTC_CMapQuery query = (FTC_CMapQuery)ftcquery;
157  FT_UNUSED( cache );
158 
159 
160  if ( list_changed )
161  *list_changed = FALSE;
162  if ( node->face_id == query->face_id &&
163  node->cmap_index == query->cmap_index )
164  {
165  FT_UInt32 offset = (FT_UInt32)( query->char_code - node->first );
166 
167 
168  return FT_BOOL( offset < FTC_CMAP_INDICES_MAX );
169  }
170 
171  return 0;
172  }
173 
174 
177  FT_Pointer ftcface_id,
179  FT_Bool* list_changed )
180  {
181  FTC_CMapNode node = (FTC_CMapNode)ftcnode;
182  FTC_FaceID face_id = (FTC_FaceID)ftcface_id;
183  FT_UNUSED( cache );
184 
185 
186  if ( list_changed )
187  *list_changed = FALSE;
188  return FT_BOOL( node->face_id == face_id );
189  }
190 
191 
192  /*************************************************************************/
193  /*************************************************************************/
194  /***** *****/
195  /***** GLYPH IMAGE CACHE *****/
196  /***** *****/
197  /*************************************************************************/
198  /*************************************************************************/
199 
200 
201  static
203  {
204  ftc_cmap_node_new, /* FTC_Node_NewFunc node_new */
205  ftc_cmap_node_weight, /* FTC_Node_WeightFunc node_weight */
206  ftc_cmap_node_compare, /* FTC_Node_CompareFunc node_compare */
207  ftc_cmap_node_remove_faceid, /* FTC_Node_CompareFunc node_remove_faceid */
208  ftc_cmap_node_free, /* FTC_Node_FreeFunc node_free */
209 
210  sizeof ( FTC_CacheRec ),
211  ftc_cache_init, /* FTC_Cache_InitFunc cache_init */
212  ftc_cache_done, /* FTC_Cache_DoneFunc cache_done */
213  };
214 
215 
216  /* documentation is in ftcache.h */
217 
220  FTC_CMapCache *acache )
221  {
222  return FTC_Manager_RegisterCache( manager,
224  FTC_CACHE_P( acache ) );
225  }
226 
227 
228  /* documentation is in ftcache.h */
229 
232  FTC_FaceID face_id,
233  FT_Int cmap_index,
234  FT_UInt32 char_code )
235  {
236  FTC_Cache cache = FTC_CACHE( cmap_cache );
238  FTC_Node node;
239  FT_Error error;
240  FT_UInt gindex = 0;
241  FT_Offset hash;
242  FT_Int no_cmap_change = 0;
243 
244 
245  if ( cmap_index < 0 )
246  {
247  /* Treat a negative cmap index as a special value, meaning that you */
248  /* don't want to change the FT_Face's character map through this */
249  /* call. This can be useful if the face requester callback already */
250  /* sets the face's charmap to the appropriate value. */
251 
252  no_cmap_change = 1;
253  cmap_index = 0;
254  }
255 
256  if ( !cache )
257  {
258  FT_TRACE0(( "FTC_CMapCache_Lookup: bad arguments, returning 0\n" ));
259  return 0;
260  }
261 
262  query.face_id = face_id;
263  query.cmap_index = (FT_UInt)cmap_index;
264  query.char_code = char_code;
265 
266  hash = FTC_CMAP_HASH( face_id, (FT_UInt)cmap_index, char_code );
267 
268 #if 1
270  node, error );
271 #else
272  error = FTC_Cache_Lookup( cache, hash, &query, &node );
273 #endif
274  if ( error )
275  goto Exit;
276 
277  FT_ASSERT( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first ) <
279 
280  /* something rotten can happen with rogue clients */
281  if ( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first >=
283  return 0; /* XXX: should return appropriate error */
284 
285  gindex = FTC_CMAP_NODE( node )->indices[char_code -
286  FTC_CMAP_NODE( node )->first];
287  if ( gindex == FTC_CMAP_UNKNOWN )
288  {
289  FT_Face face;
290 
291 
292  gindex = 0;
293 
294  error = FTC_Manager_LookupFace( cache->manager,
295  FTC_CMAP_NODE( node )->face_id,
296  &face );
297  if ( error )
298  goto Exit;
299 
300  if ( (FT_UInt)cmap_index < (FT_UInt)face->num_charmaps )
301  {
302  FT_CharMap old, cmap = NULL;
303 
304 
305  old = face->charmap;
306  cmap = face->charmaps[cmap_index];
307 
308  if ( old != cmap && !no_cmap_change )
309  FT_Set_Charmap( face, cmap );
310 
311  gindex = FT_Get_Char_Index( face, char_code );
312 
313  if ( old != cmap && !no_cmap_change )
314  FT_Set_Charmap( face, old );
315  }
316 
317  FTC_CMAP_NODE( node )->indices[char_code -
318  FTC_CMAP_NODE( node )->first]
319  = (FT_UShort)gindex;
320  }
321 
322  Exit:
323  return gindex;
324  }
325 
326 
327 /* END */
Definition: cache.c:48
int FT_Error
Definition: fttypes.h:300
GLuint GLuint GLsizei GLenum const GLvoid * indices
Definition: gl.h:1545
FT_UInt32 first
Definition: ftccmap.c:73
static const FTC_CacheClassRec ftc_cmap_cache_class
Definition: ftccmap.c:202
#define error(str)
Definition: mkdosfs.c:1605
unsigned short FT_UInt16
Definition: ftconfig.h:181
struct FTC_CMapCacheRec_ * FTC_CMapCache
Definition: ftcache.h:553
FT_UInt32 char_code
Definition: ftccmap.c:61
ftc_cmap_node_new(FTC_Node *ftcanode, FT_Pointer ftcquery, FTC_Cache cache)
Definition: ftccmap.c:108
ftc_cmap_node_weight(FTC_Node cnode, FTC_Cache cache)
Definition: ftccmap.c:138
signed int FT_Int
Definition: fttypes.h:220
struct FTC_CMapQueryRec_ FTC_CMapQueryRec
FTC_CMapCache_Lookup(FTC_CMapCache cmap_cache, FTC_FaceID face_id, FT_Int cmap_index, FT_UInt32 char_code)
Definition: ftccmap.c:231
const GLint * first
Definition: glext.h:5794
GLintptr offset
Definition: glext.h:5920
#define FTC_CMAP_NODE(x)
Definition: ftccmap.c:78
ftc_cmap_node_compare(FTC_Node ftcnode, FT_Pointer ftcquery, FTC_Cache cache, FT_Bool *list_changed)
Definition: ftccmap.c:150
static char memory[1024 *256]
Definition: process.c:116
struct FTC_CMapNodeRec_ * FTC_CMapNode
#define FTC_CMAP_INDICES_MAX
Definition: ftccmap.c:49
ftc_cmap_node_free(FTC_Node ftcnode, FTC_Cache cache)
Definition: ftccmap.c:95
FT_BEGIN_HEADER typedef FT_Pointer FTC_FaceID
Definition: ftcache.h:171
ftc_cache_init(FTC_Cache cache)
Definition: ftccache.c:335
struct FTC_CMapQueryRec_ * FTC_CMapQuery
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:108
struct node node
int hash
Definition: main.c:58
#define FT_ASSERT(condition)
Definition: ftdebug.h:211
#define FTC_CMAP_UNKNOWN
Definition: ftccmap.c:82
smooth NULL
Definition: ftsmooth.c:416
FT_UInt cmap_index
Definition: ftccmap.c:60
FTC_NodeRec node
Definition: ftccmap.c:70
#define FT_FREE(ptr)
Definition: ftmemory.h:329
FTC_Manager_RegisterCache(FTC_Manager manager, FTC_CacheClass clazz, FTC_Cache *acache)
Definition: ftcmanag.c:580
FT_Get_Char_Index(FT_Face face, FT_ULong charcode)
Definition: ftobjs.c:3668
#define FT_TRACE0(varformat)
Definition: ftdebug.h:157
FT_UInt cmap_index
Definition: ftccmap.c:72
static void Exit(void)
Definition: sock.c:1331
#define FTC_CACHE(x)
Definition: ftccache.h:161
WORD face[3]
Definition: mesh.c:4747
#define FTC_CMAP_HASH(faceid, index, charcode)
Definition: ftccmap.c:52
#define FTC_CACHE_P(x)
Definition: ftccache.h:162
#define FT_CALLBACK_DEF(x)
Definition: ftconfig.h:533
FTC_CMapCache_New(FTC_Manager manager, FTC_CMapCache *acache)
Definition: ftccmap.c:219
FT_Set_Charmap(FT_Face face, FT_CharMap charmap)
Definition: ftobjs.c:3499
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
#define FT_BOOL(x)
Definition: fttypes.h:578
struct FTC_CacheRec_ FTC_CacheRec
FTC_FaceID face_id
Definition: ftccmap.c:71
#define FTC_CACHE_LOOKUP_CMP(cache, nodecmp, hash, query, node, error)
Definition: ftccache.h:210
#define FT_EXPORT_DEF(x)
Definition: ftconfig.h:483
unsigned int FT_UInt
Definition: fttypes.h:231
FTC_FaceID face_id
Definition: ftccmap.c:59
struct FTC_CMapNodeRec_ FTC_CMapNodeRec
#define FT_NEW(ptr)
Definition: ftmemory.h:331
unsigned short FT_UShort
Definition: fttypes.h:209
Definition: _hash_fun.h:40
#define FT_UNUSED(arg)
Definition: ftconfig.h:101
GLenum query
Definition: glext.h:7781
GLenum GLuint GLint GLenum face
Definition: glext.h:7025
ftc_cache_done(FTC_Cache cache)
Definition: ftccache.c:389
FTC_Manager_LookupFace(FTC_Manager manager, FTC_FaceID face_id, FT_Face *aface)
Definition: ftcmanag.c:310
size_t FT_Offset
Definition: fttypes.h:324
Definition: dlist.c:348
ftc_cmap_node_remove_faceid(FTC_Node ftcnode, FT_Pointer ftcface_id, FTC_Cache cache, FT_Bool *list_changed)
Definition: ftccmap.c:176