~ubuntu-branches/ubuntu/wily/hedgewars/wily

« back to all changes in this revision

Viewing changes to misc/libfreetype/src/psnames/psmodule.c

  • Committer: Package Import Robot
  • Author(s): Dmitry E. Oboukhov
  • Date: 2011-09-23 10:16:55 UTC
  • mfrom: (1.2.11 upstream)
  • Revision ID: package-import@ubuntu.com-20110923101655-3977th2gc5n0a3pv
Tags: 0.9.16-1
* New upstream version.
 + Downloadable content! Simply click to install any content.
   New voices, hats, maps, themes, translations, music, scripts...
   Hedgewars is now more customisable than ever before! As time goes
   by we will be soliciting community content to feature on this page,
   so remember to check it from time to time. If you decide you want
   to go back to standard Hedgewars, just remove the Data directory
   from your Hedgewars config directory.
 + 3-D rendering! Diorama-like rendering of the game in a variety
   of 3D modes. Let us know which ones work best for you, we didn't
   really have the equipment to test them all.
 + Resizable game window.
 + New utilities! The Time Box will remove one of your hedgehogs
   from the game for a while, protecting from attack until it returns,
   somewhere else on the map. Land spray will allow you to build bridges,
   seal up holes, or just make life unpleasant for your enemies.
 + New single player: Bamboo Thicket, That Sinking Feeling, Newton and
   the Tree and multi-player: The Specialists, Space Invaders,
   Racer - scripts! And a ton more script hooks for scripters
 + New twists on old weapons. Drill strike, seduction and fire have
   been adjusted. Defective mines have been added, rope can attach to
   hogs/crates/barrels again, grenades now have variable bounce (use
   precise key + 1-5). Portal gun is now more usable in flight and
   all game actions are a lot faster.
 + New theme - Golf, dozens of new community hats and a new
   localised Default voice, Ukranian.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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,
 
300
                    PS_Unicodes           table,
 
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
 
 
519
    return ft_standard_glyph_names + ft_sid_names[sid];
 
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
 
 
533
    t1_standard_encoding,
 
534
    t1_expert_encoding
 
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
 
 
548
    t1_standard_encoding,
 
549
    t1_expert_encoding
 
550
  )
 
551
 
 
552
#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
 
553
 
 
554
 
 
555
  FT_DEFINE_SERVICEDESCREC1(pscmaps_services, 
 
556
    FT_SERVICE_ID_POSTSCRIPT_CMAPS, &FT_PSCMAPS_INTERFACE_GET
 
557
  )
 
558
 
 
559
 
 
560
 
 
561
 
 
562
  static FT_Pointer
 
563
  psnames_get_service( FT_Module    module,
 
564
                       const char*  service_id )
 
565
  {
 
566
    FT_UNUSED( module );
 
567
 
 
568
    return ft_service_list_lookup( FT_PSCMAPS_SERVICES_GET, service_id );
 
569
  }
 
570
 
 
571
#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
 
572
 
 
573
 
 
574
#ifndef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
 
575
#define PUT_PS_NAMES_SERVICE(a) 0
 
576
#else
 
577
#define PUT_PS_NAMES_SERVICE(a) a
 
578
#endif
 
579
 
 
580
  FT_DEFINE_MODULE(psnames_module_class,
 
581
  
 
582
    0,  /* this is not a font driver, nor a renderer */
 
583
    sizeof ( FT_ModuleRec ),
 
584
 
 
585
    "psnames",  /* driver name                         */
 
586
    0x10000L,   /* driver version                      */
 
587
    0x20000L,   /* driver requires FreeType 2 or above */
 
588
 
 
589
    PUT_PS_NAMES_SERVICE((void*)&FT_PSCMAPS_INTERFACE_GET),   /* module specific interface */
 
590
    (FT_Module_Constructor)0,
 
591
    (FT_Module_Destructor) 0,
 
592
    (FT_Module_Requester)  PUT_PS_NAMES_SERVICE(psnames_get_service)
 
593
  )
 
594
 
 
595
 
 
596
 
 
597
/* END */