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]
psmodule.c
Go to the documentation of this file.
1 /***************************************************************************/
2 /* */
3 /* psmodule.c */
4 /* */
5 /* PSNames module implementation (body). */
6 /* */
7 /* Copyright 1996-2003, 2005-2008, 2012, 2013 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_INTERNAL_DEBUG_H
21 #include FT_INTERNAL_OBJECTS_H
22 #include FT_SERVICE_POSTSCRIPT_CMAPS_H
23 
24 #include "psmodule.h"
25 #include "pstables.h"
26 
27 #include "psnamerr.h"
28 #include "pspic.h"
29 
30 
31 #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
32 
33 
34 #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
35 
36 
37 #define VARIANT_BIT 0x80000000UL
38 #define BASE_GLYPH( code ) ( (FT_UInt32)( (code) & ~VARIANT_BIT ) )
39 
40 
41  /* Return the Unicode value corresponding to a given glyph. Note that */
42  /* we do deal with glyph variants by detecting a non-initial dot in */
43  /* the name, as in `A.swash' or `e.final'; in this case, the */
44  /* VARIANT_BIT is set in the return value. */
45  /* */
46  static FT_UInt32
47  ps_unicode_value( const char* glyph_name )
48  {
49  /* If the name begins with `uni', then the glyph name may be a */
50  /* hard-coded unicode character code. */
51  if ( glyph_name[0] == 'u' &&
52  glyph_name[1] == 'n' &&
53  glyph_name[2] == 'i' )
54  {
55  /* determine whether the next four characters following are */
56  /* hexadecimal. */
57 
58  /* XXX: Add code to deal with ligatures, i.e. glyph names like */
59  /* `uniXXXXYYYYZZZZ'... */
60 
61  FT_Int count;
62  FT_UInt32 value = 0;
63  const char* p = glyph_name + 3;
64 
65 
66  for ( count = 4; count > 0; count--, p++ )
67  {
68  char c = *p;
69  unsigned int d;
70 
71 
72  d = (unsigned char)c - '0';
73  if ( d >= 10 )
74  {
75  d = (unsigned char)c - 'A';
76  if ( d >= 6 )
77  d = 16;
78  else
79  d += 10;
80  }
81 
82  /* Exit if a non-uppercase hexadecimal character was found */
83  /* -- this also catches character codes below `0' since such */
84  /* negative numbers cast to `unsigned int' are far too big. */
85  if ( d >= 16 )
86  break;
87 
88  value = ( value << 4 ) + d;
89  }
90 
91  /* there must be exactly four hex digits */
92  if ( count == 0 )
93  {
94  if ( *p == '\0' )
95  return value;
96  if ( *p == '.' )
97  return (FT_UInt32)( value | VARIANT_BIT );
98  }
99  }
100 
101  /* If the name begins with `u', followed by four to six uppercase */
102  /* hexadecimal digits, it is a hard-coded unicode character code. */
103  if ( glyph_name[0] == 'u' )
104  {
105  FT_Int count;
106  FT_UInt32 value = 0;
107  const char* p = glyph_name + 1;
108 
109 
110  for ( count = 6; count > 0; count--, p++ )
111  {
112  char c = *p;
113  unsigned int d;
114 
115 
116  d = (unsigned char)c - '0';
117  if ( d >= 10 )
118  {
119  d = (unsigned char)c - 'A';
120  if ( d >= 6 )
121  d = 16;
122  else
123  d += 10;
124  }
125 
126  if ( d >= 16 )
127  break;
128 
129  value = ( value << 4 ) + d;
130  }
131 
132  if ( count <= 2 )
133  {
134  if ( *p == '\0' )
135  return value;
136  if ( *p == '.' )
137  return (FT_UInt32)( value | VARIANT_BIT );
138  }
139  }
140 
141  /* Look for a non-initial dot in the glyph name in order to */
142  /* find variants like `A.swash', `e.final', etc. */
143  {
144  const char* p = glyph_name;
145  const char* dot = NULL;
146 
147 
148  for ( ; *p; p++ )
149  {
150  if ( *p == '.' && p > glyph_name )
151  {
152  dot = p;
153  break;
154  }
155  }
156 
157  /* now look up the glyph in the Adobe Glyph List */
158  if ( !dot )
159  return (FT_UInt32)ft_get_adobe_glyph_index( glyph_name, p );
160  else
161  return (FT_UInt32)( ft_get_adobe_glyph_index( glyph_name, dot ) |
162  VARIANT_BIT );
163  }
164  }
165 
166 
167  /* ft_qsort callback to sort the unicode map */
168  FT_CALLBACK_DEF( int )
169  compare_uni_maps( const void* a,
170  const void* b )
171  {
172  PS_UniMap* map1 = (PS_UniMap*)a;
173  PS_UniMap* map2 = (PS_UniMap*)b;
174  FT_UInt32 unicode1 = BASE_GLYPH( map1->unicode );
175  FT_UInt32 unicode2 = BASE_GLYPH( map2->unicode );
176 
177 
178  /* sort base glyphs before glyph variants */
179  if ( unicode1 == unicode2 )
180  {
181  if ( map1->unicode > map2->unicode )
182  return 1;
183  else if ( map1->unicode < map2->unicode )
184  return -1;
185  else
186  return 0;
187  }
188  else
189  {
190  if ( unicode1 > unicode2 )
191  return 1;
192  else if ( unicode1 < unicode2 )
193  return -1;
194  else
195  return 0;
196  }
197  }
198 
199 
200  /* support for extra glyphs not handled (well) in AGL; */
201  /* we add extra mappings for them if necessary */
202 
203 #define EXTRA_GLYPH_LIST_SIZE 10
204 
205  static const FT_UInt32 ft_extra_glyph_unicodes[EXTRA_GLYPH_LIST_SIZE] =
206  {
207  /* WGL 4 */
208  0x0394,
209  0x03A9,
210  0x2215,
211  0x00AD,
212  0x02C9,
213  0x03BC,
214  0x2219,
215  0x00A0,
216  /* Romanian */
217  0x021A,
218  0x021B
219  };
220 
221  static const char ft_extra_glyph_names[] =
222  {
223  'D','e','l','t','a',0,
224  'O','m','e','g','a',0,
225  'f','r','a','c','t','i','o','n',0,
226  'h','y','p','h','e','n',0,
227  'm','a','c','r','o','n',0,
228  'm','u',0,
229  'p','e','r','i','o','d','c','e','n','t','e','r','e','d',0,
230  's','p','a','c','e',0,
231  'T','c','o','m','m','a','a','c','c','e','n','t',0,
232  't','c','o','m','m','a','a','c','c','e','n','t',0
233  };
234 
235  static const FT_Int
236  ft_extra_glyph_name_offsets[EXTRA_GLYPH_LIST_SIZE] =
237  {
238  0,
239  6,
240  12,
241  21,
242  28,
243  35,
244  38,
245  53,
246  59,
247  72
248  };
249 
250 
251  static void
252  ps_check_extra_glyph_name( const char* gname,
253  FT_UInt glyph,
254  FT_UInt* extra_glyphs,
255  FT_UInt *states )
256  {
257  FT_UInt n;
258 
259 
260  for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ )
261  {
262  if ( ft_strcmp( ft_extra_glyph_names +
263  ft_extra_glyph_name_offsets[n], gname ) == 0 )
264  {
265  if ( states[n] == 0 )
266  {
267  /* mark this extra glyph as a candidate for the cmap */
268  states[n] = 1;
269  extra_glyphs[n] = glyph;
270  }
271 
272  return;
273  }
274  }
275  }
276 
277 
278  static void
279  ps_check_extra_glyph_unicode( FT_UInt32 uni_char,
280  FT_UInt *states )
281  {
282  FT_UInt n;
283 
284 
285  for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ )
286  {
287  if ( uni_char == ft_extra_glyph_unicodes[n] )
288  {
289  /* disable this extra glyph from being added to the cmap */
290  states[n] = 2;
291 
292  return;
293  }
294  }
295  }
296 
297 
298  /* Build a table that maps Unicode values to glyph indices. */
299  static FT_Error
300  ps_unicodes_init( FT_Memory memory,
302  FT_UInt num_glyphs,
303  PS_GetGlyphNameFunc get_glyph_name,
304  PS_FreeGlyphNameFunc free_glyph_name,
305  FT_Pointer glyph_data )
306  {
307  FT_Error error;
308 
309  FT_UInt extra_glyph_list_states[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
310  FT_UInt extra_glyphs[EXTRA_GLYPH_LIST_SIZE];
311 
312 
313  /* we first allocate the table */
314  table->num_maps = 0;
315  table->maps = 0;
316 
317  if ( !FT_NEW_ARRAY( table->maps, num_glyphs + EXTRA_GLYPH_LIST_SIZE ) )
318  {
319  FT_UInt n;
320  FT_UInt count;
321  PS_UniMap* map;
322  FT_UInt32 uni_char;
323 
324 
325  map = table->maps;
326 
327  for ( n = 0; n < num_glyphs; n++ )
328  {
329  const char* gname = get_glyph_name( glyph_data, n );
330 
331 
332  if ( gname )
333  {
334  ps_check_extra_glyph_name( gname, n,
335  extra_glyphs, extra_glyph_list_states );
336  uni_char = ps_unicode_value( gname );
337 
338  if ( BASE_GLYPH( uni_char ) != 0 )
339  {
340  ps_check_extra_glyph_unicode( uni_char,
341  extra_glyph_list_states );
342  map->unicode = uni_char;
343  map->glyph_index = n;
344  map++;
345  }
346 
347  if ( free_glyph_name )
348  free_glyph_name( glyph_data, gname );
349  }
350  }
351 
352  for ( n = 0; n < EXTRA_GLYPH_LIST_SIZE; n++ )
353  {
354  if ( extra_glyph_list_states[n] == 1 )
355  {
356  /* This glyph name has an additional representation. */
357  /* Add it to the cmap. */
358 
359  map->unicode = ft_extra_glyph_unicodes[n];
360  map->glyph_index = extra_glyphs[n];
361  map++;
362  }
363  }
364 
365  /* now compress the table a bit */
366  count = (FT_UInt)( map - table->maps );
367 
368  if ( count == 0 )
369  {
370  /* No unicode chars here! */
371  FT_FREE( table->maps );
372  if ( !error )
373  error = FT_THROW( No_Unicode_Glyph_Name );
374  }
375  else
376  {
377  /* Reallocate if the number of used entries is much smaller. */
378  if ( count < num_glyphs / 2 )
379  {
380  (void)FT_RENEW_ARRAY( table->maps, num_glyphs, count );
381  error = FT_Err_Ok;
382  }
383 
384  /* Sort the table in increasing order of unicode values, */
385  /* taking care of glyph variants. */
386  ft_qsort( table->maps, count, sizeof ( PS_UniMap ),
387  compare_uni_maps );
388  }
389 
390  table->num_maps = count;
391  }
392 
393  return error;
394  }
395 
396 
397  static FT_UInt
398  ps_unicodes_char_index( PS_Unicodes table,
399  FT_UInt32 unicode )
400  {
401  PS_UniMap *min, *max, *mid, *result = NULL;
402 
403 
404  /* Perform a binary search on the table. */
405 
406  min = table->maps;
407  max = min + table->num_maps - 1;
408 
409  while ( min <= max )
410  {
411  FT_UInt32 base_glyph;
412 
413 
414  mid = min + ( ( max - min ) >> 1 );
415 
416  if ( mid->unicode == unicode )
417  {
418  result = mid;
419  break;
420  }
421 
422  base_glyph = BASE_GLYPH( mid->unicode );
423 
424  if ( base_glyph == unicode )
425  result = mid; /* remember match but continue search for base glyph */
426 
427  if ( min == max )
428  break;
429 
430  if ( base_glyph < unicode )
431  min = mid + 1;
432  else
433  max = mid - 1;
434  }
435 
436  if ( result )
437  return result->glyph_index;
438  else
439  return 0;
440  }
441 
442 
443  static FT_UInt32
444  ps_unicodes_char_next( PS_Unicodes table,
445  FT_UInt32 *unicode )
446  {
447  FT_UInt result = 0;
448  FT_UInt32 char_code = *unicode + 1;
449 
450 
451  {
452  FT_UInt min = 0;
453  FT_UInt max = table->num_maps;
454  FT_UInt mid;
455  PS_UniMap* map;
456  FT_UInt32 base_glyph;
457 
458 
459  while ( min < max )
460  {
461  mid = min + ( ( max - min ) >> 1 );
462  map = table->maps + mid;
463 
464  if ( map->unicode == char_code )
465  {
466  result = map->glyph_index;
467  goto Exit;
468  }
469 
470  base_glyph = BASE_GLYPH( map->unicode );
471 
472  if ( base_glyph == char_code )
473  result = map->glyph_index;
474 
475  if ( base_glyph < char_code )
476  min = mid + 1;
477  else
478  max = mid;
479  }
480 
481  if ( result )
482  goto Exit; /* we have a variant glyph */
483 
484  /* we didn't find it; check whether we have a map just above it */
485  char_code = 0;
486 
487  if ( min < table->num_maps )
488  {
489  map = table->maps + min;
490  result = map->glyph_index;
491  char_code = BASE_GLYPH( map->unicode );
492  }
493  }
494 
495  Exit:
496  *unicode = char_code;
497  return result;
498  }
499 
500 
501 #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
502 
503 
504  static const char*
505  ps_get_macintosh_name( FT_UInt name_index )
506  {
507  if ( name_index >= FT_NUM_MAC_NAMES )
508  name_index = 0;
509 
510  return ft_standard_glyph_names + ft_mac_names[name_index];
511  }
512 
513 
514  static const char*
515  ps_get_standard_strings( FT_UInt sid )
516  {
517  if ( sid >= FT_NUM_SID_NAMES )
518  return 0;
519 
520  return ft_standard_glyph_names + ft_sid_names[sid];
521  }
522 
523 
524 #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
525 
527  pscmaps_interface,
528  (PS_Unicode_ValueFunc) ps_unicode_value,
529  (PS_Unicodes_InitFunc) ps_unicodes_init,
530  (PS_Unicodes_CharIndexFunc)ps_unicodes_char_index,
531  (PS_Unicodes_CharNextFunc) ps_unicodes_char_next,
532 
533  (PS_Macintosh_NameFunc) ps_get_macintosh_name,
534  (PS_Adobe_Std_StringsFunc) ps_get_standard_strings,
535 
536  t1_standard_encoding,
537  t1_expert_encoding )
538 
539 #else
540 
542  pscmaps_interface,
543  NULL,
544  NULL,
545  NULL,
546  NULL,
547 
548  (PS_Macintosh_NameFunc) ps_get_macintosh_name,
549  (PS_Adobe_Std_StringsFunc) ps_get_standard_strings,
550 
551  t1_standard_encoding,
552  t1_expert_encoding )
553 
554 #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
555 
556 
558  pscmaps_services,
560 
561 
562  static FT_Pointer
563  psnames_get_service( FT_Module module,
564  const char* service_id )
565  {
566  /* PSCMAPS_SERVICES_GET derefers `library' in PIC mode */
567 #ifdef FT_CONFIG_OPTION_PIC
569 
570 
571  if ( !module )
572  return NULL;
573  library = module->library;
574  if ( !library )
575  return NULL;
576 #else
577  FT_UNUSED( module );
578 #endif
579 
580  return ft_service_list_lookup( PSCMAPS_SERVICES_GET, service_id );
581  }
582 
583 #endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
584 
585 
586 #ifndef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
587 #define PUT_PS_NAMES_SERVICE( a ) NULL
588 #else
589 #define PUT_PS_NAMES_SERVICE( a ) a
590 #endif
591 
593  psnames_module_class,
594 
595  0, /* this is not a font driver, nor a renderer */
596  sizeof ( FT_ModuleRec ),
597 
598  "psnames", /* driver name */
599  0x10000L, /* driver version */
600  0x20000L, /* driver requires FreeType 2 or above */
601 
603  (void*)&PSCMAPS_INTERFACE_GET ), /* module specific interface */
605  (FT_Module_Destructor) NULL,
606  (FT_Module_Requester) PUT_PS_NAMES_SERVICE( psnames_get_service ) )
607 
608 
609 /* END */
ft_service_list_lookup(FT_ServiceDesc service_descriptors, const char *service_id)
Definition: ftobjs.c:58
int FT_Error
Definition: fttypes.h:296
FT_Error(* FT_Module_Constructor)(FT_Module module)
Definition: ftmodapi.h:121
GLboolean GLboolean GLboolean GLboolean a
GLfloat GLfloat p
#define FT_DEFINE_MODULE( class_, flags_, size_, name_, version_, requires_, interface_, init_, done_, get_interface_)
Definition: ftobjs.h:1445
#define NULL
Definition: ftobjs.h:61
signed int FT_Int
Definition: fttypes.h:216
sizeof(AF_ModuleRec)
#define FT_NUM_MAC_NAMES
Definition: pstables.h:447
return FT_THROW(Missing_Property)
#define FT_UNUSED(arg)
Definition: ftconfig.h:76
FT_Library library
Definition: ftobjs.h:476
FT_UInt sid
Definition: cffcmap.c:130
#define FT_SERVICE_ID_POSTSCRIPT_CMAPS
Definition: svpscmap.h:28
unsigned int FT_UInt32
Definition: ftconfig.h:133
FT_Library library
Definition: cffdrivr.c:414
return FT_Err_Ok
Definition: ftbbox.c:645
#define FT_DEFINE_SERVICEDESCREC1(class_, serv_id_1, serv_data_1)
Definition: ftserv.h:196
typedef void(APIENTRY *GLDEBUGPROCARB)(GLenum source
GLboolean GLboolean GLboolean b
#define ft_qsort
Definition: ftstdlib.h:121
FT_Module_Interface(* FT_Module_Requester)(FT_Module module, const char *name)
Definition: ftmodapi.h:153
#define FT_DEFINE_SERVICE_PSCMAPSREC(class_, unicode_value_, unicodes_init_, unicodes_char_index_, unicodes_char_next_, macintosh_name_, adobe_std_strings_, adobe_std_encoding_, adobe_expert_encoding_)
Definition: svpscmap.h:123
float dot(float a, float b)
Definition: glsl_math.hpp:1111
#define FT_FREE(ptr)
Definition: ftmemory.h:286
PS_UniMap * maps
Definition: svpscmap.h:68
#define PSCMAPS_INTERFACE_GET
Definition: pspic.h:30
FT_Error error
Definition: cffdrivr.c:411
const char *(* PS_GetGlyphNameFunc)(FT_Pointer data, FT_UInt string_index)
Definition: svpscmap.h:78
FT_UInt glyph_index
Definition: svpscmap.h:57
const char *(* PS_Macintosh_NameFunc)(FT_UInt name_index)
Definition: svpscmap.h:41
void * FT_Pointer
Definition: fttypes.h:307
#define PUT_PS_NAMES_SERVICE(a)
Definition: psmodule.c:587
float min(float a, float b)
Definition: Vector2.hpp:307
GLdouble n
void(* PS_FreeGlyphNameFunc)(FT_Pointer data, const char *name)
Definition: svpscmap.h:86
const GLubyte * c
#define FT_CALLBACK_DEF(x)
Definition: ftconfig.h:323
#define FT_RENEW_ARRAY(ptr, curcnt, newcnt)
Definition: ftmemory.h:293
GLsizei const GLfloat * value
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
local int max
Definition: enough.c:170
#define FT_NEW_ARRAY(ptr, count)
Definition: ftmemory.h:290
const char *(* PS_Adobe_Std_StringsFunc)(FT_UInt string_index)
Definition: svpscmap.h:47
FT_UInt32(* PS_Unicodes_CharNextFunc)(PS_Unicodes unicodes, FT_UInt32 *unicode)
Definition: svpscmap.h:102
FT_Error(* PS_Unicodes_InitFunc)(FT_Memory memory, PS_Unicodes unicodes, FT_UInt num_glyphs, PS_GetGlyphNameFunc get_glyph_name, PS_FreeGlyphNameFunc free_glyph_name, FT_Pointer glyph_data)
Definition: svpscmap.h:90
#define PSCMAPS_SERVICES_GET
Definition: pspic.h:29
GLuint64EXT * result
unsigned int FT_UInt
Definition: fttypes.h:227
void(* FT_Module_Destructor)(FT_Module module)
Definition: ftmodapi.h:136
FT_UInt32 unicode
Definition: svpscmap.h:56
FT_UInt32(* PS_Unicode_ValueFunc)(const char *glyph_name)
Definition: svpscmap.h:35
GLuint GLuint GLsizei count
FT_UInt num_maps
Definition: svpscmap.h:67
#define FT_NUM_SID_NAMES
Definition: pstables.h:475
GLenum GLsizei GLenum GLenum const GLvoid * table
FT_UInt(* PS_Unicodes_CharIndexFunc)(PS_Unicodes unicodes, FT_UInt32 unicode)
Definition: svpscmap.h:98
#define ft_strcmp
Definition: ftstdlib.h:85