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