Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3918 Serge 1
/***************************************************************************/
2
/*                                                                         */
3
/*  cffdrivr.c                                                             */
4
/*                                                                         */
5
/*    OpenType font driver implementation (body).                          */
6
/*                                                                         */
7
/*  Copyright 1996-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 
20
#include FT_FREETYPE_H
21
#include FT_INTERNAL_DEBUG_H
22
#include FT_INTERNAL_STREAM_H
23
#include FT_INTERNAL_SFNT_H
24
#include FT_SERVICE_CID_H
25
#include FT_SERVICE_POSTSCRIPT_INFO_H
26
#include FT_SERVICE_POSTSCRIPT_NAME_H
27
#include FT_SERVICE_TT_CMAP_H
28
 
29
#include "cffdrivr.h"
30
#include "cffgload.h"
31
#include "cffload.h"
32
#include "cffcmap.h"
33
#include "cffparse.h"
34
 
35
#include "cfferrs.h"
36
#include "cffpic.h"
37
 
38
#include FT_SERVICE_XFREE86_NAME_H
39
#include FT_SERVICE_GLYPH_DICT_H
40
#include FT_SERVICE_PROPERTIES_H
41
#include FT_CFF_DRIVER_H
42
 
43
 
44
  /*************************************************************************/
45
  /*                                                                       */
46
  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
47
  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
48
  /* messages during execution.                                            */
49
  /*                                                                       */
50
#undef  FT_COMPONENT
51
#define FT_COMPONENT  trace_cffdriver
52
 
53
 
54
  /*************************************************************************/
55
  /*************************************************************************/
56
  /*************************************************************************/
57
  /****                                                                 ****/
58
  /****                                                                 ****/
59
  /****                          F A C E S                              ****/
60
  /****                                                                 ****/
61
  /****                                                                 ****/
62
  /*************************************************************************/
63
  /*************************************************************************/
64
  /*************************************************************************/
65
 
66
 
67
#undef  PAIR_TAG
68
#define PAIR_TAG( left, right )  ( ( (FT_ULong)left << 16 ) | \
69
                                     (FT_ULong)right        )
70
 
71
 
72
  /*************************************************************************/
73
  /*                                                                       */
74
  /*                                                             */
75
  /*    cff_get_kerning                                                    */
76
  /*                                                                       */
77
  /*                                                          */
78
  /*    A driver method used to return the kerning vector between two      */
79
  /*    glyphs of the same face.                                           */
80
  /*                                                                       */
81
  /*                                                                */
82
  /*    face        :: A handle to the source face object.                 */
83
  /*                                                                       */
84
  /*    left_glyph  :: The index of the left glyph in the kern pair.       */
85
  /*                                                                       */
86
  /*    right_glyph :: The index of the right glyph in the kern pair.      */
87
  /*                                                                       */
88
  /*                                                               */
89
  /*    kerning     :: The kerning vector.  This is in font units for      */
90
  /*                   scalable formats, and in pixels for fixed-sizes     */
91
  /*                   formats.                                            */
92
  /*                                                                       */
93
  /*                                                               */
94
  /*    FreeType error code.  0 means success.                             */
95
  /*                                                                       */
96
  /*                                                                 */
97
  /*    Only horizontal layouts (left-to-right & right-to-left) are        */
98
  /*    supported by this function.  Other layouts, or more sophisticated  */
99
  /*    kernings, are out of scope of this method (the basic driver        */
100
  /*    interface is meant to be simple).                                  */
101
  /*                                                                       */
102
  /*    They can be implemented by format-specific interfaces.             */
103
  /*                                                                       */
104
  FT_CALLBACK_DEF( FT_Error )
105
  cff_get_kerning( FT_Face     ttface,          /* TT_Face */
106
                   FT_UInt     left_glyph,
107
                   FT_UInt     right_glyph,
108
                   FT_Vector*  kerning )
109
  {
110
    TT_Face       face = (TT_Face)ttface;
111
    SFNT_Service  sfnt = (SFNT_Service)face->sfnt;
112
 
113
 
114
    kerning->x = 0;
115
    kerning->y = 0;
116
 
117
    if ( sfnt )
118
      kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph );
119
 
120
    return FT_Err_Ok;
121
  }
122
 
123
 
124
#undef PAIR_TAG
125
 
126
 
127
  /*************************************************************************/
128
  /*                                                                       */
129
  /*                                                             */
130
  /*    cff_glyph_load                                                     */
131
  /*                                                                       */
132
  /*                                                          */
133
  /*    A driver method used to load a glyph within a given glyph slot.    */
134
  /*                                                                       */
135
  /*                                                                */
136
  /*    slot        :: A handle to the target slot object where the glyph  */
137
  /*                   will be loaded.                                     */
138
  /*                                                                       */
139
  /*    size        :: A handle to the source face size at which the glyph */
140
  /*                   must be scaled, loaded, etc.                        */
141
  /*                                                                       */
142
  /*    glyph_index :: The index of the glyph in the font file.            */
143
  /*                                                                       */
144
  /*    load_flags  :: A flag indicating what to load for this glyph.  The */
145
  /*                   FT_LOAD_??? constants can be used to control the    */
146
  /*                   glyph loading process (e.g., whether the outline    */
147
  /*                   should be scaled, whether to load bitmaps or not,   */
148
  /*                   whether to hint the outline, etc).                  */
149
  /*                                                                       */
150
  /*                                                               */
151
  /*    FreeType error code.  0 means success.                             */
152
  /*                                                                       */
153
  FT_CALLBACK_DEF( FT_Error )
154
  cff_glyph_load( FT_GlyphSlot  cffslot,      /* CFF_GlyphSlot */
155
                  FT_Size       cffsize,      /* CFF_Size      */
156
                  FT_UInt       glyph_index,
157
                  FT_Int32      load_flags )
158
  {
159
    FT_Error       error;
160
    CFF_GlyphSlot  slot = (CFF_GlyphSlot)cffslot;
161
    CFF_Size       size = (CFF_Size)cffsize;
162
 
163
 
164
    if ( !slot )
165
      return FT_THROW( Invalid_Slot_Handle );
166
 
167
    /* check whether we want a scaled outline or bitmap */
168
    if ( !size )
169
      load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
170
 
171
    /* reset the size object if necessary */
172
    if ( load_flags & FT_LOAD_NO_SCALE )
173
      size = NULL;
174
 
175
    if ( size )
176
    {
177
      /* these two objects must have the same parent */
178
      if ( cffsize->face != cffslot->face )
179
        return FT_THROW( Invalid_Face_Handle );
180
    }
181
 
182
    /* now load the glyph outline if necessary */
183
    error = cff_slot_load( slot, size, glyph_index, load_flags );
184
 
185
    /* force drop-out mode to 2 - irrelevant now */
186
    /* slot->outline.dropout_mode = 2; */
187
 
188
    return error;
189
  }
190
 
191
 
192
  FT_CALLBACK_DEF( FT_Error )
193
  cff_get_advances( FT_Face    face,
194
                    FT_UInt    start,
195
                    FT_UInt    count,
196
                    FT_Int32   flags,
197
                    FT_Fixed*  advances )
198
  {
199
    FT_UInt       nn;
200
    FT_Error      error = FT_Err_Ok;
201
    FT_GlyphSlot  slot  = face->glyph;
202
 
203
 
204
    flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY;
205
 
206
    for ( nn = 0; nn < count; nn++ )
207
    {
208
      error = cff_glyph_load( slot, face->size, start + nn, flags );
209
      if ( error )
210
        break;
211
 
212
      advances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT )
213
                     ? slot->linearVertAdvance
214
                     : slot->linearHoriAdvance;
215
    }
216
 
217
    return error;
218
  }
219
 
220
 
221
  /*
222
   *  GLYPH DICT SERVICE
223
   *
224
   */
225
 
226
  static FT_Error
227
  cff_get_glyph_name( CFF_Face    face,
228
                      FT_UInt     glyph_index,
229
                      FT_Pointer  buffer,
230
                      FT_UInt     buffer_max )
231
  {
232
    CFF_Font    font   = (CFF_Font)face->extra.data;
233
    FT_String*  gname;
234
    FT_UShort   sid;
235
    FT_Error    error;
236
 
237
 
238
    if ( !font->psnames )
239
    {
240
      FT_ERROR(( "cff_get_glyph_name:"
241
                 " cannot get glyph name from CFF & CEF fonts\n"
242
                 "                   "
243
                 " without the `PSNames' module\n" ));
244
      error = FT_THROW( Missing_Module );
245
      goto Exit;
246
    }
247
 
248
    /* first, locate the sid in the charset table */
249
    sid = font->charset.sids[glyph_index];
250
 
251
    /* now, lookup the name itself */
252
    gname = cff_index_get_sid_string( font, sid );
253
 
254
    if ( gname )
255
      FT_STRCPYN( buffer, gname, buffer_max );
256
 
257
    error = FT_Err_Ok;
258
 
259
  Exit:
260
    return error;
261
  }
262
 
263
 
264
  static FT_UInt
265
  cff_get_name_index( CFF_Face    face,
266
                      FT_String*  glyph_name )
267
  {
268
    CFF_Font            cff;
269
    CFF_Charset         charset;
270
    FT_Service_PsCMaps  psnames;
271
    FT_String*          name;
272
    FT_UShort           sid;
273
    FT_UInt             i;
274
 
275
 
276
    cff     = (CFF_FontRec *)face->extra.data;
277
    charset = &cff->charset;
278
 
279
    FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
280
    if ( !psnames )
281
      return 0;
282
 
283
    for ( i = 0; i < cff->num_glyphs; i++ )
284
    {
285
      sid = charset->sids[i];
286
 
287
      if ( sid > 390 )
288
        name = cff_index_get_string( cff, sid - 391 );
289
      else
290
        name = (FT_String *)psnames->adobe_std_strings( sid );
291
 
292
      if ( !name )
293
        continue;
294
 
295
      if ( !ft_strcmp( glyph_name, name ) )
296
        return i;
297
    }
298
 
299
    return 0;
300
  }
301
 
302
 
303
  FT_DEFINE_SERVICE_GLYPHDICTREC(
304
    cff_service_glyph_dict,
305
    (FT_GlyphDict_GetNameFunc)  cff_get_glyph_name,
306
    (FT_GlyphDict_NameIndexFunc)cff_get_name_index
307
  )
308
 
309
 
310
  /*
311
   *  POSTSCRIPT INFO SERVICE
312
   *
313
   */
314
 
315
  static FT_Int
316
  cff_ps_has_glyph_names( FT_Face  face )
317
  {
318
    return ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) > 0;
319
  }
320
 
321
 
322
  static FT_Error
323
  cff_ps_get_font_info( CFF_Face         face,
324
                        PS_FontInfoRec*  afont_info )
325
  {
326
    CFF_Font  cff   = (CFF_Font)face->extra.data;
327
    FT_Error  error = FT_Err_Ok;
328
 
329
 
330
    if ( cff && cff->font_info == NULL )
331
    {
332
      CFF_FontRecDict  dict   = &cff->top_font.font_dict;
333
      PS_FontInfoRec  *font_info = NULL;
334
      FT_Memory        memory = face->root.memory;
335
 
336
 
337
      if ( FT_ALLOC( font_info, sizeof ( *font_info ) ) )
338
        goto Fail;
339
 
340
      font_info->version     = cff_index_get_sid_string( cff,
341
                                                         dict->version );
342
      font_info->notice      = cff_index_get_sid_string( cff,
343
                                                         dict->notice );
344
      font_info->full_name   = cff_index_get_sid_string( cff,
345
                                                         dict->full_name );
346
      font_info->family_name = cff_index_get_sid_string( cff,
347
                                                         dict->family_name );
348
      font_info->weight      = cff_index_get_sid_string( cff,
349
                                                         dict->weight );
350
      font_info->italic_angle        = dict->italic_angle;
351
      font_info->is_fixed_pitch      = dict->is_fixed_pitch;
352
      font_info->underline_position  = (FT_Short)dict->underline_position;
353
      font_info->underline_thickness = (FT_Short)dict->underline_thickness;
354
 
355
      cff->font_info = font_info;
356
    }
357
 
358
    if ( cff )
359
      *afont_info = *cff->font_info;
360
 
361
  Fail:
362
    return error;
363
  }
364
 
365
 
366
  FT_DEFINE_SERVICE_PSINFOREC(
367
    cff_service_ps_info,
368
    (PS_GetFontInfoFunc)   cff_ps_get_font_info,
369
    (PS_GetFontExtraFunc)  NULL,
370
    (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names,
371
    (PS_GetFontPrivateFunc)NULL,        /* unsupported with CFF fonts */
372
    (PS_GetFontValueFunc)  NULL         /* not implemented            */
373
  )
374
 
375
 
376
  /*
377
   *  POSTSCRIPT NAME SERVICE
378
   *
379
   */
380
 
381
  static const char*
382
  cff_get_ps_name( CFF_Face  face )
383
  {
384
    CFF_Font  cff = (CFF_Font)face->extra.data;
385
 
386
 
387
    return (const char*)cff->font_name;
388
  }
389
 
390
 
391
  FT_DEFINE_SERVICE_PSFONTNAMEREC(
392
    cff_service_ps_name,
393
    (FT_PsName_GetFunc)cff_get_ps_name
394
  )
395
 
396
 
397
  /*
398
   * TT CMAP INFO
399
   *
400
   * If the charmap is a synthetic Unicode encoding cmap or
401
   * a Type 1 standard (or expert) encoding cmap, hide TT CMAP INFO
402
   * service defined in SFNT module.
403
   *
404
   * Otherwise call the service function in the sfnt module.
405
   *
406
   */
407
  static FT_Error
408
  cff_get_cmap_info( FT_CharMap    charmap,
409
                     TT_CMapInfo  *cmap_info )
410
  {
411
    FT_CMap   cmap  = FT_CMAP( charmap );
412
    FT_Error  error = FT_Err_Ok;
413
 
414
    FT_Face     face    = FT_CMAP_FACE( cmap );
415
    FT_Library  library = FT_FACE_LIBRARY( face );
416
 
417
 
418
    cmap_info->language = 0;
419
    cmap_info->format   = 0;
420
 
421
    if ( cmap->clazz != &CFF_CMAP_ENCODING_CLASS_REC_GET &&
422
         cmap->clazz != &CFF_CMAP_UNICODE_CLASS_REC_GET  )
423
    {
424
      FT_Module           sfnt    = FT_Get_Module( library, "sfnt" );
425
      FT_Service_TTCMaps  service =
426
        (FT_Service_TTCMaps)ft_module_get_service( sfnt,
427
                                                   FT_SERVICE_ID_TT_CMAP );
428
 
429
 
430
      if ( service && service->get_cmap_info )
431
        error = service->get_cmap_info( charmap, cmap_info );
432
    }
433
 
434
    return error;
435
  }
436
 
437
 
438
  FT_DEFINE_SERVICE_TTCMAPSREC(
439
    cff_service_get_cmap_info,
440
    (TT_CMap_Info_GetFunc)cff_get_cmap_info
441
  )
442
 
443
 
444
  /*
445
   *  CID INFO SERVICE
446
   *
447
   */
448
  static FT_Error
449
  cff_get_ros( CFF_Face      face,
450
               const char*  *registry,
451
               const char*  *ordering,
452
               FT_Int       *supplement )
453
  {
454
    FT_Error  error = FT_Err_Ok;
455
    CFF_Font  cff   = (CFF_Font)face->extra.data;
456
 
457
 
458
    if ( cff )
459
    {
460
      CFF_FontRecDict  dict = &cff->top_font.font_dict;
461
 
462
 
463
      if ( dict->cid_registry == 0xFFFFU )
464
      {
465
        error = FT_THROW( Invalid_Argument );
466
        goto Fail;
467
      }
468
 
469
      if ( registry )
470
      {
471
        if ( cff->registry == NULL )
472
          cff->registry = cff_index_get_sid_string( cff,
473
                                                    dict->cid_registry );
474
        *registry = cff->registry;
475
      }
476
 
477
      if ( ordering )
478
      {
479
        if ( cff->ordering == NULL )
480
          cff->ordering = cff_index_get_sid_string( cff,
481
                                                    dict->cid_ordering );
482
        *ordering = cff->ordering;
483
      }
484
 
485
      /*
486
       * XXX: According to Adobe TechNote #5176, the supplement in CFF
487
       *      can be a real number. We truncate it to fit public API
488
       *      since freetype-2.3.6.
489
       */
490
      if ( supplement )
491
      {
492
        if ( dict->cid_supplement < FT_INT_MIN ||
493
             dict->cid_supplement > FT_INT_MAX )
494
          FT_TRACE1(( "cff_get_ros: too large supplement %d is truncated\n",
495
                      dict->cid_supplement ));
496
        *supplement = (FT_Int)dict->cid_supplement;
497
      }
498
    }
499
 
500
  Fail:
501
    return error;
502
  }
503
 
504
 
505
  static FT_Error
506
  cff_get_is_cid( CFF_Face  face,
507
                  FT_Bool  *is_cid )
508
  {
509
    FT_Error  error = FT_Err_Ok;
510
    CFF_Font  cff   = (CFF_Font)face->extra.data;
511
 
512
 
513
    *is_cid = 0;
514
 
515
    if ( cff )
516
    {
517
      CFF_FontRecDict  dict = &cff->top_font.font_dict;
518
 
519
 
520
      if ( dict->cid_registry != 0xFFFFU )
521
        *is_cid = 1;
522
    }
523
 
524
    return error;
525
  }
526
 
527
 
528
  static FT_Error
529
  cff_get_cid_from_glyph_index( CFF_Face  face,
530
                                FT_UInt   glyph_index,
531
                                FT_UInt  *cid )
532
  {
533
    FT_Error  error = FT_Err_Ok;
534
    CFF_Font  cff;
535
 
536
 
537
    cff = (CFF_Font)face->extra.data;
538
 
539
    if ( cff )
540
    {
541
      FT_UInt          c;
542
      CFF_FontRecDict  dict = &cff->top_font.font_dict;
543
 
544
 
545
      if ( dict->cid_registry == 0xFFFFU )
546
      {
547
        error = FT_THROW( Invalid_Argument );
548
        goto Fail;
549
      }
550
 
551
      if ( glyph_index > cff->num_glyphs )
552
      {
553
        error = FT_THROW( Invalid_Argument );
554
        goto Fail;
555
      }
556
 
557
      c = cff->charset.sids[glyph_index];
558
 
559
      if ( cid )
560
        *cid = c;
561
    }
562
 
563
  Fail:
564
    return error;
565
  }
566
 
567
 
568
  FT_DEFINE_SERVICE_CIDREC(
569
    cff_service_cid_info,
570
    (FT_CID_GetRegistryOrderingSupplementFunc)cff_get_ros,
571
    (FT_CID_GetIsInternallyCIDKeyedFunc)      cff_get_is_cid,
572
    (FT_CID_GetCIDFromGlyphIndexFunc)         cff_get_cid_from_glyph_index
573
  )
574
 
575
 
576
  /*
577
   *  PROPERTY SERVICE
578
   *
579
   */
580
  static FT_Error
581
  cff_property_set( FT_Module    module,         /* CFF_Driver */
582
                    const char*  property_name,
583
                    const void*  value )
584
  {
585
    FT_Error    error  = FT_Err_Ok;
586
    CFF_Driver  driver = (CFF_Driver)module;
587
 
588
 
589
    if ( !ft_strcmp( property_name, "hinting-engine" ) )
590
    {
591
      FT_UInt*  hinting_engine = (FT_UInt*)value;
592
 
593
 
594
#ifndef CFF_CONFIG_OPTION_OLD_ENGINE
595
      if ( *hinting_engine != FT_CFF_HINTING_ADOBE )
596
        error = FT_ERR( Unimplemented_Feature );
597
      else
598
#endif
599
        driver->hinting_engine = *hinting_engine;
600
 
601
      return error;
602
    }
603
    else if ( !ft_strcmp( property_name, "no-stem-darkening" ) )
604
    {
605
      FT_Bool*  no_stem_darkening = (FT_Bool*)value;
606
 
607
 
608
      driver->no_stem_darkening = *no_stem_darkening;
609
 
610
      return error;
611
    }
612
 
613
    FT_TRACE0(( "cff_property_set: missing property `%s'\n",
614
                property_name ));
615
    return FT_THROW( Missing_Property );
616
  }
617
 
618
 
619
  static FT_Error
620
  cff_property_get( FT_Module    module,         /* CFF_Driver */
621
                    const char*  property_name,
622
                    const void*  value )
623
  {
624
    FT_Error    error  = FT_Err_Ok;
625
    CFF_Driver  driver = (CFF_Driver)module;
626
 
627
    FT_UInt  hinting_engine    = driver->hinting_engine;
628
    FT_Bool  no_stem_darkening = driver->no_stem_darkening;
629
 
630
 
631
    if ( !ft_strcmp( property_name, "hinting-engine" ) )
632
    {
633
      FT_UInt*  val = (FT_UInt*)value;
634
 
635
 
636
      *val = hinting_engine;
637
 
638
      return error;
639
    }
640
    else if ( !ft_strcmp( property_name, "no-stem-darkening" ) )
641
    {
642
      FT_Bool*  val = (FT_Bool*)value;
643
 
644
 
645
      *val = no_stem_darkening;
646
 
647
      return error;
648
    }
649
 
650
    FT_TRACE0(( "cff_property_get: missing property `%s'\n",
651
                property_name ));
652
    return FT_THROW( Missing_Property );
653
  }
654
 
655
 
656
  FT_DEFINE_SERVICE_PROPERTIESREC(
657
    cff_service_properties,
658
    (FT_Properties_SetFunc)cff_property_set,
659
    (FT_Properties_GetFunc)cff_property_get )
660
 
661
 
662
  /*************************************************************************/
663
  /*************************************************************************/
664
  /*************************************************************************/
665
  /****                                                                 ****/
666
  /****                                                                 ****/
667
  /****                D R I V E R  I N T E R F A C E                   ****/
668
  /****                                                                 ****/
669
  /****                                                                 ****/
670
  /*************************************************************************/
671
  /*************************************************************************/
672
  /*************************************************************************/
673
 
674
#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
675
  FT_DEFINE_SERVICEDESCREC7(
676
    cff_services,
677
    FT_SERVICE_ID_XF86_NAME,            FT_XF86_FORMAT_CFF,
678
    FT_SERVICE_ID_POSTSCRIPT_INFO,      &CFF_SERVICE_PS_INFO_GET,
679
    FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET,
680
    FT_SERVICE_ID_GLYPH_DICT,           &CFF_SERVICE_GLYPH_DICT_GET,
681
    FT_SERVICE_ID_TT_CMAP,              &CFF_SERVICE_GET_CMAP_INFO_GET,
682
    FT_SERVICE_ID_CID,                  &CFF_SERVICE_CID_INFO_GET,
683
    FT_SERVICE_ID_PROPERTIES,           &CFF_SERVICE_PROPERTIES_GET
684
  )
685
#else
686
  FT_DEFINE_SERVICEDESCREC6(
687
    cff_services,
688
    FT_SERVICE_ID_XF86_NAME,            FT_XF86_FORMAT_CFF,
689
    FT_SERVICE_ID_POSTSCRIPT_INFO,      &CFF_SERVICE_PS_INFO_GET,
690
    FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET,
691
    FT_SERVICE_ID_TT_CMAP,              &CFF_SERVICE_GET_CMAP_INFO_GET,
692
    FT_SERVICE_ID_CID,                  &CFF_SERVICE_CID_INFO_GET,
693
    FT_SERVICE_ID_PROPERTIES,           &CFF_SERVICE_PROPERTIES_GET
694
  )
695
#endif
696
 
697
 
698
  FT_CALLBACK_DEF( FT_Module_Interface )
699
  cff_get_interface( FT_Module    driver,       /* CFF_Driver */
700
                     const char*  module_interface )
701
  {
702
    FT_Library           library;
703
    FT_Module            sfnt;
704
    FT_Module_Interface  result;
705
 
706
 
707
    /* CFF_SERVICES_GET derefers `library' in PIC mode */
708
#ifdef FT_CONFIG_OPTION_PIC
709
    if ( !driver )
710
      return NULL;
711
    library = driver->library;
712
    if ( !library )
713
      return NULL;
714
#endif
715
 
716
    result = ft_service_list_lookup( CFF_SERVICES_GET, module_interface );
717
    if ( result != NULL )
718
      return result;
719
 
720
    /* `driver' is not yet evaluated in non-PIC mode */
721
#ifndef FT_CONFIG_OPTION_PIC
722
    if ( !driver )
723
      return NULL;
724
    library = driver->library;
725
    if ( !library )
726
      return NULL;
727
#endif
728
 
729
    /* we pass our request to the `sfnt' module */
730
    sfnt = FT_Get_Module( library, "sfnt" );
731
 
732
    return sfnt ? sfnt->clazz->get_interface( sfnt, module_interface ) : 0;
733
  }
734
 
735
 
736
  /* The FT_DriverInterface structure is defined in ftdriver.h. */
737
 
738
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
739
#define CFF_SIZE_SELECT cff_size_select
740
#else
741
#define CFF_SIZE_SELECT 0
742
#endif
743
 
744
  FT_DEFINE_DRIVER(
745
    cff_driver_class,
746
 
747
      FT_MODULE_FONT_DRIVER       |
748
      FT_MODULE_DRIVER_SCALABLE   |
749
      FT_MODULE_DRIVER_HAS_HINTER,
750
 
751
      sizeof ( CFF_DriverRec ),
752
      "cff",
753
      0x10000L,
754
      0x20000L,
755
 
756
      0,   /* module-specific interface */
757
 
758
      cff_driver_init,
759
      cff_driver_done,
760
      cff_get_interface,
761
 
762
    /* now the specific driver fields */
763
    sizeof ( TT_FaceRec ),
764
    sizeof ( CFF_SizeRec ),
765
    sizeof ( CFF_GlyphSlotRec ),
766
 
767
    cff_face_init,
768
    cff_face_done,
769
    cff_size_init,
770
    cff_size_done,
771
    cff_slot_init,
772
    cff_slot_done,
773
 
774
    cff_glyph_load,
775
 
776
    cff_get_kerning,
777
    0,                       /* FT_Face_AttachFunc */
778
    cff_get_advances,
779
 
780
    cff_size_request,
781
 
782
    CFF_SIZE_SELECT
783
  )
784
 
785
 
786
/* END */