Visualization Library 2.0.0-b5

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
ftccmap.c
Go to the documentation of this file.
1 /***************************************************************************/
2 /* */
3 /* ftccmap.c */
4 /* */
5 /* FreeType CharMap cache (body) */
6 /* */
7 /* Copyright 2000-2012 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 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
35 
36  typedef enum FTC_OldCMapType_
37  {
38  FTC_OLD_CMAP_BY_INDEX = 0,
39  FTC_OLD_CMAP_BY_ENCODING = 1,
40  FTC_OLD_CMAP_BY_ID = 2
41 
42  } FTC_OldCMapType;
43 
44 
45  typedef struct FTC_OldCMapIdRec_
46  {
47  FT_UInt platform;
48  FT_UInt encoding;
49 
50  } FTC_OldCMapIdRec, *FTC_OldCMapId;
51 
52 
53  typedef struct FTC_OldCMapDescRec_
54  {
55  FTC_FaceID face_id;
56  FTC_OldCMapType type;
57 
58  union
59  {
60  FT_UInt index;
61  FT_Encoding encoding;
62  FTC_OldCMapIdRec id;
63 
64  } u;
65 
66  } FTC_OldCMapDescRec, *FTC_OldCMapDesc;
67 
68 #endif /* FT_CONFIG_OLD_INTERNALS */
69 
70 
71  /*************************************************************************/
72  /* */
73  /* Each FTC_CMapNode contains a simple array to map a range of character */
74  /* codes to equivalent glyph indices. */
75  /* */
76  /* For now, the implementation is very basic: Each node maps a range of */
77  /* 128 consecutive character codes to their corresponding glyph indices. */
78  /* */
79  /* We could do more complex things, but I don't think it is really very */
80  /* useful. */
81  /* */
82  /*************************************************************************/
83 
84 
85  /* number of glyph indices / character code per node */
86 #define FTC_CMAP_INDICES_MAX 128
87 
88  /* compute a query/node hash */
89 #define FTC_CMAP_HASH( faceid, index, charcode ) \
90  ( _FTC_FACE_ID_HASH( faceid ) + 211 * (index) + \
91  ( (charcode) / FTC_CMAP_INDICES_MAX ) )
92 
93  /* the charmap query */
94  typedef struct FTC_CMapQueryRec_
95  {
96  FTC_FaceID face_id;
97  FT_UInt cmap_index;
98  FT_UInt32 char_code;
99 
101 
102 #define FTC_CMAP_QUERY( x ) ((FTC_CMapQuery)(x))
103 #define FTC_CMAP_QUERY_HASH( x ) \
104  FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->char_code )
105 
106  /* the cmap cache node */
107  typedef struct FTC_CMapNodeRec_
108  {
109  FTC_NodeRec node;
110  FTC_FaceID face_id;
111  FT_UInt cmap_index;
112  FT_UInt32 first; /* first character in node */
113  FT_UInt16 indices[FTC_CMAP_INDICES_MAX]; /* array of glyph indices */
114 
116 
117 #define FTC_CMAP_NODE( x ) ( (FTC_CMapNode)( x ) )
118 #define FTC_CMAP_NODE_HASH( x ) \
119  FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->first )
120 
121  /* if (indices[n] == FTC_CMAP_UNKNOWN), we assume that the corresponding */
122  /* glyph indices haven't been queried through FT_Get_Glyph_Index() yet */
123 #define FTC_CMAP_UNKNOWN (FT_UInt16)~0
124 
125 
126  /*************************************************************************/
127  /*************************************************************************/
128  /***** *****/
129  /***** CHARMAP NODES *****/
130  /***** *****/
131  /*************************************************************************/
132  /*************************************************************************/
133 
134 
135  FT_CALLBACK_DEF( void )
137  FTC_Cache cache )
138  {
139  FTC_CMapNode node = (FTC_CMapNode)ftcnode;
140  FT_Memory memory = cache->memory;
141 
142 
143  FT_FREE( node );
144  }
145 
146 
147  /* initialize a new cmap node */
150  FT_Pointer ftcquery,
151  FTC_Cache cache )
152  {
153  FTC_CMapNode *anode = (FTC_CMapNode*)ftcanode;
154  FTC_CMapQuery query = (FTC_CMapQuery)ftcquery;
155  FT_Error error;
156  FT_Memory memory = cache->memory;
157  FTC_CMapNode node = NULL;
158  FT_UInt nn;
159 
160 
161  if ( !FT_NEW( node ) )
162  {
163  node->face_id = query->face_id;
164  node->cmap_index = query->cmap_index;
165  node->first = (query->char_code / FTC_CMAP_INDICES_MAX) *
167 
168  for ( nn = 0; nn < FTC_CMAP_INDICES_MAX; nn++ )
169  node->indices[nn] = FTC_CMAP_UNKNOWN;
170  }
171 
172  *anode = node;
173  return error;
174  }
175 
176 
177  /* compute the weight of a given cmap node */
180  FTC_Cache cache )
181  {
182  FT_UNUSED( cnode );
183  FT_UNUSED( cache );
184 
185  return sizeof ( *cnode );
186  }
187 
188 
189  /* compare a cmap node to a given query */
192  FT_Pointer ftcquery,
193  FTC_Cache cache,
194  FT_Bool* list_changed )
195  {
196  FTC_CMapNode node = (FTC_CMapNode)ftcnode;
197  FTC_CMapQuery query = (FTC_CMapQuery)ftcquery;
198  FT_UNUSED( cache );
199 
200 
201  if ( list_changed )
202  *list_changed = FALSE;
203  if ( node->face_id == query->face_id &&
204  node->cmap_index == query->cmap_index )
205  {
206  FT_UInt32 offset = (FT_UInt32)( query->char_code - node->first );
207 
208 
209  return FT_BOOL( offset < FTC_CMAP_INDICES_MAX );
210  }
211 
212  return 0;
213  }
214 
215 
218  FT_Pointer ftcface_id,
219  FTC_Cache cache,
220  FT_Bool* list_changed )
221  {
222  FTC_CMapNode node = (FTC_CMapNode)ftcnode;
223  FTC_FaceID face_id = (FTC_FaceID)ftcface_id;
224  FT_UNUSED( cache );
225 
226 
227  if ( list_changed )
228  *list_changed = FALSE;
229  return FT_BOOL( node->face_id == face_id );
230  }
231 
232 
233  /*************************************************************************/
234  /*************************************************************************/
235  /***** *****/
236  /***** GLYPH IMAGE CACHE *****/
237  /***** *****/
238  /*************************************************************************/
239  /*************************************************************************/
240 
241 
244  {
250 
251  sizeof ( FTC_CacheRec ),
254  };
255 
256 
257  /* documentation is in ftcache.h */
258 
261  FTC_CMapCache *acache )
262  {
263  return FTC_Manager_RegisterCache( manager,
264  &ftc_cmap_cache_class,
265  FTC_CACHE_P( acache ) );
266  }
267 
268 
269 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
270 
271  /*
272  * Unfortunately, it is not possible to support binary backwards
273  * compatibility in the cmap cache. The FTC_CMapCache_Lookup signature
274  * changes were too deep, and there is no clever hackish way to detect
275  * what kind of structure we are being passed.
276  *
277  * On the other hand it seems that no production code is using this
278  * function on Unix distributions.
279  */
280 
281 #endif
282 
283 
284  /* documentation is in ftcache.h */
285 
288  FTC_FaceID face_id,
289  FT_Int cmap_index,
290  FT_UInt32 char_code )
291  {
292  FTC_Cache cache = FTC_CACHE( cmap_cache );
294  FTC_Node node;
295  FT_Error error;
296  FT_UInt gindex = 0;
297  FT_PtrDist hash;
298  FT_Int no_cmap_change = 0;
299 
300 
301  if ( cmap_index < 0 )
302  {
303  /* Treat a negative cmap index as a special value, meaning that you */
304  /* don't want to change the FT_Face's character map through this */
305  /* call. This can be useful if the face requester callback already */
306  /* sets the face's charmap to the appropriate value. */
307 
308  no_cmap_change = 1;
309  cmap_index = 0;
310  }
311 
312  if ( !cache )
313  {
314  FT_TRACE0(( "FTC_CMapCache_Lookup: bad arguments, returning 0\n" ));
315  return 0;
316  }
317 
318 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
319 
320  /*
321  * If cmap_index is greater than the maximum number of cachable
322  * charmaps, we assume the request is from a legacy rogue client
323  * using old internal header. See include/config/ftoption.h.
324  */
325  if ( cmap_index > FT_MAX_CHARMAP_CACHEABLE && !no_cmap_change )
326  {
327  FTC_OldCMapDesc desc = (FTC_OldCMapDesc) face_id;
328 
329 
330  char_code = (FT_UInt32)cmap_index;
331  query.face_id = desc->face_id;
332 
333 
334  switch ( desc->type )
335  {
336  case FTC_OLD_CMAP_BY_INDEX:
337  query.cmap_index = desc->u.index;
338  query.char_code = (FT_UInt32)cmap_index;
339  break;
340 
341  case FTC_OLD_CMAP_BY_ENCODING:
342  {
343  FT_Face face;
344 
345 
346  error = FTC_Manager_LookupFace( cache->manager, desc->face_id,
347  &face );
348  if ( error )
349  return 0;
350 
351  FT_Select_Charmap( face, desc->u.encoding );
352 
353  return FT_Get_Char_Index( face, char_code );
354  }
355 
356  default:
357  return 0;
358  }
359  }
360  else
361 
362 #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
363 
364  {
365  query.face_id = face_id;
366  query.cmap_index = (FT_UInt)cmap_index;
367  query.char_code = char_code;
368  }
369 
370  hash = FTC_CMAP_HASH( face_id, cmap_index, char_code );
371 
372 #if 1
374  node, error );
375 #else
376  error = FTC_Cache_Lookup( cache, hash, &query, &node );
377 #endif
378  if ( error )
379  goto Exit;
380 
381  FT_ASSERT( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first ) <
383 
384  /* something rotten can happen with rogue clients */
385  if ( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first >=
387  return 0; /* XXX: should return appropriate error */
388 
389  gindex = FTC_CMAP_NODE( node )->indices[char_code -
390  FTC_CMAP_NODE( node )->first];
391  if ( gindex == FTC_CMAP_UNKNOWN )
392  {
393  FT_Face face;
394 
395 
396  gindex = 0;
397 
399  FTC_CMAP_NODE( node )->face_id,
400  &face );
401  if ( error )
402  goto Exit;
403 
404 #ifdef FT_MAX_CHARMAP_CACHEABLE
405  /* something rotten can happen with rogue clients */
406  if ( cmap_index > FT_MAX_CHARMAP_CACHEABLE )
407  return 0; /* XXX: should return appropriate error */
408 #endif
409 
410  if ( (FT_UInt)cmap_index < (FT_UInt)face->num_charmaps )
411  {
412  FT_CharMap old, cmap = NULL;
413 
414 
415  old = face->charmap;
416  cmap = face->charmaps[cmap_index];
417 
418  if ( old != cmap && !no_cmap_change )
419  FT_Set_Charmap( face, cmap );
420 
421  gindex = FT_Get_Char_Index( face, char_code );
422 
423  if ( old != cmap && !no_cmap_change )
424  FT_Set_Charmap( face, old );
425  }
426 
427  FTC_CMAP_NODE( node )->indices[char_code -
428  FTC_CMAP_NODE( node )->first]
429  = (FT_UShort)gindex;
430  }
431 
432  Exit:
433  return gindex;
434  }
435 
436 
437 /* END */
int FT_Error
Definition: fttypes.h:296
ft_ptrdiff_t FT_PtrDist
Definition: fttypes.h:333
FTC_Manager manager
Definition: ftccache.h:158
struct FTC_CMapCacheRec_ * FTC_CMapCache
Definition: ftcache.h:571
FT_CharMap charmap
Definition: freetype.h:958
ftc_cmap_node_new(FTC_Node *ftcanode, FT_Pointer ftcquery, FTC_Cache cache)
Definition: ftccmap.c:149
unsigned short FT_UInt16
Definition: ftconfig.h:128
ftc_cmap_node_weight(FTC_Node cnode, FTC_Cache cache)
Definition: ftccmap.c:179
#define NULL
Definition: ftobjs.h:61
signed int FT_Int
Definition: fttypes.h:216
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:287
#define FTC_CMAP_NODE(x)
Definition: ftccmap.c:117
FT_CALLBACK_TABLE_DEF const FTC_CacheClassRec ftc_cmap_cache_class
Definition: ftccmap.c:243
#define FT_UNUSED(arg)
Definition: ftconfig.h:76
unsigned int FT_UInt32
Definition: ftconfig.h:133
ftc_cmap_node_compare(FTC_Node ftcnode, FT_Pointer ftcquery, FTC_Cache cache, FT_Bool *list_changed)
Definition: ftccmap.c:191
struct FTC_CMapNodeRec_ * FTC_CMapNode
#define FTC_CMAP_INDICES_MAX
Definition: ftccmap.c:86
ftc_cmap_node_free(FTC_Node ftcnode, FTC_Cache cache)
Definition: ftccmap.c:136
FT_BEGIN_HEADER typedef FT_Pointer FTC_FaceID
Definition: ftcache.h:171
ftc_cache_init(FTC_Cache cache)
Definition: ftccache.c:339
struct FTC_CMapQueryRec_ * FTC_CMapQuery
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:104
GLenum GLuint GLint GLenum face
#define FT_ASSERT(condition)
Definition: ftdebug.h:211
#define FTC_CMAP_UNKNOWN
Definition: ftccmap.c:123
GLenum GLuint id
FT_Int num_charmaps
Definition: freetype.h:935
#define FT_FREE(ptr)
Definition: ftmemory.h:286
FTC_Manager_RegisterCache(FTC_Manager manager, FTC_CacheClass clazz, FTC_Cache *acache)
Definition: ftcmanag.c:574
#define FT_EXPORT_DEF(x)
Definition: ftconfig.h:32
FT_Get_Char_Index(FT_Face face, FT_ULong charcode)
Definition: ftobjs.c:3302
FT_Error error
Definition: cffdrivr.c:411
void * FT_Pointer
Definition: fttypes.h:307
FT_Select_Charmap(FT_Face face, FT_Encoding encoding)
Definition: ftobjs.c:3066
#define FTC_CACHE(x)
Definition: ftccache.h:167
#define FTC_CMAP_HASH(faceid, index, charcode)
Definition: ftccmap.c:89
#define FT_CALLBACK_DEF(x)
Definition: ftconfig.h:323
#define FTC_CACHE_P(x)
Definition: ftccache.h:168
const GLint * first
GLintptr offset
#define FALSE
Definition: ftobjs.h:57
FT_CharMap * charmaps
Definition: freetype.h:936
FTC_CMapCache_New(FTC_Manager manager, FTC_CMapCache *acache)
Definition: ftccmap.c:260
enum FT_Encoding_ FT_Encoding
FT_Set_Charmap(FT_Face face, FT_CharMap charmap)
Definition: ftobjs.c:3117
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
#define FT_BOOL(x)
Definition: fttypes.h:574
struct FTC_CacheRec_ FTC_CacheRec
GLenum type
#define FTC_CACHE_LOOKUP_CMP(cache, nodecmp, hash, query, node, error)
Definition: ftccache.h:216
#define FT_CALLBACK_TABLE_DEF
Definition: ftconfig.h:333
unsigned int FT_UInt
Definition: fttypes.h:227
GLuint index
struct FTC_CMapNodeRec_ FTC_CMapNodeRec
GLuint GLuint GLsizei GLenum const GLvoid * indices
#define FT_NEW(ptr)
Definition: ftmemory.h:288
GLenum query
FT_TRACE0(("cff_property_set: missing property `%s'\, property_name))
unsigned short FT_UShort
Definition: fttypes.h:205
ftc_cache_done(FTC_Cache cache)
Definition: ftccache.c:393
FTC_Manager_LookupFace(FTC_Manager manager, FTC_FaceID face_id, FT_Face *aface)
Definition: ftcmanag.c:308
size_t FT_Offset
Definition: fttypes.h:320
ftc_cmap_node_remove_faceid(FTC_Node ftcnode, FT_Pointer ftcface_id, FTC_Cache cache, FT_Bool *list_changed)
Definition: ftccmap.c:217