xref: /aosp_15_r20/external/freetype/src/cff/cffdrivr.c (revision 63949dbd25bcc50c4e1178497ff9e9574d44fc5a)
1 /****************************************************************************
2  *
3  * cffdrivr.c
4  *
5  *   OpenType font driver implementation (body).
6  *
7  * Copyright (C) 1996-2023 by
8  * David Turner, Robert Wilhelm, Werner Lemberg, and Dominik Röttsches.
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 <freetype/freetype.h>
20 #include <freetype/internal/ftdebug.h>
21 #include <freetype/internal/ftstream.h>
22 #include <freetype/internal/sfnt.h>
23 #include <freetype/internal/psaux.h>
24 #include <freetype/internal/ftpsprop.h>
25 #include <freetype/internal/services/svcid.h>
26 #include <freetype/internal/services/svpsinfo.h>
27 #include <freetype/internal/services/svpostnm.h>
28 #include <freetype/internal/services/svttcmap.h>
29 #include <freetype/internal/services/svcfftl.h>
30 
31 #include "cffdrivr.h"
32 #include "cffgload.h"
33 #include "cffload.h"
34 #include "cffcmap.h"
35 #include "cffparse.h"
36 #include "cffobjs.h"
37 
38 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
39 #include <freetype/internal/services/svmm.h>
40 #include <freetype/internal/services/svmetric.h>
41 #endif
42 
43 #include "cfferrs.h"
44 
45 #include <freetype/internal/services/svfntfmt.h>
46 #include <freetype/internal/services/svgldict.h>
47 #include <freetype/internal/services/svprop.h>
48 #include <freetype/ftdriver.h>
49 
50 
51   /**************************************************************************
52    *
53    * The macro FT_COMPONENT is used in trace mode.  It is an implicit
54    * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
55    * messages during execution.
56    */
57 #undef  FT_COMPONENT
58 #define FT_COMPONENT  cffdriver
59 
60 
61   /*************************************************************************/
62   /*************************************************************************/
63   /*************************************************************************/
64   /****                                                                 ****/
65   /****                                                                 ****/
66   /****                          F A C E S                              ****/
67   /****                                                                 ****/
68   /****                                                                 ****/
69   /*************************************************************************/
70   /*************************************************************************/
71   /*************************************************************************/
72 
73 
74   /**************************************************************************
75    *
76    * @Function:
77    *   cff_get_kerning
78    *
79    * @Description:
80    *   A driver method used to return the kerning vector between two
81    *   glyphs of the same face.
82    *
83    * @Input:
84    *   face ::
85    *     A handle to the source face object.
86    *
87    *   left_glyph ::
88    *     The index of the left glyph in the kern pair.
89    *
90    *   right_glyph ::
91    *     The index of the right glyph in the kern pair.
92    *
93    * @Output:
94    *   kerning ::
95    *     The kerning vector.  This is in font units for
96    *     scalable formats, and in pixels for fixed-sizes
97    *     formats.
98    *
99    * @Return:
100    *   FreeType error code.  0 means success.
101    *
102    * @Note:
103    *   Only horizontal layouts (left-to-right & right-to-left) are
104    *   supported by this function.  Other layouts, or more sophisticated
105    *   kernings, are out of scope of this method (the basic driver
106    *   interface is meant to be simple).
107    *
108    *   They can be implemented by format-specific interfaces.
109    */
110   FT_CALLBACK_DEF( FT_Error )
cff_get_kerning(FT_Face face,FT_UInt left_glyph,FT_UInt right_glyph,FT_Vector * kerning)111   cff_get_kerning( FT_Face     face,          /* CFF_Face */
112                    FT_UInt     left_glyph,
113                    FT_UInt     right_glyph,
114                    FT_Vector*  kerning )
115   {
116     CFF_Face      cffface = (CFF_Face)face;
117     SFNT_Service  sfnt    = (SFNT_Service)cffface->sfnt;
118 
119 
120     kerning->x = 0;
121     kerning->y = 0;
122 
123     if ( sfnt )
124       kerning->x = sfnt->get_kerning( cffface, left_glyph, right_glyph );
125 
126     return FT_Err_Ok;
127   }
128 
129 
130   /**************************************************************************
131    *
132    * @Function:
133    *   cff_glyph_load
134    *
135    * @Description:
136    *   A driver method used to load a glyph within a given glyph slot.
137    *
138    * @Input:
139    *   slot ::
140    *     A handle to the target slot object where the glyph
141    *     will be loaded.
142    *
143    *   size ::
144    *     A handle to the source face size at which the glyph
145    *     must be scaled, loaded, etc.
146    *
147    *   glyph_index ::
148    *     The index of the glyph in the font file.
149    *
150    *   load_flags ::
151    *     A flag indicating what to load for this glyph.  The
152    *     FT_LOAD_??? constants can be used to control the
153    *     glyph loading process (e.g., whether the outline
154    *     should be scaled, whether to load bitmaps or not,
155    *     whether to hint the outline, etc).
156    *
157    * @Return:
158    *   FreeType error code.  0 means success.
159    */
160   FT_CALLBACK_DEF( FT_Error )
cff_glyph_load(FT_GlyphSlot slot,FT_Size size,FT_UInt glyph_index,FT_Int32 load_flags)161   cff_glyph_load( FT_GlyphSlot  slot,        /* CFF_GlyphSlot */
162                   FT_Size       size,        /* CFF_Size      */
163                   FT_UInt       glyph_index,
164                   FT_Int32      load_flags )
165   {
166     FT_Error       error;
167     CFF_GlyphSlot  cffslot = (CFF_GlyphSlot)slot;
168     CFF_Size       cffsize = (CFF_Size)size;
169 
170 
171     if ( !cffslot )
172       return FT_THROW( Invalid_Slot_Handle );
173 
174     FT_TRACE1(( "cff_glyph_load: glyph index %d\n", glyph_index ));
175 
176     /* check whether we want a scaled outline or bitmap */
177     if ( !cffsize )
178       load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
179 
180     /* reset the size object if necessary */
181     if ( load_flags & FT_LOAD_NO_SCALE )
182       size = NULL;
183 
184     if ( size )
185     {
186       /* these two objects must have the same parent */
187       if ( size->face != slot->face )
188         return FT_THROW( Invalid_Face_Handle );
189     }
190 
191     /* now load the glyph outline if necessary */
192     error = cff_slot_load( cffslot, cffsize, glyph_index, load_flags );
193 
194     /* force drop-out mode to 2 - irrelevant now */
195     /* slot->outline.dropout_mode = 2; */
196 
197     return error;
198   }
199 
200 
201   FT_CALLBACK_DEF( FT_Error )
cff_get_advances(FT_Face face,FT_UInt start,FT_UInt count,FT_Int32 flags,FT_Fixed * advances)202   cff_get_advances( FT_Face    face,
203                     FT_UInt    start,
204                     FT_UInt    count,
205                     FT_Int32   flags,
206                     FT_Fixed*  advances )
207   {
208     FT_UInt       nn;
209     FT_Error      error = FT_Err_Ok;
210     FT_GlyphSlot  slot  = face->glyph;
211 
212 
213     if ( FT_IS_SFNT( face ) )
214     {
215       /* OpenType 1.7 mandates that the data from `hmtx' table be used; */
216       /* it is no longer necessary that those values are identical to   */
217       /* the values in the `CFF' table                                  */
218 
219       CFF_Face  cffface = (CFF_Face)face;
220       FT_Short  dummy;
221 
222 
223       if ( flags & FT_LOAD_VERTICAL_LAYOUT )
224       {
225 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
226         /* no fast retrieval for blended MM fonts without VVAR table */
227         if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) &&
228              !( cffface->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
229           return FT_THROW( Unimplemented_Feature );
230 #endif
231 
232         /* check whether we have data from the `vmtx' table at all; */
233         /* otherwise we extract the info from the CFF glyphstrings  */
234         /* (instead of synthesizing a global value using the `OS/2' */
235         /* table)                                                   */
236         if ( !cffface->vertical_info )
237           goto Missing_Table;
238 
239         for ( nn = 0; nn < count; nn++ )
240         {
241           FT_UShort  ah;
242 
243 
244           ( (SFNT_Service)cffface->sfnt )->get_metrics( cffface,
245                                                         1,
246                                                         start + nn,
247                                                         &dummy,
248                                                         &ah );
249 
250           FT_TRACE5(( "  idx %d: advance height %d font unit%s\n",
251                       start + nn,
252                       ah,
253                       ah == 1 ? "" : "s" ));
254           advances[nn] = ah;
255         }
256       }
257       else
258       {
259 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
260         /* no fast retrieval for blended MM fonts without HVAR table */
261         if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) &&
262              !( cffface->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
263           return FT_THROW( Unimplemented_Feature );
264 #endif
265 
266         /* check whether we have data from the `hmtx' table at all */
267         if ( !cffface->horizontal.number_Of_HMetrics )
268           goto Missing_Table;
269 
270         for ( nn = 0; nn < count; nn++ )
271         {
272           FT_UShort  aw;
273 
274 
275           ( (SFNT_Service)cffface->sfnt )->get_metrics( cffface,
276                                                         0,
277                                                         start + nn,
278                                                         &dummy,
279                                                         &aw );
280 
281           FT_TRACE5(( "  idx %d: advance width %d font unit%s\n",
282                       start + nn,
283                       aw,
284                       aw == 1 ? "" : "s" ));
285           advances[nn] = aw;
286         }
287       }
288 
289       return error;
290     }
291 
292   Missing_Table:
293     flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY;
294 
295     for ( nn = 0; nn < count; nn++ )
296     {
297       error = cff_glyph_load( slot, face->size, start + nn, flags );
298       if ( error )
299         break;
300 
301       advances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT )
302                      ? slot->linearVertAdvance
303                      : slot->linearHoriAdvance;
304     }
305 
306     return error;
307   }
308 
309 
310   /*
311    * GLYPH DICT SERVICE
312    *
313    */
314 
315   FT_CALLBACK_DEF( FT_Error )
cff_get_glyph_name(FT_Face face,FT_UInt glyph_index,FT_Pointer buffer,FT_UInt buffer_max)316   cff_get_glyph_name( FT_Face     face,        /* CFF_Face */
317                       FT_UInt     glyph_index,
318                       FT_Pointer  buffer,
319                       FT_UInt     buffer_max )
320   {
321     CFF_Face    cffface = (CFF_Face)face;
322     CFF_Font    font    = (CFF_Font)cffface->extra.data;
323     FT_String*  gname;
324     FT_UShort   sid;
325     FT_Error    error;
326 
327 
328     /* CFF2 table does not have glyph names; */
329     /* we need to use `post' table method    */
330     if ( font->version_major == 2 )
331     {
332       FT_Library            library     = FT_FACE_LIBRARY( face );
333       FT_Module             sfnt_module = FT_Get_Module( library, "sfnt" );
334       FT_Service_GlyphDict  service     =
335         (FT_Service_GlyphDict)ft_module_get_service(
336                                  sfnt_module,
337                                  FT_SERVICE_ID_GLYPH_DICT,
338                                  0 );
339 
340 
341       if ( service && service->get_name )
342         return service->get_name( face, glyph_index, buffer, buffer_max );
343       else
344       {
345         FT_ERROR(( "cff_get_glyph_name:"
346                    " cannot get glyph name from a CFF2 font\n" ));
347         FT_ERROR(( "                   "
348                    " without the `psnames' module\n" ));
349         error = FT_THROW( Missing_Module );
350         goto Exit;
351       }
352     }
353 
354     if ( !font->psnames )
355     {
356       FT_ERROR(( "cff_get_glyph_name:"
357                  " cannot get glyph name from CFF & CEF fonts\n" ));
358       FT_ERROR(( "                   "
359                  " without the `psnames' module\n" ));
360       error = FT_THROW( Missing_Module );
361       goto Exit;
362     }
363 
364     /* first, locate the sid in the charset table */
365     sid = font->charset.sids[glyph_index];
366 
367     /* now, look up the name itself */
368     gname = cff_index_get_sid_string( font, sid );
369 
370     if ( gname )
371       FT_STRCPYN( buffer, gname, buffer_max );
372 
373     error = FT_Err_Ok;
374 
375   Exit:
376     return error;
377   }
378 
379 
380   FT_CALLBACK_DEF( FT_UInt )
cff_get_name_index(FT_Face face,const FT_String * glyph_name)381   cff_get_name_index( FT_Face           face,        /* CFF_Face */
382                       const FT_String*  glyph_name )
383   {
384     CFF_Face            cffface = (CFF_Face)face;
385     CFF_Font            cff     = (CFF_Font)cffface->extra.data;
386     CFF_Charset         charset = &cff->charset;
387     FT_Service_PsCMaps  psnames;
388     FT_String*          name;
389     FT_UShort           sid;
390     FT_UInt             i;
391 
392 
393     /* CFF2 table does not have glyph names; */
394     /* we need to use `post' table method    */
395     if ( cff->version_major == 2 )
396     {
397       FT_Library            library     = FT_FACE_LIBRARY( face );
398       FT_Module             sfnt_module = FT_Get_Module( library, "sfnt" );
399       FT_Service_GlyphDict  service     =
400         (FT_Service_GlyphDict)ft_module_get_service(
401                                  sfnt_module,
402                                  FT_SERVICE_ID_GLYPH_DICT,
403                                  0 );
404 
405 
406       if ( service && service->name_index )
407         return service->name_index( face, glyph_name );
408       else
409       {
410         FT_ERROR(( "cff_get_name_index:"
411                    " cannot get glyph index from a CFF2 font\n" ));
412         FT_ERROR(( "                   "
413                    " without the `psnames' module\n" ));
414         return 0;
415       }
416     }
417 
418     FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
419     if ( !psnames )
420       return 0;
421 
422     for ( i = 0; i < cff->num_glyphs; i++ )
423     {
424       sid = charset->sids[i];
425 
426       if ( sid > 390 )
427         name = cff_index_get_string( cff, sid - 391 );
428       else
429         name = (FT_String *)psnames->adobe_std_strings( sid );
430 
431       if ( !name )
432         continue;
433 
434       if ( !ft_strcmp( glyph_name, name ) )
435         return i;
436     }
437 
438     return 0;
439   }
440 
441 
FT_DEFINE_SERVICE_GLYPHDICTREC(cff_service_glyph_dict,cff_get_glyph_name,cff_get_name_index)442   FT_DEFINE_SERVICE_GLYPHDICTREC(
443     cff_service_glyph_dict,
444 
445     cff_get_glyph_name,  /* FT_GlyphDict_GetNameFunc   get_name   */
446     cff_get_name_index   /* FT_GlyphDict_NameIndexFunc name_index */
447   )
448 
449 
450   /*
451    * POSTSCRIPT INFO SERVICE
452    *
453    */
454 
455   FT_CALLBACK_DEF( FT_Int )
456   cff_ps_has_glyph_names( FT_Face  face )
457   {
458     return ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) > 0;
459   }
460 
461 
462   FT_CALLBACK_DEF( FT_Error )
cff_ps_get_font_info(FT_Face face,PS_FontInfoRec * afont_info)463   cff_ps_get_font_info( FT_Face          face,        /* CFF_Face */
464                         PS_FontInfoRec*  afont_info )
465   {
466     CFF_Face  cffface = (CFF_Face)face;
467     CFF_Font  cff     = (CFF_Font)cffface->extra.data;
468     FT_Error  error   = FT_Err_Ok;
469 
470 
471     if ( cffface->is_cff2 )
472     {
473       error = FT_THROW( Invalid_Argument );
474       goto Fail;
475     }
476 
477     if ( cff && !cff->font_info )
478     {
479       CFF_FontRecDict  dict      = &cff->top_font.font_dict;
480       FT_Memory        memory    = FT_FACE_MEMORY( face );
481       PS_FontInfoRec*  font_info = NULL;
482 
483 
484       if ( FT_QNEW( font_info ) )
485         goto Fail;
486 
487       font_info->version     = cff_index_get_sid_string( cff,
488                                                          dict->version );
489       font_info->notice      = cff_index_get_sid_string( cff,
490                                                          dict->notice );
491       font_info->full_name   = cff_index_get_sid_string( cff,
492                                                          dict->full_name );
493       font_info->family_name = cff_index_get_sid_string( cff,
494                                                          dict->family_name );
495       font_info->weight      = cff_index_get_sid_string( cff,
496                                                          dict->weight );
497       font_info->italic_angle        = dict->italic_angle;
498       font_info->is_fixed_pitch      = dict->is_fixed_pitch;
499       font_info->underline_position  = (FT_Short)dict->underline_position;
500       font_info->underline_thickness = (FT_UShort)dict->underline_thickness;
501 
502       cff->font_info = font_info;
503     }
504 
505     if ( cff )
506       *afont_info = *cff->font_info;
507 
508   Fail:
509     return error;
510   }
511 
512 
513   FT_CALLBACK_DEF( FT_Error )
cff_ps_get_font_extra(FT_Face face,PS_FontExtraRec * afont_extra)514   cff_ps_get_font_extra( FT_Face           face,         /* CFF_Face */
515                          PS_FontExtraRec*  afont_extra )
516   {
517     CFF_Face  cffface = (CFF_Face)face;
518     CFF_Font  cff     = (CFF_Font)cffface->extra.data;
519     FT_Error  error   = FT_Err_Ok;
520 
521 
522     if ( cff && !cff->font_extra )
523     {
524       CFF_FontRecDict   dict       = &cff->top_font.font_dict;
525       FT_Memory         memory     = FT_FACE_MEMORY( face );
526       PS_FontExtraRec*  font_extra = NULL;
527       FT_String*        embedded_postscript;
528 
529 
530       if ( FT_QNEW( font_extra ) )
531         goto Fail;
532 
533       font_extra->fs_type = 0U;
534 
535       embedded_postscript = cff_index_get_sid_string(
536                               cff,
537                               dict->embedded_postscript );
538       if ( embedded_postscript )
539       {
540         FT_String*  start_fstype;
541         FT_String*  start_def;
542 
543 
544         /* Identify the XYZ integer in `/FSType XYZ def' substring. */
545         if ( ( start_fstype = ft_strstr( embedded_postscript,
546                                          "/FSType" ) ) != NULL    &&
547              ( start_def = ft_strstr( start_fstype +
548                                         sizeof ( "/FSType" ) - 1,
549                                       "def" ) ) != NULL           )
550         {
551           FT_String*  s;
552 
553 
554           for ( s = start_fstype + sizeof ( "/FSType" ) - 1;
555                 s != start_def;
556                 s++ )
557           {
558             if ( *s >= '0' && *s <= '9' )
559             {
560               if ( font_extra->fs_type >= ( FT_USHORT_MAX - 9 ) / 10 )
561               {
562                 /* Overflow - ignore the FSType value.  */
563                 font_extra->fs_type = 0U;
564                 break;
565               }
566 
567               font_extra->fs_type *= 10;
568               font_extra->fs_type += (FT_UShort)( *s - '0' );
569             }
570             else if ( *s != ' ' && *s != '\n' && *s != '\r' )
571             {
572               /* Non-whitespace character between `/FSType' and next `def' */
573               /* - ignore the FSType value.                                */
574               font_extra->fs_type = 0U;
575               break;
576             }
577           }
578         }
579       }
580 
581       cff->font_extra = font_extra;
582     }
583 
584     if ( cff )
585       *afont_extra = *cff->font_extra;
586 
587   Fail:
588     return error;
589   }
590 
591 
FT_DEFINE_SERVICE_PSINFOREC(cff_service_ps_info,cff_ps_get_font_info,cff_ps_get_font_extra,cff_ps_has_glyph_names,NULL,NULL)592   FT_DEFINE_SERVICE_PSINFOREC(
593     cff_service_ps_info,
594 
595     cff_ps_get_font_info,    /* PS_GetFontInfoFunc    ps_get_font_info    */
596     cff_ps_get_font_extra,   /* PS_GetFontExtraFunc   ps_get_font_extra   */
597     cff_ps_has_glyph_names,  /* PS_HasGlyphNamesFunc  ps_has_glyph_names  */
598     /* unsupported with CFF fonts */
599     NULL,                    /* PS_GetFontPrivateFunc ps_get_font_private */
600     /* not implemented            */
601     NULL                     /* PS_GetFontValueFunc   ps_get_font_value   */
602   )
603 
604 
605   /*
606    * POSTSCRIPT NAME SERVICE
607    *
608    */
609 
610   FT_CALLBACK_DEF( const char* )
611   cff_get_ps_name( FT_Face  face )    /* CFF_Face */
612   {
613     CFF_Face      cffface = (CFF_Face)face;
614     CFF_Font      cff     = (CFF_Font)cffface->extra.data;
615     SFNT_Service  sfnt    = (SFNT_Service)cffface->sfnt;
616 
617 
618     /* following the OpenType specification 1.7, we return the name stored */
619     /* in the `name' table for a CFF wrapped into an SFNT container        */
620 
621     if ( FT_IS_SFNT( face ) && sfnt )
622     {
623       FT_Library             library     = FT_FACE_LIBRARY( face );
624       FT_Module              sfnt_module = FT_Get_Module( library, "sfnt" );
625       FT_Service_PsFontName  service     =
626         (FT_Service_PsFontName)ft_module_get_service(
627                                  sfnt_module,
628                                  FT_SERVICE_ID_POSTSCRIPT_FONT_NAME,
629                                  0 );
630 
631 
632       if ( service && service->get_ps_font_name )
633         return service->get_ps_font_name( face );
634     }
635 
636     return cff ? (const char*)cff->font_name : NULL;
637   }
638 
639 
FT_DEFINE_SERVICE_PSFONTNAMEREC(cff_service_ps_name,cff_get_ps_name)640   FT_DEFINE_SERVICE_PSFONTNAMEREC(
641     cff_service_ps_name,
642 
643     cff_get_ps_name  /* FT_PsName_GetFunc get_ps_font_name */
644   )
645 
646 
647   /*
648    * TT CMAP INFO
649    *
650    * If the charmap is a synthetic Unicode encoding cmap or
651    * a Type 1 standard (or expert) encoding cmap, hide TT CMAP INFO
652    * service defined in SFNT module.
653    *
654    * Otherwise call the service function in the sfnt module.
655    *
656    */
657   FT_CALLBACK_DEF( FT_Error )
658   cff_get_cmap_info( FT_CharMap    charmap,
659                      TT_CMapInfo  *cmap_info )
660   {
661     FT_CMap   cmap  = FT_CMAP( charmap );
662     FT_Error  error = FT_Err_Ok;
663 
664     FT_Face     face    = FT_CMAP_FACE( cmap );
665     FT_Library  library = FT_FACE_LIBRARY( face );
666 
667 
668     if ( cmap->clazz != &cff_cmap_encoding_class_rec &&
669          cmap->clazz != &cff_cmap_unicode_class_rec  )
670     {
671       FT_Module           sfnt    = FT_Get_Module( library, "sfnt" );
672       FT_Service_TTCMaps  service =
673         (FT_Service_TTCMaps)ft_module_get_service( sfnt,
674                                                    FT_SERVICE_ID_TT_CMAP,
675                                                    0 );
676 
677 
678       if ( service && service->get_cmap_info )
679         error = service->get_cmap_info( charmap, cmap_info );
680     }
681     else
682       error = FT_THROW( Invalid_CharMap_Format );
683 
684     return error;
685   }
686 
687 
FT_DEFINE_SERVICE_TTCMAPSREC(cff_service_get_cmap_info,cff_get_cmap_info)688   FT_DEFINE_SERVICE_TTCMAPSREC(
689     cff_service_get_cmap_info,
690 
691     cff_get_cmap_info  /* TT_CMap_Info_GetFunc get_cmap_info */
692   )
693 
694 
695   /*
696    * CID INFO SERVICE
697    *
698    */
699   FT_CALLBACK_DEF( FT_Error )
700   cff_get_ros( FT_Face       face,        /* FT_Face */
701                const char*  *registry,
702                const char*  *ordering,
703                FT_Int       *supplement )
704   {
705     FT_Error  error   = FT_Err_Ok;
706     CFF_Face  cffface = (CFF_Face)face;
707     CFF_Font  cff     = (CFF_Font)cffface->extra.data;
708 
709 
710     if ( cff )
711     {
712       CFF_FontRecDict  dict = &cff->top_font.font_dict;
713 
714 
715       if ( dict->cid_registry == 0xFFFFU )
716       {
717         error = FT_THROW( Invalid_Argument );
718         goto Fail;
719       }
720 
721       if ( registry )
722       {
723         if ( !cff->registry )
724           cff->registry = cff_index_get_sid_string( cff,
725                                                     dict->cid_registry );
726         *registry = cff->registry;
727       }
728 
729       if ( ordering )
730       {
731         if ( !cff->ordering )
732           cff->ordering = cff_index_get_sid_string( cff,
733                                                     dict->cid_ordering );
734         *ordering = cff->ordering;
735       }
736 
737       /*
738        * XXX: According to Adobe TechNote #5176, the supplement in CFF
739        *      can be a real number. We truncate it to fit public API
740        *      since freetype-2.3.6.
741        */
742       if ( supplement )
743       {
744         if ( dict->cid_supplement < FT_INT_MIN ||
745              dict->cid_supplement > FT_INT_MAX )
746           FT_TRACE1(( "cff_get_ros: too large supplement %ld is truncated\n",
747                       dict->cid_supplement ));
748         *supplement = (FT_Int)dict->cid_supplement;
749       }
750     }
751 
752   Fail:
753     return error;
754   }
755 
756 
757   FT_CALLBACK_DEF( FT_Error )
cff_get_is_cid(FT_Face face,FT_Bool * is_cid)758   cff_get_is_cid( FT_Face   face,    /* CFF_Face */
759                   FT_Bool  *is_cid )
760   {
761     FT_Error  error   = FT_Err_Ok;
762     CFF_Face  cffface = (CFF_Face)face;
763     CFF_Font  cff     = (CFF_Font)cffface->extra.data;
764 
765 
766     *is_cid = 0;
767 
768     if ( cff )
769     {
770       CFF_FontRecDict  dict = &cff->top_font.font_dict;
771 
772 
773       if ( dict->cid_registry != 0xFFFFU )
774         *is_cid = 1;
775     }
776 
777     return error;
778   }
779 
780 
781   FT_CALLBACK_DEF( FT_Error )
cff_get_cid_from_glyph_index(FT_Face face,FT_UInt glyph_index,FT_UInt * cid)782   cff_get_cid_from_glyph_index( FT_Face   face,        /* CFF_Face */
783                                 FT_UInt   glyph_index,
784                                 FT_UInt  *cid )
785   {
786     FT_Error  error   = FT_Err_Ok;
787     CFF_Face  cffface = (CFF_Face)face;
788     CFF_Font  cff     = (CFF_Font)cffface->extra.data;
789 
790 
791     if ( cff )
792     {
793       FT_UInt          c;
794       CFF_FontRecDict  dict = &cff->top_font.font_dict;
795 
796 
797       if ( dict->cid_registry == 0xFFFFU )
798       {
799         error = FT_THROW( Invalid_Argument );
800         goto Fail;
801       }
802 
803       if ( glyph_index >= cff->num_glyphs )
804       {
805         error = FT_THROW( Invalid_Argument );
806         goto Fail;
807       }
808 
809       c = cff->charset.sids[glyph_index];
810 
811       if ( cid )
812         *cid = c;
813     }
814 
815   Fail:
816     return error;
817   }
818 
819 
FT_DEFINE_SERVICE_CIDREC(cff_service_cid_info,cff_get_ros,cff_get_is_cid,cff_get_cid_from_glyph_index)820   FT_DEFINE_SERVICE_CIDREC(
821     cff_service_cid_info,
822 
823     cff_get_ros,
824       /* FT_CID_GetRegistryOrderingSupplementFunc get_ros                  */
825     cff_get_is_cid,
826       /* FT_CID_GetIsInternallyCIDKeyedFunc       get_is_cid               */
827     cff_get_cid_from_glyph_index
828       /* FT_CID_GetCIDFromGlyphIndexFunc          get_cid_from_glyph_index */
829   )
830 
831 
832   /*
833    * PROPERTY SERVICE
834    *
835    */
836 
837   FT_DEFINE_SERVICE_PROPERTIESREC(
838     cff_service_properties,
839 
840     ps_property_set,  /* FT_Properties_SetFunc set_property */
841     ps_property_get   /* FT_Properties_GetFunc get_property */
842   )
843 
844 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
845 
846   /*
847    * MULTIPLE MASTER SERVICE
848    *
849    */
850 
851   FT_CALLBACK_DEF( FT_Error )
852   cff_set_mm_blend( FT_Face    face,        /* CFF_Face */
853                     FT_UInt    num_coords,
854                     FT_Fixed*  coords )
855   {
856     CFF_Face                 cffface = (CFF_Face)face;
857     FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
858 
859 
860     return mm->set_mm_blend( face, num_coords, coords );
861   }
862 
863 
864   FT_CALLBACK_DEF( FT_Error )
cff_get_mm_blend(FT_Face face,FT_UInt num_coords,FT_Fixed * coords)865   cff_get_mm_blend( FT_Face    face,       /* CFF_Face */
866                     FT_UInt    num_coords,
867                     FT_Fixed*  coords )
868   {
869     CFF_Face                 cffface = (CFF_Face)face;
870     FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
871 
872 
873     return mm->get_mm_blend( face, num_coords, coords );
874   }
875 
876 
877   FT_CALLBACK_DEF( FT_Error )
cff_set_mm_weightvector(FT_Face face,FT_UInt len,FT_Fixed * weightvector)878   cff_set_mm_weightvector( FT_Face    face,          /* CFF_Face */
879                            FT_UInt    len,
880                            FT_Fixed*  weightvector )
881   {
882     CFF_Face                 cffface = (CFF_Face)face;
883     FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
884 
885 
886     return mm->set_mm_weightvector( face, len, weightvector );
887   }
888 
889 
890   FT_CALLBACK_DEF( FT_Error )
cff_get_mm_weightvector(FT_Face face,FT_UInt * len,FT_Fixed * weightvector)891   cff_get_mm_weightvector( FT_Face    face,          /* CFF_Face */
892                            FT_UInt*   len,
893                            FT_Fixed*  weightvector )
894   {
895     CFF_Face                 cffface = (CFF_Face)face;
896     FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
897 
898 
899     return mm->get_mm_weightvector( face, len, weightvector );
900   }
901 
902 
903   FT_CALLBACK_DEF( void )
cff_construct_ps_name(FT_Face face)904   cff_construct_ps_name( FT_Face  face )  /* CFF_Face */
905   {
906     CFF_Face                 cffface = (CFF_Face)face;
907     FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
908 
909 
910     mm->construct_ps_name( face );
911   }
912 
913 
914   FT_CALLBACK_DEF( FT_Error )
cff_get_mm_var(FT_Face face,FT_MM_Var ** master)915   cff_get_mm_var( FT_Face      face,    /* CFF_Face */
916                   FT_MM_Var*  *master )
917   {
918     CFF_Face                 cffface = (CFF_Face)face;
919     FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
920 
921 
922     return mm->get_mm_var( face, master );
923   }
924 
925 
926   FT_CALLBACK_DEF( FT_Error )
cff_set_var_design(FT_Face face,FT_UInt num_coords,FT_Fixed * coords)927   cff_set_var_design( FT_Face    face,       /* CFF_Face */
928                       FT_UInt    num_coords,
929                       FT_Fixed*  coords )
930   {
931     CFF_Face                 cffface = (CFF_Face)face;
932     FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
933 
934 
935     return mm->set_var_design( face, num_coords, coords );
936   }
937 
938 
939   FT_CALLBACK_DEF( FT_Error )
cff_get_var_design(FT_Face face,FT_UInt num_coords,FT_Fixed * coords)940   cff_get_var_design( FT_Face    face,       /* CFF_Face */
941                       FT_UInt    num_coords,
942                       FT_Fixed*  coords )
943   {
944     CFF_Face                 cffface = (CFF_Face)face;
945     FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
946 
947 
948     return mm->get_var_design( face, num_coords, coords );
949   }
950 
951 
952   FT_CALLBACK_DEF( FT_Error )
cff_set_named_instance(FT_Face face,FT_UInt instance_index)953   cff_set_named_instance( FT_Face   face,            /* CFF_Face */
954                           FT_UInt   instance_index )
955   {
956     CFF_Face                 cffface = (CFF_Face)face;
957     FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
958 
959 
960     return mm->set_named_instance( face, instance_index );
961   }
962 
963 
964   FT_CALLBACK_DEF( FT_Error )
cff_get_default_named_instance(FT_Face face,FT_UInt * instance_index)965   cff_get_default_named_instance( FT_Face   face,            /* CFF_Face */
966                                   FT_UInt  *instance_index )
967   {
968     CFF_Face                 cffface = (CFF_Face)face;
969     FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
970 
971 
972     return mm->get_default_named_instance( face, instance_index );
973   }
974 
975 
976   FT_CALLBACK_DEF( FT_Error )
cff_load_item_variation_store(FT_Face face,FT_ULong offset,GX_ItemVarStore itemStore)977   cff_load_item_variation_store( FT_Face          face,       /* CFF_Face */
978                                  FT_ULong         offset,
979                                  GX_ItemVarStore  itemStore )
980   {
981     CFF_Face                 cffface = (CFF_Face)face;
982     FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
983 
984 
985     return mm->load_item_var_store( face, offset, itemStore );
986   }
987 
988 
989   FT_CALLBACK_DEF( FT_Error )
cff_load_delta_set_index_mapping(FT_Face face,FT_ULong offset,GX_DeltaSetIdxMap map,GX_ItemVarStore itemStore,FT_ULong table_len)990   cff_load_delta_set_index_mapping( FT_Face            face,   /* CFF_Face */
991                                     FT_ULong           offset,
992                                     GX_DeltaSetIdxMap  map,
993                                     GX_ItemVarStore    itemStore,
994                                     FT_ULong           table_len )
995   {
996     CFF_Face                 cffface = (CFF_Face)face;
997     FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
998 
999 
1000     return mm->load_delta_set_idx_map( face, offset, map,
1001                                        itemStore, table_len );
1002   }
1003 
1004 
1005   FT_CALLBACK_DEF( FT_Int )
cff_get_item_delta(FT_Face face,GX_ItemVarStore itemStore,FT_UInt outerIndex,FT_UInt innerIndex)1006   cff_get_item_delta( FT_Face          face,        /* CFF_Face */
1007                       GX_ItemVarStore  itemStore,
1008                       FT_UInt          outerIndex,
1009                       FT_UInt          innerIndex )
1010   {
1011     CFF_Face                 cffface = (CFF_Face)face;
1012     FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
1013 
1014 
1015     return mm->get_item_delta( face, itemStore, outerIndex, innerIndex );
1016   }
1017 
1018 
1019   FT_CALLBACK_DEF( void )
cff_done_item_variation_store(FT_Face face,GX_ItemVarStore itemStore)1020   cff_done_item_variation_store( FT_Face          face,       /* CFF_Face */
1021                                  GX_ItemVarStore  itemStore )
1022   {
1023     CFF_Face                 cffface = (CFF_Face)face;
1024     FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
1025 
1026 
1027     mm->done_item_var_store( face, itemStore );
1028   }
1029 
1030 
1031   FT_CALLBACK_DEF( void )
cff_done_delta_set_index_map(FT_Face face,GX_DeltaSetIdxMap deltaSetIdxMap)1032   cff_done_delta_set_index_map( FT_Face            face,       /* CFF_Face */
1033                                 GX_DeltaSetIdxMap  deltaSetIdxMap )
1034   {
1035     CFF_Face                 cffface = (CFF_Face)face;
1036     FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
1037 
1038 
1039     mm->done_delta_set_idx_map( face, deltaSetIdxMap );
1040   }
1041 
1042 
1043 
FT_DEFINE_SERVICE_MULTIMASTERSREC(cff_service_multi_masters,NULL,NULL,cff_set_mm_blend,cff_get_mm_blend,cff_get_mm_var,cff_set_var_design,cff_get_var_design,cff_set_named_instance,cff_get_default_named_instance,cff_set_mm_weightvector,cff_get_mm_weightvector,cff_construct_ps_name,cff_load_delta_set_index_mapping,cff_load_item_variation_store,cff_get_item_delta,cff_done_item_variation_store,cff_done_delta_set_index_map,cff_get_var_blend,cff_done_blend)1044   FT_DEFINE_SERVICE_MULTIMASTERSREC(
1045     cff_service_multi_masters,
1046 
1047     NULL,                /* FT_Get_MM_Func         get_mm                     */
1048     NULL,                /* FT_Set_MM_Design_Func  set_mm_design              */
1049     cff_set_mm_blend,    /* FT_Set_MM_Blend_Func   set_mm_blend               */
1050     cff_get_mm_blend,    /* FT_Get_MM_Blend_Func   get_mm_blend               */
1051     cff_get_mm_var,      /* FT_Get_MM_Var_Func     get_mm_var                 */
1052     cff_set_var_design,  /* FT_Set_Var_Design_Func set_var_design             */
1053     cff_get_var_design,  /* FT_Get_Var_Design_Func get_var_design             */
1054     cff_set_named_instance,
1055              /* FT_Set_Named_Instance_Func         set_named_instance         */
1056     cff_get_default_named_instance,
1057              /* FT_Get_Default_Named_Instance_Func get_default_named_instance */
1058     cff_set_mm_weightvector,
1059              /* FT_Set_MM_WeightVector_Func        set_mm_weightvector        */
1060     cff_get_mm_weightvector,
1061              /* FT_Get_MM_WeightVector_Func        get_mm_weightvector        */
1062     cff_construct_ps_name,
1063              /* FT_Construct_PS_Name_Func          construct_ps_name          */
1064     cff_load_delta_set_index_mapping,
1065              /* FT_Var_Load_Delta_Set_Idx_Map_Func load_delta_set_idx_map     */
1066     cff_load_item_variation_store,
1067              /* FT_Var_Load_Item_Var_Store_Func    load_item_variation_store  */
1068     cff_get_item_delta,
1069              /* FT_Var_Get_Item_Delta_Func         get_item_delta             */
1070     cff_done_item_variation_store,
1071              /* FT_Var_Done_Item_Var_Store_Func    done_item_variation_store  */
1072     cff_done_delta_set_index_map,
1073              /* FT_Var_Done_Delta_Set_Idx_Map_Func done_delta_set_index_map   */
1074     cff_get_var_blend,   /* FT_Get_Var_Blend_Func  get_var_blend              */
1075     cff_done_blend       /* FT_Done_Blend_Func     done_blend                 */
1076   )
1077 
1078 
1079   /*
1080    * METRICS VARIATIONS SERVICE
1081    *
1082    */
1083 
1084   FT_CALLBACK_DEF( FT_Error )
1085   cff_hadvance_adjust( FT_Face   face,    /* CFF_Face */
1086                        FT_UInt   gindex,
1087                        FT_Int   *avalue )
1088   {
1089     CFF_Face  cffface = (CFF_Face)face;
1090     FT_Service_MetricsVariations
1091               var     = (FT_Service_MetricsVariations)cffface->tt_var;
1092 
1093 
1094     return var->hadvance_adjust( face, gindex, avalue );
1095   }
1096 
1097 
1098   FT_CALLBACK_DEF( void )
cff_metrics_adjust(FT_Face face)1099   cff_metrics_adjust( FT_Face  face )    /* CFF_Face */
1100   {
1101     CFF_Face  cffface = (CFF_Face)face;
1102     FT_Service_MetricsVariations
1103               var     = (FT_Service_MetricsVariations)cffface->tt_var;
1104 
1105 
1106     var->metrics_adjust( face );
1107   }
1108 
1109 
FT_DEFINE_SERVICE_METRICSVARIATIONSREC(cff_service_metrics_variations,cff_hadvance_adjust,NULL,NULL,NULL,NULL,NULL,NULL,cff_metrics_adjust,NULL)1110   FT_DEFINE_SERVICE_METRICSVARIATIONSREC(
1111     cff_service_metrics_variations,
1112 
1113     cff_hadvance_adjust,  /* FT_HAdvance_Adjust_Func hadvance_adjust */
1114     NULL,                 /* FT_LSB_Adjust_Func      lsb_adjust      */
1115     NULL,                 /* FT_RSB_Adjust_Func      rsb_adjust      */
1116 
1117     NULL,                 /* FT_VAdvance_Adjust_Func vadvance_adjust */
1118     NULL,                 /* FT_TSB_Adjust_Func      tsb_adjust      */
1119     NULL,                 /* FT_BSB_Adjust_Func      bsb_adjust      */
1120     NULL,                 /* FT_VOrg_Adjust_Func     vorg_adjust     */
1121 
1122     cff_metrics_adjust,   /* FT_Metrics_Adjust_Func  metrics_adjust  */
1123     NULL                  /* FT_Size_Reset_Func      size_reset      */
1124   )
1125 #endif
1126 
1127 
1128   /*
1129    * CFFLOAD SERVICE
1130    *
1131    */
1132 
1133   FT_DEFINE_SERVICE_CFFLOADREC(
1134     cff_service_cff_load,
1135 
1136     cff_get_standard_encoding,  /* FT_Get_Standard_Encoding_Func get_standard_encoding */
1137     cff_load_private_dict,      /* FT_Load_Private_Dict_Func     load_private_dict     */
1138     cff_fd_select_get,          /* FT_FD_Select_Get_Func         fd_select_get         */
1139     cff_blend_check_vector,     /* FT_Blend_Check_Vector_Func    blend_check_vector    */
1140     cff_blend_build_vector      /* FT_Blend_Build_Vector_Func    blend_build_vector    */
1141   )
1142 
1143 
1144   /*************************************************************************/
1145   /*************************************************************************/
1146   /*************************************************************************/
1147   /****                                                                 ****/
1148   /****                                                                 ****/
1149   /****                D R I V E R  I N T E R F A C E                   ****/
1150   /****                                                                 ****/
1151   /****                                                                 ****/
1152   /*************************************************************************/
1153   /*************************************************************************/
1154   /*************************************************************************/
1155 
1156 #if defined TT_CONFIG_OPTION_GX_VAR_SUPPORT
1157   FT_DEFINE_SERVICEDESCREC10(
1158     cff_services,
1159 
1160     FT_SERVICE_ID_FONT_FORMAT,          FT_FONT_FORMAT_CFF,
1161     FT_SERVICE_ID_MULTI_MASTERS,        &cff_service_multi_masters,
1162     FT_SERVICE_ID_METRICS_VARIATIONS,   &cff_service_metrics_variations,
1163     FT_SERVICE_ID_POSTSCRIPT_INFO,      &cff_service_ps_info,
1164     FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cff_service_ps_name,
1165     FT_SERVICE_ID_GLYPH_DICT,           &cff_service_glyph_dict,
1166     FT_SERVICE_ID_TT_CMAP,              &cff_service_get_cmap_info,
1167     FT_SERVICE_ID_CID,                  &cff_service_cid_info,
1168     FT_SERVICE_ID_PROPERTIES,           &cff_service_properties,
1169     FT_SERVICE_ID_CFF_LOAD,             &cff_service_cff_load
1170   )
1171 #else
1172   FT_DEFINE_SERVICEDESCREC8(
1173     cff_services,
1174 
1175     FT_SERVICE_ID_FONT_FORMAT,          FT_FONT_FORMAT_CFF,
1176     FT_SERVICE_ID_POSTSCRIPT_INFO,      &cff_service_ps_info,
1177     FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cff_service_ps_name,
1178     FT_SERVICE_ID_GLYPH_DICT,           &cff_service_glyph_dict,
1179     FT_SERVICE_ID_TT_CMAP,              &cff_service_get_cmap_info,
1180     FT_SERVICE_ID_CID,                  &cff_service_cid_info,
1181     FT_SERVICE_ID_PROPERTIES,           &cff_service_properties,
1182     FT_SERVICE_ID_CFF_LOAD,             &cff_service_cff_load
1183   )
1184 #endif
1185 
1186 
1187   FT_CALLBACK_DEF( FT_Module_Interface )
1188   cff_get_interface( FT_Module    driver,       /* CFF_Driver */
1189                      const char*  module_interface )
1190   {
1191     FT_Library           library;
1192     FT_Module            sfnt;
1193     FT_Module_Interface  result;
1194 
1195 
1196     result = ft_service_list_lookup( cff_services, module_interface );
1197     if ( result )
1198       return result;
1199 
1200     /* `driver' is not yet evaluated */
1201     if ( !driver )
1202       return NULL;
1203     library = driver->library;
1204     if ( !library )
1205       return NULL;
1206 
1207     /* we pass our request to the `sfnt' module */
1208     sfnt = FT_Get_Module( library, "sfnt" );
1209 
1210     return sfnt ? sfnt->clazz->get_interface( sfnt, module_interface ) : 0;
1211   }
1212 
1213 
1214   /* The FT_DriverInterface structure is defined in ftdriver.h. */
1215 
1216 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
1217 #define CFF_SIZE_SELECT cff_size_select
1218 #else
1219 #define CFF_SIZE_SELECT 0
1220 #endif
1221 
1222   FT_DEFINE_DRIVER(
1223     cff_driver_class,
1224 
1225       FT_MODULE_FONT_DRIVER          |
1226       FT_MODULE_DRIVER_SCALABLE      |
1227       FT_MODULE_DRIVER_HAS_HINTER    |
1228       FT_MODULE_DRIVER_HINTS_LIGHTLY,
1229 
1230       sizeof ( PS_DriverRec ),
1231       "cff",
1232       0x10000L,
1233       0x20000L,
1234 
1235       NULL,   /* module-specific interface */
1236 
1237       cff_driver_init,          /* FT_Module_Constructor  module_init   */
1238       cff_driver_done,          /* FT_Module_Destructor   module_done   */
1239       cff_get_interface,        /* FT_Module_Requester    get_interface */
1240 
1241     sizeof ( TT_FaceRec ),
1242     sizeof ( CFF_SizeRec ),
1243     sizeof ( CFF_GlyphSlotRec ),
1244 
1245     cff_face_init,              /* FT_Face_InitFunc  init_face */
1246     cff_face_done,              /* FT_Face_DoneFunc  done_face */
1247     cff_size_init,              /* FT_Size_InitFunc  init_size */
1248     cff_size_done,              /* FT_Size_DoneFunc  done_size */
1249     cff_slot_init,              /* FT_Slot_InitFunc  init_slot */
1250     cff_slot_done,              /* FT_Slot_DoneFunc  done_slot */
1251 
1252     cff_glyph_load,             /* FT_Slot_LoadFunc  load_glyph */
1253 
1254     cff_get_kerning,            /* FT_Face_GetKerningFunc   get_kerning  */
1255     NULL,                       /* FT_Face_AttachFunc       attach_file  */
1256     cff_get_advances,           /* FT_Face_GetAdvancesFunc  get_advances */
1257 
1258     cff_size_request,           /* FT_Size_RequestFunc  request_size */
1259     CFF_SIZE_SELECT             /* FT_Size_SelectFunc   select_size  */
1260   )
1261 
1262 
1263 /* END */
1264