~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/3rdparty/freetype/src/psaux/t1cmap.c

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************/
 
2
/*                                                                         */
 
3
/*  t1cmap.c                                                               */
 
4
/*                                                                         */
 
5
/*    Type 1 character map support (body).                                 */
 
6
/*                                                                         */
 
7
/*  Copyright 2002, 2003 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 "t1cmap.h"
 
20
 
 
21
#include FT_INTERNAL_DEBUG_H
 
22
 
 
23
#include "psauxerr.h"
 
24
 
 
25
 
 
26
  /*************************************************************************/
 
27
  /*************************************************************************/
 
28
  /*****                                                               *****/
 
29
  /*****          TYPE1 STANDARD (AND EXPERT) ENCODING CMAPS           *****/
 
30
  /*****                                                               *****/
 
31
  /*************************************************************************/
 
32
  /*************************************************************************/
 
33
 
 
34
  static void
 
35
  t1_cmap_std_init( T1_CMapStd  cmap,
 
36
                    FT_Int      is_expert )
 
37
  {
 
38
    T1_Face             face    = (T1_Face)FT_CMAP_FACE( cmap );
 
39
    FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)face->psnames;
 
40
 
 
41
 
 
42
    cmap->num_glyphs    = face->type1.num_glyphs;
 
43
    cmap->glyph_names   = (const char* const*)face->type1.glyph_names;
 
44
    cmap->sid_to_string = psnames->adobe_std_strings;
 
45
    cmap->code_to_sid   = is_expert ? psnames->adobe_expert_encoding
 
46
                                    : psnames->adobe_std_encoding;
 
47
 
 
48
    FT_ASSERT( cmap->code_to_sid != NULL );
 
49
  }
 
50
 
 
51
 
 
52
  FT_CALLBACK_DEF( void )
 
53
  t1_cmap_std_done( T1_CMapStd  cmap )
 
54
  {
 
55
    cmap->num_glyphs    = 0;
 
56
    cmap->glyph_names   = NULL;
 
57
    cmap->sid_to_string = NULL;
 
58
    cmap->code_to_sid   = NULL;
 
59
  }
 
60
 
 
61
 
 
62
  FT_CALLBACK_DEF( FT_UInt )
 
63
  t1_cmap_std_char_index( T1_CMapStd  cmap,
 
64
                          FT_UInt32   char_code )
 
65
  {
 
66
    FT_UInt  result = 0;
 
67
 
 
68
 
 
69
    if ( char_code < 256 )
 
70
    {
 
71
      FT_UInt      code, n;
 
72
      const char*  glyph_name;
 
73
 
 
74
 
 
75
      /* convert character code to Adobe SID string */
 
76
      code       = cmap->code_to_sid[char_code];
 
77
      glyph_name = cmap->sid_to_string( code );
 
78
 
 
79
      /* look for the corresponding glyph name */
 
80
      for ( n = 0; n < cmap->num_glyphs; n++ )
 
81
      {
 
82
        const char* gname = cmap->glyph_names[n];
 
83
 
 
84
 
 
85
        if ( gname && gname[0] == glyph_name[0]  &&
 
86
             ft_strcmp( gname, glyph_name ) == 0 )
 
87
        {
 
88
          result = n;
 
89
          break;
 
90
        }
 
91
      }
 
92
    }
 
93
 
 
94
    return result;
 
95
  }
 
96
 
 
97
 
 
98
  FT_CALLBACK_DEF( FT_UInt )
 
99
  t1_cmap_std_char_next( T1_CMapStd   cmap,
 
100
                         FT_UInt32   *pchar_code )
 
101
  {
 
102
    FT_UInt    result    = 0;
 
103
    FT_UInt32  char_code = *pchar_code + 1;
 
104
 
 
105
 
 
106
    while ( char_code < 256 )
 
107
    {
 
108
      result = t1_cmap_std_char_index( cmap, char_code );
 
109
      if ( result != 0 )
 
110
        goto Exit;
 
111
 
 
112
      char_code++;
 
113
    }
 
114
    char_code = 0;
 
115
 
 
116
  Exit:
 
117
    *pchar_code = char_code;
 
118
    return result;
 
119
  }
 
120
 
 
121
 
 
122
  FT_CALLBACK_DEF( FT_Error )
 
123
  t1_cmap_standard_init( T1_CMapStd  cmap )
 
124
  {
 
125
    t1_cmap_std_init( cmap, 0 );
 
126
    return 0;
 
127
  }
 
128
 
 
129
 
 
130
  FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
 
131
  t1_cmap_standard_class_rec =
 
132
  {
 
133
    sizeof ( T1_CMapStdRec ),
 
134
 
 
135
    (FT_CMap_InitFunc)     t1_cmap_standard_init,
 
136
    (FT_CMap_DoneFunc)     t1_cmap_std_done,
 
137
    (FT_CMap_CharIndexFunc)t1_cmap_std_char_index,
 
138
    (FT_CMap_CharNextFunc) t1_cmap_std_char_next
 
139
  };
 
140
 
 
141
 
 
142
  FT_CALLBACK_DEF( FT_Error )
 
143
  t1_cmap_expert_init( T1_CMapStd  cmap )
 
144
  {
 
145
    t1_cmap_std_init( cmap, 1 );
 
146
    return 0;
 
147
  }
 
148
 
 
149
  FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
 
150
  t1_cmap_expert_class_rec =
 
151
  {
 
152
    sizeof ( T1_CMapStdRec ),
 
153
 
 
154
    (FT_CMap_InitFunc)     t1_cmap_expert_init,
 
155
    (FT_CMap_DoneFunc)     t1_cmap_std_done,
 
156
    (FT_CMap_CharIndexFunc)t1_cmap_std_char_index,
 
157
    (FT_CMap_CharNextFunc) t1_cmap_std_char_next
 
158
  };
 
159
 
 
160
 
 
161
  /*************************************************************************/
 
162
  /*************************************************************************/
 
163
  /*****                                                               *****/
 
164
  /*****                    TYPE1 CUSTOM ENCODING CMAP                 *****/
 
165
  /*****                                                               *****/
 
166
  /*************************************************************************/
 
167
  /*************************************************************************/
 
168
 
 
169
 
 
170
  FT_CALLBACK_DEF( FT_Error )
 
171
  t1_cmap_custom_init( T1_CMapCustom  cmap )
 
172
  {
 
173
    T1_Face      face     = (T1_Face)FT_CMAP_FACE( cmap );
 
174
    T1_Encoding  encoding = &face->type1.encoding;
 
175
 
 
176
 
 
177
    cmap->first   = encoding->code_first;
 
178
    cmap->count   = (FT_UInt)( encoding->code_last - cmap->first + 1 );
 
179
    cmap->indices = encoding->char_index;
 
180
 
 
181
    FT_ASSERT( cmap->indices != NULL );
 
182
    FT_ASSERT( encoding->code_first <= encoding->code_last );
 
183
 
 
184
    return 0;
 
185
  }
 
186
 
 
187
 
 
188
  FT_CALLBACK_DEF( void )
 
189
  t1_cmap_custom_done( T1_CMapCustom  cmap )
 
190
  {
 
191
    cmap->indices = NULL;
 
192
    cmap->first   = 0;
 
193
    cmap->count   = 0;
 
194
  }
 
195
 
 
196
 
 
197
  FT_CALLBACK_DEF( FT_UInt )
 
198
  t1_cmap_custom_char_index( T1_CMapCustom  cmap,
 
199
                             FT_UInt32      char_code )
 
200
  {
 
201
    FT_UInt    result = 0;
 
202
 
 
203
 
 
204
    if ( ( char_code >= cmap->first )                  &&
 
205
         ( char_code < ( cmap->first + cmap->count ) ) )
 
206
      result = cmap->indices[char_code];
 
207
 
 
208
    return result;
 
209
  }
 
210
 
 
211
 
 
212
  FT_CALLBACK_DEF( FT_UInt )
 
213
  t1_cmap_custom_char_next( T1_CMapCustom  cmap,
 
214
                            FT_UInt32     *pchar_code )
 
215
  {
 
216
    FT_UInt    result = 0;
 
217
    FT_UInt32  char_code = *pchar_code;
 
218
 
 
219
 
 
220
    ++char_code;
 
221
 
 
222
    if ( char_code < cmap->first )
 
223
      char_code = cmap->first;
 
224
 
 
225
    for ( ; char_code < ( cmap->first + cmap->count ); char_code++ )
 
226
    {
 
227
      result = cmap->indices[char_code];
 
228
      if ( result != 0 )
 
229
        goto Exit;
 
230
    }
 
231
 
 
232
    char_code = 0;
 
233
 
 
234
  Exit:
 
235
    *pchar_code = char_code;
 
236
    return result;
 
237
  }
 
238
 
 
239
 
 
240
  FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
 
241
  t1_cmap_custom_class_rec =
 
242
  {
 
243
    sizeof ( T1_CMapCustomRec ),
 
244
 
 
245
    (FT_CMap_InitFunc)     t1_cmap_custom_init,
 
246
    (FT_CMap_DoneFunc)     t1_cmap_custom_done,
 
247
    (FT_CMap_CharIndexFunc)t1_cmap_custom_char_index,
 
248
    (FT_CMap_CharNextFunc) t1_cmap_custom_char_next
 
249
  };
 
250
 
 
251
 
 
252
  /*************************************************************************/
 
253
  /*************************************************************************/
 
254
  /*****                                                               *****/
 
255
  /*****            TYPE1 SYNTHETIC UNICODE ENCODING CMAP              *****/
 
256
  /*****                                                               *****/
 
257
  /*************************************************************************/
 
258
  /*************************************************************************/
 
259
 
 
260
  FT_CALLBACK_DEF( FT_Int )
 
261
  t1_cmap_uni_pair_compare( const void*  pair1,
 
262
                            const void*  pair2 )
 
263
  {
 
264
    FT_UInt32  u1 = ((T1_CMapUniPair)pair1)->unicode;
 
265
    FT_UInt32  u2 = ((T1_CMapUniPair)pair2)->unicode;
 
266
 
 
267
 
 
268
    if ( u1 < u2 )
 
269
      return -1;
 
270
 
 
271
    if ( u1 > u2 )
 
272
      return +1;
 
273
 
 
274
    return 0;
 
275
  }
 
276
 
 
277
 
 
278
  FT_CALLBACK_DEF( FT_Error )
 
279
  t1_cmap_unicode_init( T1_CMapUnicode  cmap )
 
280
  {
 
281
    FT_Error            error;
 
282
    FT_UInt             count;
 
283
    T1_Face             face    = (T1_Face)FT_CMAP_FACE( cmap );
 
284
    FT_Memory           memory  = FT_FACE_MEMORY( face );
 
285
    FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)face->psnames;
 
286
 
 
287
 
 
288
    cmap->num_pairs = 0;
 
289
    cmap->pairs     = NULL;
 
290
 
 
291
    count = face->type1.num_glyphs;
 
292
 
 
293
    if ( !FT_NEW_ARRAY( cmap->pairs, count ) )
 
294
    {
 
295
      FT_UInt         n, new_count;
 
296
      T1_CMapUniPair  pair;
 
297
      FT_UInt32       uni_code;
 
298
 
 
299
 
 
300
      pair = cmap->pairs;
 
301
      for ( n = 0; n < count; n++ )
 
302
      {
 
303
        const char*  gname = face->type1.glyph_names[n];
 
304
 
 
305
 
 
306
        /* build unsorted pair table by matching glyph names */
 
307
        if ( gname )
 
308
        {
 
309
          uni_code = psnames->unicode_value( gname );
 
310
 
 
311
          if ( uni_code != 0 )
 
312
          {
 
313
            pair->unicode = uni_code;
 
314
            pair->gindex  = n;
 
315
            pair++;
 
316
          }
 
317
        }
 
318
      }
 
319
 
 
320
      new_count = (FT_UInt)( pair - cmap->pairs );
 
321
      if ( new_count == 0 )
 
322
      {
 
323
        /* there are no unicode characters in here! */
 
324
        FT_FREE( cmap->pairs );
 
325
        error = PSaux_Err_Invalid_Argument;
 
326
      }
 
327
      else
 
328
      {
 
329
        /* re-allocate if the new array is much smaller than the original */
 
330
        /* one                                                            */
 
331
        if ( new_count != count && new_count < count / 2 )
 
332
        {
 
333
          (void)FT_RENEW_ARRAY( cmap->pairs, count, new_count );
 
334
          error = 0;
 
335
        }
 
336
 
 
337
        /* sort the pairs table to allow efficient binary searches */
 
338
        ft_qsort( cmap->pairs,
 
339
                  new_count,
 
340
                  sizeof ( T1_CMapUniPairRec ),
 
341
                  t1_cmap_uni_pair_compare );
 
342
 
 
343
        cmap->num_pairs = new_count;
 
344
      }
 
345
    }
 
346
 
 
347
    return error;
 
348
  }
 
349
 
 
350
 
 
351
  FT_CALLBACK_DEF( void )
 
352
  t1_cmap_unicode_done( T1_CMapUnicode  cmap )
 
353
  {
 
354
    FT_Face    face   = FT_CMAP_FACE(cmap);
 
355
    FT_Memory  memory = FT_FACE_MEMORY(face);
 
356
 
 
357
    FT_FREE( cmap->pairs );
 
358
    cmap->num_pairs = 0;
 
359
  }
 
360
 
 
361
 
 
362
  FT_CALLBACK_DEF( FT_UInt )
 
363
  t1_cmap_unicode_char_index( T1_CMapUnicode  cmap,
 
364
                              FT_UInt32       char_code )
 
365
  {
 
366
    FT_UInt         min = 0;
 
367
    FT_UInt         max = cmap->num_pairs;
 
368
    FT_UInt         mid;
 
369
    T1_CMapUniPair  pair;
 
370
 
 
371
 
 
372
    while ( min < max )
 
373
    {
 
374
      mid  = min + ( max - min ) / 2;
 
375
      pair = cmap->pairs + mid;
 
376
 
 
377
      if ( pair->unicode == char_code )
 
378
        return pair->gindex;
 
379
 
 
380
      if ( pair->unicode < char_code )
 
381
        min = mid + 1;
 
382
      else
 
383
        max = mid;
 
384
    }
 
385
    return 0;
 
386
  }
 
387
 
 
388
 
 
389
  FT_CALLBACK_DEF( FT_UInt )
 
390
  t1_cmap_unicode_char_next( T1_CMapUnicode  cmap,
 
391
                             FT_UInt32      *pchar_code )
 
392
  {
 
393
    FT_UInt    result    = 0;
 
394
    FT_UInt32  char_code = *pchar_code + 1;
 
395
 
 
396
 
 
397
  Restart:
 
398
    {
 
399
      FT_UInt         min = 0;
 
400
      FT_UInt         max = cmap->num_pairs;
 
401
      FT_UInt         mid;
 
402
      T1_CMapUniPair  pair;
 
403
 
 
404
 
 
405
      while ( min < max )
 
406
      {
 
407
        mid  = min + ( ( max - min ) >> 1 );
 
408
        pair = cmap->pairs + mid;
 
409
 
 
410
        if ( pair->unicode == char_code )
 
411
        {
 
412
          result = pair->gindex;
 
413
          if ( result != 0 )
 
414
            goto Exit;
 
415
 
 
416
          char_code++;
 
417
          goto Restart;
 
418
        }
 
419
 
 
420
        if ( pair->unicode < char_code )
 
421
          min = mid+1;
 
422
        else
 
423
          max = mid;
 
424
      }
 
425
 
 
426
      /* we didn't find it, but we have a pair just above it */
 
427
      char_code = 0;
 
428
 
 
429
      if ( min < cmap->num_pairs )
 
430
      {
 
431
        pair   = cmap->pairs + min;
 
432
        result = pair->gindex;
 
433
        if ( result != 0 )
 
434
          char_code = pair->unicode;
 
435
      }
 
436
    }
 
437
 
 
438
  Exit:
 
439
    *pchar_code = char_code;
 
440
    return result;
 
441
  }
 
442
 
 
443
 
 
444
  FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
 
445
  t1_cmap_unicode_class_rec =
 
446
  {
 
447
    sizeof ( T1_CMapUnicodeRec ),
 
448
 
 
449
    (FT_CMap_InitFunc)     t1_cmap_unicode_init,
 
450
    (FT_CMap_DoneFunc)     t1_cmap_unicode_done,
 
451
    (FT_CMap_CharIndexFunc)t1_cmap_unicode_char_index,
 
452
    (FT_CMap_CharNextFunc) t1_cmap_unicode_char_next
 
453
  };
 
454
 
 
455
 
 
456
/* END */