~ubuntu-branches/ubuntu/wily/qtbase-opensource-src/wily

« back to all changes in this revision

Viewing changes to src/3rdparty/freetype/src/bdf/bdfdrivr.c

  • Committer: Package Import Robot
  • Author(s): Timo Jyrinki
  • Date: 2013-02-05 12:46:17 UTC
  • Revision ID: package-import@ubuntu.com-20130205124617-c8jouts182j002fx
Tags: upstream-5.0.1+dfsg
ImportĀ upstreamĀ versionĀ 5.0.1+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  bdfdrivr.c
 
2
 
 
3
    FreeType font driver for bdf files
 
4
 
 
5
    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by
 
6
    Francesco Zappa Nardelli
 
7
 
 
8
Permission is hereby granted, free of charge, to any person obtaining a copy
 
9
of this software and associated documentation files (the "Software"), to deal
 
10
in the Software without restriction, including without limitation the rights
 
11
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
12
copies of the Software, and to permit persons to whom the Software is
 
13
furnished to do so, subject to the following conditions:
 
14
 
 
15
The above copyright notice and this permission notice shall be included in
 
16
all copies or substantial portions of the Software.
 
17
 
 
18
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
19
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
20
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 
21
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
22
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
23
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
24
THE SOFTWARE.
 
25
*/
 
26
 
 
27
#include <ft2build.h>
 
28
 
 
29
#include FT_INTERNAL_DEBUG_H
 
30
#include FT_INTERNAL_STREAM_H
 
31
#include FT_INTERNAL_OBJECTS_H
 
32
#include FT_BDF_H
 
33
 
 
34
#include FT_SERVICE_BDF_H
 
35
#include FT_SERVICE_XFREE86_NAME_H
 
36
 
 
37
#include "bdf.h"
 
38
#include "bdfdrivr.h"
 
39
 
 
40
#include "bdferror.h"
 
41
 
 
42
 
 
43
  /*************************************************************************/
 
44
  /*                                                                       */
 
45
  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
 
46
  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
 
47
  /* messages during execution.                                            */
 
48
  /*                                                                       */
 
49
#undef  FT_COMPONENT
 
50
#define FT_COMPONENT  trace_bdfdriver
 
51
 
 
52
 
 
53
  typedef struct  BDF_CMapRec_
 
54
  {
 
55
    FT_CMapRec        cmap;
 
56
    FT_UInt           num_encodings;
 
57
    BDF_encoding_el*  encodings;
 
58
 
 
59
  } BDF_CMapRec, *BDF_CMap;
 
60
 
 
61
 
 
62
  FT_CALLBACK_DEF( FT_Error )
 
63
  bdf_cmap_init( FT_CMap     bdfcmap,
 
64
                 FT_Pointer  init_data )
 
65
  {
 
66
    BDF_CMap  cmap = (BDF_CMap)bdfcmap;
 
67
    BDF_Face  face = (BDF_Face)FT_CMAP_FACE( cmap );
 
68
    FT_UNUSED( init_data );
 
69
 
 
70
 
 
71
    cmap->num_encodings = face->bdffont->glyphs_used;
 
72
    cmap->encodings     = face->en_table;
 
73
 
 
74
    return BDF_Err_Ok;
 
75
  }
 
76
 
 
77
 
 
78
  FT_CALLBACK_DEF( void )
 
79
  bdf_cmap_done( FT_CMap  bdfcmap )
 
80
  {
 
81
    BDF_CMap  cmap = (BDF_CMap)bdfcmap;
 
82
 
 
83
 
 
84
    cmap->encodings     = NULL;
 
85
    cmap->num_encodings = 0;
 
86
  }
 
87
 
 
88
 
 
89
  FT_CALLBACK_DEF( FT_UInt )
 
90
  bdf_cmap_char_index( FT_CMap    bdfcmap,
 
91
                       FT_UInt32  charcode )
 
92
  {
 
93
    BDF_CMap          cmap      = (BDF_CMap)bdfcmap;
 
94
    BDF_encoding_el*  encodings = cmap->encodings;
 
95
    FT_UInt           min, max, mid;
 
96
    FT_UInt           result    = 0;
 
97
 
 
98
 
 
99
    min = 0;
 
100
    max = cmap->num_encodings;
 
101
 
 
102
    while ( min < max )
 
103
    {
 
104
      FT_UInt32  code;
 
105
 
 
106
 
 
107
      mid  = ( min + max ) >> 1;
 
108
      code = encodings[mid].enc;
 
109
 
 
110
      if ( charcode == code )
 
111
      {
 
112
        /* increase glyph index by 1 --              */
 
113
        /* we reserve slot 0 for the undefined glyph */
 
114
        result = encodings[mid].glyph + 1;
 
115
        break;
 
116
      }
 
117
 
 
118
      if ( charcode < code )
 
119
        max = mid;
 
120
      else
 
121
        min = mid + 1;
 
122
    }
 
123
 
 
124
    return result;
 
125
  }
 
126
 
 
127
 
 
128
  FT_CALLBACK_DEF( FT_UInt )
 
129
  bdf_cmap_char_next( FT_CMap     bdfcmap,
 
130
                      FT_UInt32  *acharcode )
 
131
  {
 
132
    BDF_CMap          cmap      = (BDF_CMap)bdfcmap;
 
133
    BDF_encoding_el*  encodings = cmap->encodings;
 
134
    FT_UInt           min, max, mid;
 
135
    FT_UInt32         charcode = *acharcode + 1;
 
136
    FT_UInt           result   = 0;
 
137
 
 
138
 
 
139
    min = 0;
 
140
    max = cmap->num_encodings;
 
141
 
 
142
    while ( min < max )
 
143
    {
 
144
      FT_UInt32  code;
 
145
 
 
146
 
 
147
      mid  = ( min + max ) >> 1;
 
148
      code = encodings[mid].enc;
 
149
 
 
150
      if ( charcode == code )
 
151
      {
 
152
        /* increase glyph index by 1 --              */
 
153
        /* we reserve slot 0 for the undefined glyph */
 
154
        result = encodings[mid].glyph + 1;
 
155
        goto Exit;
 
156
      }
 
157
 
 
158
      if ( charcode < code )
 
159
        max = mid;
 
160
      else
 
161
        min = mid + 1;
 
162
    }
 
163
 
 
164
    charcode = 0;
 
165
    if ( min < cmap->num_encodings )
 
166
    {
 
167
      charcode = encodings[min].enc;
 
168
      result   = encodings[min].glyph + 1;
 
169
    }
 
170
 
 
171
  Exit:
 
172
    *acharcode = charcode;
 
173
    return result;
 
174
  }
 
175
 
 
176
 
 
177
  FT_CALLBACK_TABLE_DEF
 
178
  const FT_CMap_ClassRec  bdf_cmap_class =
 
179
  {
 
180
    sizeof ( BDF_CMapRec ),
 
181
    bdf_cmap_init,
 
182
    bdf_cmap_done,
 
183
    bdf_cmap_char_index,
 
184
    bdf_cmap_char_next,
 
185
 
 
186
    NULL, NULL, NULL, NULL, NULL
 
187
  };
 
188
 
 
189
 
 
190
  static FT_Error
 
191
  bdf_interpret_style( BDF_Face  bdf )
 
192
  {
 
193
    FT_Error         error  = BDF_Err_Ok;
 
194
    FT_Face          face   = FT_FACE( bdf );
 
195
    FT_Memory        memory = face->memory;
 
196
    bdf_font_t*      font   = bdf->bdffont;
 
197
    bdf_property_t*  prop;
 
198
 
 
199
    int    nn, len;
 
200
    char*  strings[4] = { NULL, NULL, NULL, NULL };
 
201
    int    lengths[4];
 
202
 
 
203
 
 
204
    face->style_flags = 0;
 
205
 
 
206
    prop = bdf_get_font_property( font, (char *)"SLANT" );
 
207
    if ( prop && prop->format == BDF_ATOM                             &&
 
208
         prop->value.atom                                             &&
 
209
         ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' ||
 
210
           *(prop->value.atom) == 'I' || *(prop->value.atom) == 'i' ) )
 
211
    {
 
212
      face->style_flags |= FT_STYLE_FLAG_ITALIC;
 
213
      strings[2] = ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' )
 
214
                   ? (char *)"Oblique"
 
215
                   : (char *)"Italic";
 
216
    }
 
217
 
 
218
    prop = bdf_get_font_property( font, (char *)"WEIGHT_NAME" );
 
219
    if ( prop && prop->format == BDF_ATOM                             &&
 
220
         prop->value.atom                                             &&
 
221
         ( *(prop->value.atom) == 'B' || *(prop->value.atom) == 'b' ) )
 
222
    {
 
223
      face->style_flags |= FT_STYLE_FLAG_BOLD;
 
224
      strings[1] = (char *)"Bold";
 
225
    }
 
226
 
 
227
    prop = bdf_get_font_property( font, (char *)"SETWIDTH_NAME" );
 
228
    if ( prop && prop->format == BDF_ATOM                              &&
 
229
         prop->value.atom && *(prop->value.atom)                       &&
 
230
         !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) )
 
231
      strings[3] = (char *)(prop->value.atom);
 
232
 
 
233
    prop = bdf_get_font_property( font, (char *)"ADD_STYLE_NAME" );
 
234
    if ( prop && prop->format == BDF_ATOM                              &&
 
235
         prop->value.atom && *(prop->value.atom)                       &&
 
236
         !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) )
 
237
      strings[0] = (char *)(prop->value.atom);
 
238
 
 
239
    len = 0;
 
240
 
 
241
    for ( len = 0, nn = 0; nn < 4; nn++ )
 
242
    {
 
243
      lengths[nn] = 0;
 
244
      if ( strings[nn] )
 
245
      {
 
246
        lengths[nn] = ft_strlen( strings[nn] );
 
247
        len        += lengths[nn] + 1;
 
248
      }
 
249
    }
 
250
 
 
251
    if ( len == 0 )
 
252
    {
 
253
      strings[0] = (char *)"Regular";
 
254
      lengths[0] = ft_strlen( strings[0] );
 
255
      len        = lengths[0] + 1;
 
256
    }
 
257
 
 
258
    {
 
259
      char*  s;
 
260
 
 
261
 
 
262
      if ( FT_ALLOC( face->style_name, len ) )
 
263
        return error;
 
264
 
 
265
      s = face->style_name;
 
266
 
 
267
      for ( nn = 0; nn < 4; nn++ )
 
268
      {
 
269
        char*  src = strings[nn];
 
270
 
 
271
 
 
272
        len = lengths[nn];
 
273
 
 
274
        if ( src == NULL )
 
275
          continue;
 
276
 
 
277
        /* separate elements with a space */
 
278
        if ( s != face->style_name )
 
279
          *s++ = ' ';
 
280
 
 
281
        ft_memcpy( s, src, len );
 
282
 
 
283
        /* need to convert spaces to dashes for */
 
284
        /* add_style_name and setwidth_name     */
 
285
        if ( nn == 0 || nn == 3 )
 
286
        {
 
287
          int  mm;
 
288
 
 
289
 
 
290
          for ( mm = 0; mm < len; mm++ )
 
291
            if ( s[mm] == ' ' )
 
292
              s[mm] = '-';
 
293
        }
 
294
 
 
295
        s += len;
 
296
      }
 
297
      *s = 0;
 
298
    }
 
299
 
 
300
    return error;
 
301
  }
 
302
 
 
303
 
 
304
  FT_CALLBACK_DEF( void )
 
305
  BDF_Face_Done( FT_Face  bdfface )         /* BDF_Face */
 
306
  {
 
307
    BDF_Face   face = (BDF_Face)bdfface;
 
308
    FT_Memory  memory;
 
309
 
 
310
 
 
311
    if ( !face )
 
312
      return;
 
313
 
 
314
    memory = FT_FACE_MEMORY( face );
 
315
 
 
316
    bdf_free_font( face->bdffont );
 
317
 
 
318
    FT_FREE( face->en_table );
 
319
 
 
320
    FT_FREE( face->charset_encoding );
 
321
    FT_FREE( face->charset_registry );
 
322
    FT_FREE( bdfface->family_name );
 
323
    FT_FREE( bdfface->style_name );
 
324
 
 
325
    FT_FREE( bdfface->available_sizes );
 
326
 
 
327
    FT_FREE( face->bdffont );
 
328
 
 
329
    FT_TRACE4(( "BDF_Face_Done: done face\n" ));
 
330
  }
 
331
 
 
332
 
 
333
  FT_CALLBACK_DEF( FT_Error )
 
334
  BDF_Face_Init( FT_Stream      stream,
 
335
                 FT_Face        bdfface,        /* BDF_Face */
 
336
                 FT_Int         face_index,
 
337
                 FT_Int         num_params,
 
338
                 FT_Parameter*  params )
 
339
  {
 
340
    FT_Error       error  = BDF_Err_Ok;
 
341
    BDF_Face       face   = (BDF_Face)bdfface;
 
342
    FT_Memory      memory = FT_FACE_MEMORY( face );
 
343
 
 
344
    bdf_font_t*    font = NULL;
 
345
    bdf_options_t  options;
 
346
 
 
347
    FT_UNUSED( num_params );
 
348
    FT_UNUSED( params );
 
349
    FT_UNUSED( face_index );
 
350
 
 
351
 
 
352
    if ( FT_STREAM_SEEK( 0 ) )
 
353
      goto Exit;
 
354
 
 
355
    options.correct_metrics = 1;   /* FZ XXX: options semantics */
 
356
    options.keep_unencoded  = 1;
 
357
    options.keep_comments   = 0;
 
358
    options.font_spacing    = BDF_PROPORTIONAL;
 
359
 
 
360
    error = bdf_load_font( stream, memory, &options, &font );
 
361
    if ( error == BDF_Err_Missing_Startfont_Field )
 
362
    {
 
363
      FT_TRACE2(( "[not a valid BDF file]\n" ));
 
364
      goto Fail;
 
365
    }
 
366
    else if ( error )
 
367
      goto Exit;
 
368
 
 
369
    /* we have a bdf font: let's construct the face object */
 
370
    face->bdffont = font;
 
371
    {
 
372
      bdf_property_t*  prop = NULL;
 
373
 
 
374
 
 
375
      FT_TRACE4(( "number of glyphs: %d (%d)\n",
 
376
                  font->glyphs_size,
 
377
                  font->glyphs_used ));
 
378
      FT_TRACE4(( "number of unencoded glyphs: %d (%d)\n",
 
379
                  font->unencoded_size,
 
380
                  font->unencoded_used ));
 
381
 
 
382
      bdfface->num_faces  = 1;
 
383
      bdfface->face_index = 0;
 
384
      bdfface->face_flags = FT_FACE_FLAG_FIXED_SIZES |
 
385
                            FT_FACE_FLAG_HORIZONTAL  |
 
386
                            FT_FACE_FLAG_FAST_GLYPHS;
 
387
 
 
388
      prop = bdf_get_font_property( font, "SPACING" );
 
389
      if ( prop && prop->format == BDF_ATOM                             &&
 
390
           prop->value.atom                                             &&
 
391
           ( *(prop->value.atom) == 'M' || *(prop->value.atom) == 'm' ||
 
392
             *(prop->value.atom) == 'C' || *(prop->value.atom) == 'c' ) )
 
393
        bdfface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
 
394
 
 
395
      /* FZ XXX: TO DO: FT_FACE_FLAGS_VERTICAL   */
 
396
      /* FZ XXX: I need a font to implement this */
 
397
 
 
398
      prop = bdf_get_font_property( font, "FAMILY_NAME" );
 
399
      if ( prop && prop->value.atom )
 
400
      {
 
401
        if ( FT_STRDUP( bdfface->family_name, prop->value.atom ) )
 
402
          goto Exit;
 
403
      }
 
404
      else
 
405
        bdfface->family_name = 0;
 
406
 
 
407
      if ( ( error = bdf_interpret_style( face ) ) != 0 )
 
408
        goto Exit;
 
409
 
 
410
      /* the number of glyphs (with one slot for the undefined glyph */
 
411
      /* at position 0 and all unencoded glyphs)                     */
 
412
      bdfface->num_glyphs = font->glyphs_size + 1;
 
413
 
 
414
      bdfface->num_fixed_sizes = 1;
 
415
      if ( FT_NEW_ARRAY( bdfface->available_sizes, 1 ) )
 
416
        goto Exit;
 
417
 
 
418
      {
 
419
        FT_Bitmap_Size*  bsize = bdfface->available_sizes;
 
420
        FT_Short         resolution_x = 0, resolution_y = 0;
 
421
 
 
422
 
 
423
        FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) );
 
424
 
 
425
        bsize->height = (FT_Short)( font->font_ascent + font->font_descent );
 
426
 
 
427
        prop = bdf_get_font_property( font, "AVERAGE_WIDTH" );
 
428
        if ( prop )
 
429
          bsize->width = (FT_Short)( ( prop->value.int32 + 5 ) / 10 );
 
430
        else
 
431
          bsize->width = (FT_Short)( bsize->height * 2/3 );
 
432
 
 
433
        prop = bdf_get_font_property( font, "POINT_SIZE" );
 
434
        if ( prop )
 
435
          /* convert from 722.7 decipoints to 72 points per inch */
 
436
          bsize->size =
 
437
            (FT_Pos)( ( prop->value.int32 * 64 * 7200 + 36135L ) / 72270L );
 
438
        else
 
439
          bsize->size = bsize->width << 6;
 
440
 
 
441
        prop = bdf_get_font_property( font, "PIXEL_SIZE" );
 
442
        if ( prop )
 
443
          bsize->y_ppem = (FT_Short)prop->value.int32 << 6;
 
444
 
 
445
        prop = bdf_get_font_property( font, "RESOLUTION_X" );
 
446
        if ( prop )
 
447
          resolution_x = (FT_Short)prop->value.int32;
 
448
 
 
449
        prop = bdf_get_font_property( font, "RESOLUTION_Y" );
 
450
        if ( prop )
 
451
          resolution_y = (FT_Short)prop->value.int32;
 
452
 
 
453
        if ( bsize->y_ppem == 0 )
 
454
        {
 
455
          bsize->y_ppem = bsize->size;
 
456
          if ( resolution_y )
 
457
            bsize->y_ppem = bsize->y_ppem * resolution_y / 72;
 
458
        }
 
459
        if ( resolution_x && resolution_y )
 
460
          bsize->x_ppem = bsize->y_ppem * resolution_x / resolution_y;
 
461
        else
 
462
          bsize->x_ppem = bsize->y_ppem;
 
463
      }
 
464
 
 
465
      /* encoding table */
 
466
      {
 
467
        bdf_glyph_t*   cur = font->glyphs;
 
468
        unsigned long  n;
 
469
 
 
470
 
 
471
        if ( FT_NEW_ARRAY( face->en_table, font->glyphs_size ) )
 
472
          goto Exit;
 
473
 
 
474
        face->default_glyph = 0;
 
475
        for ( n = 0; n < font->glyphs_size; n++ )
 
476
        {
 
477
          (face->en_table[n]).enc = cur[n].encoding;
 
478
          FT_TRACE4(( "idx %d, val 0x%lX\n", n, cur[n].encoding ));
 
479
          (face->en_table[n]).glyph = (FT_Short)n;
 
480
 
 
481
          if ( cur[n].encoding == font->default_char )
 
482
            face->default_glyph = n;
 
483
        }
 
484
      }
 
485
 
 
486
      /* charmaps */
 
487
      {
 
488
        bdf_property_t  *charset_registry = 0, *charset_encoding = 0;
 
489
        FT_Bool          unicode_charmap  = 0;
 
490
 
 
491
 
 
492
        charset_registry =
 
493
          bdf_get_font_property( font, "CHARSET_REGISTRY" );
 
494
        charset_encoding =
 
495
          bdf_get_font_property( font, "CHARSET_ENCODING" );
 
496
        if ( charset_registry && charset_encoding )
 
497
        {
 
498
          if ( charset_registry->format == BDF_ATOM &&
 
499
               charset_encoding->format == BDF_ATOM &&
 
500
               charset_registry->value.atom         &&
 
501
               charset_encoding->value.atom         )
 
502
          {
 
503
            const char*  s;
 
504
 
 
505
 
 
506
            if ( FT_STRDUP( face->charset_encoding,
 
507
                            charset_encoding->value.atom ) ||
 
508
                 FT_STRDUP( face->charset_registry,
 
509
                            charset_registry->value.atom ) )
 
510
              goto Exit;
 
511
 
 
512
            /* Uh, oh, compare first letters manually to avoid dependency */
 
513
            /* on locales.                                                */
 
514
            s = face->charset_registry;
 
515
            if ( ( s[0] == 'i' || s[0] == 'I' ) &&
 
516
                 ( s[1] == 's' || s[1] == 'S' ) &&
 
517
                 ( s[2] == 'o' || s[2] == 'O' ) )
 
518
            {
 
519
              s += 3;
 
520
              if ( !ft_strcmp( s, "10646" )                      ||
 
521
                   ( !ft_strcmp( s, "8859" ) &&
 
522
                     !ft_strcmp( face->charset_encoding, "1" ) ) )
 
523
              unicode_charmap = 1;
 
524
            }
 
525
 
 
526
            {
 
527
              FT_CharMapRec  charmap;
 
528
 
 
529
 
 
530
              charmap.face        = FT_FACE( face );
 
531
              charmap.encoding    = FT_ENCODING_NONE;
 
532
              charmap.platform_id = 0;
 
533
              charmap.encoding_id = 0;
 
534
 
 
535
              if ( unicode_charmap )
 
536
              {
 
537
                charmap.encoding    = FT_ENCODING_UNICODE;
 
538
                charmap.platform_id = 3;
 
539
                charmap.encoding_id = 1;
 
540
              }
 
541
 
 
542
              error = FT_CMap_New( &bdf_cmap_class, NULL, &charmap, NULL );
 
543
 
 
544
#if 0
 
545
              /* Select default charmap */
 
546
              if ( bdfface->num_charmaps )
 
547
                bdfface->charmap = bdfface->charmaps[0];
 
548
#endif
 
549
            }
 
550
 
 
551
            goto Exit;
 
552
          }
 
553
        }
 
554
 
 
555
        /* otherwise assume Adobe standard encoding */
 
556
 
 
557
        {
 
558
          FT_CharMapRec  charmap;
 
559
 
 
560
 
 
561
          charmap.face        = FT_FACE( face );
 
562
          charmap.encoding    = FT_ENCODING_ADOBE_STANDARD;
 
563
          charmap.platform_id = 7;
 
564
          charmap.encoding_id = 0;
 
565
 
 
566
          error = FT_CMap_New( &bdf_cmap_class, NULL, &charmap, NULL );
 
567
 
 
568
          /* Select default charmap */
 
569
          if ( bdfface->num_charmaps )
 
570
            bdfface->charmap = bdfface->charmaps[0];
 
571
        }
 
572
      }
 
573
    }
 
574
 
 
575
  Exit:
 
576
    return error;
 
577
 
 
578
  Fail:
 
579
    BDF_Face_Done( bdfface );
 
580
    return BDF_Err_Unknown_File_Format;
 
581
  }
 
582
 
 
583
 
 
584
  FT_CALLBACK_DEF( FT_Error )
 
585
  BDF_Size_Select( FT_Size   size,
 
586
                   FT_ULong  strike_index )
 
587
  {
 
588
    bdf_font_t*  bdffont = ( (BDF_Face)size->face )->bdffont;
 
589
 
 
590
 
 
591
    FT_Select_Metrics( size->face, strike_index );
 
592
 
 
593
    size->metrics.ascender    = bdffont->font_ascent << 6;
 
594
    size->metrics.descender   = -bdffont->font_descent << 6;
 
595
    size->metrics.max_advance = bdffont->bbx.width << 6;
 
596
 
 
597
    return BDF_Err_Ok;
 
598
  }
 
599
 
 
600
 
 
601
  FT_CALLBACK_DEF( FT_Error )
 
602
  BDF_Size_Request( FT_Size          size,
 
603
                    FT_Size_Request  req )
 
604
  {
 
605
    FT_Face          face    = size->face;
 
606
    FT_Bitmap_Size*  bsize   = face->available_sizes;
 
607
    bdf_font_t*      bdffont = ( (BDF_Face)face )->bdffont;
 
608
    FT_Error         error   = BDF_Err_Invalid_Pixel_Size;
 
609
    FT_Long          height;
 
610
 
 
611
 
 
612
    height = FT_REQUEST_HEIGHT( req );
 
613
    height = ( height + 32 ) >> 6;
 
614
 
 
615
    switch ( req->type )
 
616
    {
 
617
    case FT_SIZE_REQUEST_TYPE_NOMINAL:
 
618
      if ( height == ( ( bsize->y_ppem + 32 ) >> 6 ) )
 
619
        error = BDF_Err_Ok;
 
620
      break;
 
621
 
 
622
    case FT_SIZE_REQUEST_TYPE_REAL_DIM:
 
623
      if ( height == ( bdffont->font_ascent +
 
624
                       bdffont->font_descent ) )
 
625
        error = BDF_Err_Ok;
 
626
      break;
 
627
 
 
628
    default:
 
629
      error = BDF_Err_Unimplemented_Feature;
 
630
      break;
 
631
    }
 
632
 
 
633
    if ( error )
 
634
      return error;
 
635
    else
 
636
      return BDF_Size_Select( size, 0 );
 
637
  }
 
638
 
 
639
 
 
640
 
 
641
  FT_CALLBACK_DEF( FT_Error )
 
642
  BDF_Glyph_Load( FT_GlyphSlot  slot,
 
643
                  FT_Size       size,
 
644
                  FT_UInt       glyph_index,
 
645
                  FT_Int32      load_flags )
 
646
  {
 
647
    BDF_Face     bdf    = (BDF_Face)FT_SIZE_FACE( size );
 
648
    FT_Face      face   = FT_FACE( bdf );
 
649
    FT_Error     error  = BDF_Err_Ok;
 
650
    FT_Bitmap*   bitmap = &slot->bitmap;
 
651
    bdf_glyph_t  glyph;
 
652
    int          bpp    = bdf->bdffont->bpp;
 
653
 
 
654
    FT_UNUSED( load_flags );
 
655
 
 
656
 
 
657
    if ( !face || glyph_index >= (FT_UInt)face->num_glyphs )
 
658
    {
 
659
      error = BDF_Err_Invalid_Argument;
 
660
      goto Exit;
 
661
    }
 
662
 
 
663
    /* index 0 is the undefined glyph */
 
664
    if ( glyph_index == 0 )
 
665
      glyph_index = bdf->default_glyph;
 
666
    else
 
667
      glyph_index--;
 
668
 
 
669
    /* slot, bitmap => freetype, glyph => bdflib */
 
670
    glyph = bdf->bdffont->glyphs[glyph_index];
 
671
 
 
672
    bitmap->rows  = glyph.bbx.height;
 
673
    bitmap->width = glyph.bbx.width;
 
674
    bitmap->pitch = glyph.bpr;
 
675
 
 
676
    /* note: we don't allocate a new array to hold the bitmap; */
 
677
    /*       we can simply point to it                         */
 
678
    ft_glyphslot_set_bitmap( slot, glyph.bitmap );
 
679
 
 
680
    switch ( bpp )
 
681
    {
 
682
    case 1:
 
683
      bitmap->pixel_mode = FT_PIXEL_MODE_MONO;
 
684
      break;
 
685
    case 2:
 
686
      bitmap->pixel_mode = FT_PIXEL_MODE_GRAY2;
 
687
      break;
 
688
    case 4:
 
689
      bitmap->pixel_mode = FT_PIXEL_MODE_GRAY4;
 
690
      break;
 
691
    case 8:
 
692
      bitmap->pixel_mode = FT_PIXEL_MODE_GRAY;
 
693
      bitmap->num_grays  = 256;
 
694
      break;
 
695
    }
 
696
 
 
697
    slot->format      = FT_GLYPH_FORMAT_BITMAP;
 
698
    slot->bitmap_left = glyph.bbx.x_offset;
 
699
    slot->bitmap_top  = glyph.bbx.ascent;
 
700
 
 
701
    slot->metrics.horiAdvance  = glyph.dwidth << 6;
 
702
    slot->metrics.horiBearingX = glyph.bbx.x_offset << 6;
 
703
    slot->metrics.horiBearingY = glyph.bbx.ascent << 6;
 
704
    slot->metrics.width        = bitmap->width << 6;
 
705
    slot->metrics.height       = bitmap->rows << 6;
 
706
 
 
707
    /*
 
708
     * XXX DWIDTH1 and VVECTOR should be parsed and
 
709
     * used here, provided such fonts do exist.
 
710
     */
 
711
    ft_synthesize_vertical_metrics( &slot->metrics,
 
712
                                    bdf->bdffont->bbx.height << 6 );
 
713
 
 
714
  Exit:
 
715
    return error;
 
716
  }
 
717
 
 
718
 
 
719
 /*
 
720
  *
 
721
  *  BDF SERVICE
 
722
  *
 
723
  */
 
724
 
 
725
  static FT_Error
 
726
  bdf_get_bdf_property( BDF_Face          face,
 
727
                        const char*       prop_name,
 
728
                        BDF_PropertyRec  *aproperty )
 
729
  {
 
730
    bdf_property_t*  prop;
 
731
 
 
732
 
 
733
    FT_ASSERT( face && face->bdffont );
 
734
 
 
735
    prop = bdf_get_font_property( face->bdffont, prop_name );
 
736
    if ( prop )
 
737
    {
 
738
      switch ( prop->format )
 
739
      {
 
740
      case BDF_ATOM:
 
741
        aproperty->type   = BDF_PROPERTY_TYPE_ATOM;
 
742
        aproperty->u.atom = prop->value.atom;
 
743
        break;
 
744
 
 
745
      case BDF_INTEGER:
 
746
        aproperty->type      = BDF_PROPERTY_TYPE_INTEGER;
 
747
        aproperty->u.integer = prop->value.int32;
 
748
        break;
 
749
 
 
750
      case BDF_CARDINAL:
 
751
        aproperty->type       = BDF_PROPERTY_TYPE_CARDINAL;
 
752
        aproperty->u.cardinal = prop->value.card32;
 
753
        break;
 
754
 
 
755
      default:
 
756
        goto Fail;
 
757
      }
 
758
      return 0;
 
759
    }
 
760
 
 
761
  Fail:
 
762
    return BDF_Err_Invalid_Argument;
 
763
  }
 
764
 
 
765
 
 
766
  static FT_Error
 
767
  bdf_get_charset_id( BDF_Face      face,
 
768
                      const char*  *acharset_encoding,
 
769
                      const char*  *acharset_registry )
 
770
  {
 
771
    *acharset_encoding = face->charset_encoding;
 
772
    *acharset_registry = face->charset_registry;
 
773
 
 
774
    return 0;
 
775
  }
 
776
 
 
777
 
 
778
  static const FT_Service_BDFRec  bdf_service_bdf =
 
779
  {
 
780
    (FT_BDF_GetCharsetIdFunc)bdf_get_charset_id,
 
781
    (FT_BDF_GetPropertyFunc) bdf_get_bdf_property
 
782
  };
 
783
 
 
784
 
 
785
 /*
 
786
  *
 
787
  *  SERVICES LIST
 
788
  *
 
789
  */
 
790
 
 
791
  static const FT_ServiceDescRec  bdf_services[] =
 
792
  {
 
793
    { FT_SERVICE_ID_BDF,       &bdf_service_bdf },
 
794
    { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_BDF },
 
795
    { NULL, NULL }
 
796
  };
 
797
 
 
798
 
 
799
  FT_CALLBACK_DEF( FT_Module_Interface )
 
800
  bdf_driver_requester( FT_Module    module,
 
801
                        const char*  name )
 
802
  {
 
803
    FT_UNUSED( module );
 
804
 
 
805
    return ft_service_list_lookup( bdf_services, name );
 
806
  }
 
807
 
 
808
 
 
809
 
 
810
  FT_CALLBACK_TABLE_DEF
 
811
  const FT_Driver_ClassRec  bdf_driver_class =
 
812
  {
 
813
    {
 
814
      FT_MODULE_FONT_DRIVER         |
 
815
      FT_MODULE_DRIVER_NO_OUTLINES,
 
816
      sizeof ( FT_DriverRec ),
 
817
 
 
818
      "bdf",
 
819
      0x10000L,
 
820
      0x20000L,
 
821
 
 
822
      0,
 
823
 
 
824
      (FT_Module_Constructor)0,
 
825
      (FT_Module_Destructor) 0,
 
826
      (FT_Module_Requester)  bdf_driver_requester
 
827
    },
 
828
 
 
829
    sizeof ( BDF_FaceRec ),
 
830
    sizeof ( FT_SizeRec ),
 
831
    sizeof ( FT_GlyphSlotRec ),
 
832
 
 
833
    BDF_Face_Init,
 
834
    BDF_Face_Done,
 
835
    0,                          /* FT_Size_InitFunc */
 
836
    0,                          /* FT_Size_DoneFunc */
 
837
    0,                          /* FT_Slot_InitFunc */
 
838
    0,                          /* FT_Slot_DoneFunc */
 
839
 
 
840
#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
 
841
    ft_stub_set_char_sizes,
 
842
    ft_stub_set_pixel_sizes,
 
843
#endif
 
844
    BDF_Glyph_Load,
 
845
 
 
846
    0,                          /* FT_Face_GetKerningFunc   */
 
847
    0,                          /* FT_Face_AttachFunc       */
 
848
    0,                          /* FT_Face_GetAdvancesFunc  */
 
849
 
 
850
    BDF_Size_Request,
 
851
    BDF_Size_Select
 
852
  };
 
853
 
 
854
 
 
855
/* END */