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