xref: /aosp_15_r20/external/freetype/src/truetype/ttdriver.c (revision 63949dbd25bcc50c4e1178497ff9e9574d44fc5a)
1 /****************************************************************************
2  *
3  * ttdriver.c
4  *
5  *   TrueType font driver implementation (body).
6  *
7  * Copyright (C) 1996-2023 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 <freetype/internal/ftdebug.h>
20 #include <freetype/internal/ftstream.h>
21 #include <freetype/internal/sfnt.h>
22 #include <freetype/internal/services/svfntfmt.h>
23 
24 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
25 #include <freetype/ftmm.h>
26 #include <freetype/internal/services/svmm.h>
27 #include <freetype/internal/services/svmetric.h>
28 #endif
29 
30 #include <freetype/internal/services/svtteng.h>
31 #include <freetype/internal/services/svttglyf.h>
32 #include <freetype/internal/services/svprop.h>
33 #include <freetype/ftdriver.h>
34 
35 #include "ttdriver.h"
36 #include "ttgload.h"
37 #include "ttpload.h"
38 
39 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
40 #include "ttgxvar.h"
41 #endif
42 
43 #include "tterrors.h"
44 
45 
46   /**************************************************************************
47    *
48    * The macro FT_COMPONENT is used in trace mode.  It is an implicit
49    * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
50    * messages during execution.
51    */
52 #undef  FT_COMPONENT
53 #define FT_COMPONENT  ttdriver
54 
55 
56   /*
57    * PROPERTY SERVICE
58    *
59    */
60   FT_CALLBACK_DEF( FT_Error )
tt_property_set(FT_Module module,const char * property_name,const void * value,FT_Bool value_is_string)61   tt_property_set( FT_Module    module,         /* TT_Driver */
62                    const char*  property_name,
63                    const void*  value,
64                    FT_Bool      value_is_string )
65   {
66     FT_Error   error  = FT_Err_Ok;
67     TT_Driver  driver = (TT_Driver)module;
68 
69 #ifndef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
70     FT_UNUSED( value_is_string );
71 #endif
72 
73 
74     if ( !ft_strcmp( property_name, "interpreter-version" ) )
75     {
76       FT_UInt  interpreter_version;
77 
78 
79 #ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
80       if ( value_is_string )
81       {
82         const char*  s = (const char*)value;
83 
84 
85         interpreter_version = (FT_UInt)ft_strtol( s, NULL, 10 );
86       }
87       else
88 #endif
89       {
90         FT_UInt*  iv = (FT_UInt*)value;
91 
92 
93         interpreter_version = *iv;
94       }
95 
96       switch ( interpreter_version )
97       {
98       case TT_INTERPRETER_VERSION_35:
99         driver->interpreter_version = TT_INTERPRETER_VERSION_35;
100         break;
101 
102       case TT_INTERPRETER_VERSION_38:
103       case TT_INTERPRETER_VERSION_40:
104 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
105         driver->interpreter_version = TT_INTERPRETER_VERSION_40;
106       break;
107 #endif
108 
109       default:
110         error = FT_ERR( Unimplemented_Feature );
111       }
112 
113       return error;
114     }
115 
116     FT_TRACE2(( "tt_property_set: missing property `%s'\n",
117                 property_name ));
118     return FT_THROW( Missing_Property );
119   }
120 
121 
122   FT_CALLBACK_DEF( FT_Error )
tt_property_get(FT_Module module,const char * property_name,void * value)123   tt_property_get( FT_Module    module,         /* TT_Driver */
124                    const char*  property_name,
125                    void*        value )
126   {
127     FT_Error   error  = FT_Err_Ok;
128     TT_Driver  driver = (TT_Driver)module;
129 
130     FT_UInt  interpreter_version = driver->interpreter_version;
131 
132 
133     if ( !ft_strcmp( property_name, "interpreter-version" ) )
134     {
135       FT_UInt*  val = (FT_UInt*)value;
136 
137 
138       *val = interpreter_version;
139 
140       return error;
141     }
142 
143     FT_TRACE2(( "tt_property_get: missing property `%s'\n",
144                 property_name ));
145     return FT_THROW( Missing_Property );
146   }
147 
148 
FT_DEFINE_SERVICE_PROPERTIESREC(tt_service_properties,tt_property_set,tt_property_get)149   FT_DEFINE_SERVICE_PROPERTIESREC(
150     tt_service_properties,
151 
152     tt_property_set,  /* FT_Properties_SetFunc set_property */
153     tt_property_get   /* FT_Properties_GetFunc get_property */
154   )
155 
156 
157   /*************************************************************************/
158   /*************************************************************************/
159   /*************************************************************************/
160   /****                                                                 ****/
161   /****                                                                 ****/
162   /****                          F A C E S                              ****/
163   /****                                                                 ****/
164   /****                                                                 ****/
165   /*************************************************************************/
166   /*************************************************************************/
167   /*************************************************************************/
168 
169 
170   /**************************************************************************
171    *
172    * @Function:
173    *   tt_get_kerning
174    *
175    * @Description:
176    *   A driver method used to return the kerning vector between two
177    *   glyphs of the same face.
178    *
179    * @Input:
180    *   face ::
181    *     A handle to the source face object.
182    *
183    *   left_glyph ::
184    *     The index of the left glyph in the kern pair.
185    *
186    *   right_glyph ::
187    *     The index of the right glyph in the kern pair.
188    *
189    * @Output:
190    *   kerning ::
191    *     The kerning vector.  This is in font units for
192    *     scalable formats, and in pixels for fixed-sizes
193    *     formats.
194    *
195    * @Return:
196    *   FreeType error code.  0 means success.
197    *
198    * @Note:
199    *   Only horizontal layouts (left-to-right & right-to-left) are
200    *   supported by this function.  Other layouts, or more sophisticated
201    *   kernings, are out of scope of this method (the basic driver
202    *   interface is meant to be simple).
203    *
204    *   They can be implemented by format-specific interfaces.
205    */
206   FT_CALLBACK_DEF( FT_Error )
207   tt_get_kerning( FT_Face     face,        /* TT_Face */
208                   FT_UInt     left_glyph,
209                   FT_UInt     right_glyph,
210                   FT_Vector*  kerning )
211   {
212     TT_Face       ttface = (TT_Face)face;
213     SFNT_Service  sfnt   = (SFNT_Service)ttface->sfnt;
214 
215 
216     kerning->x = 0;
217     kerning->y = 0;
218 
219     if ( sfnt )
220       kerning->x = sfnt->get_kerning( ttface, left_glyph, right_glyph );
221 
222     return 0;
223   }
224 
225 
226   FT_CALLBACK_DEF( FT_Error )
tt_get_advances(FT_Face face,FT_UInt start,FT_UInt count,FT_Int32 flags,FT_Fixed * advances)227   tt_get_advances( FT_Face    face,      /* TT_Face */
228                    FT_UInt    start,
229                    FT_UInt    count,
230                    FT_Int32   flags,
231                    FT_Fixed  *advances )
232   {
233     FT_UInt  nn;
234     TT_Face  ttface = (TT_Face)face;
235 
236 
237     /* XXX: TODO: check for sbits */
238 
239     if ( flags & FT_LOAD_VERTICAL_LAYOUT )
240     {
241 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
242       /* no fast retrieval for blended MM fonts without VVAR table */
243       if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) &&
244            !( ttface->variation_support & TT_FACE_FLAG_VAR_VADVANCE )  )
245         return FT_THROW( Unimplemented_Feature );
246 #endif
247 
248       for ( nn = 0; nn < count; nn++ )
249       {
250         FT_Short   tsb;
251         FT_UShort  ah;
252 
253 
254         /* since we don't need `tsb', we use zero for `yMax' parameter */
255         TT_Get_VMetrics( ttface, start + nn, 0, &tsb, &ah );
256         advances[nn] = ah;
257       }
258     }
259     else
260     {
261 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
262       /* no fast retrieval for blended MM fonts without HVAR table */
263       if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) &&
264            !( ttface->variation_support & TT_FACE_FLAG_VAR_HADVANCE )  )
265         return FT_THROW( Unimplemented_Feature );
266 #endif
267 
268       for ( nn = 0; nn < count; nn++ )
269       {
270         FT_Short   lsb;
271         FT_UShort  aw;
272 
273 
274         TT_Get_HMetrics( ttface, start + nn, &lsb, &aw );
275         advances[nn] = aw;
276       }
277     }
278 
279     return FT_Err_Ok;
280   }
281 
282 
283   /*************************************************************************/
284   /*************************************************************************/
285   /*************************************************************************/
286   /****                                                                 ****/
287   /****                                                                 ****/
288   /****                           S I Z E S                             ****/
289   /****                                                                 ****/
290   /****                                                                 ****/
291   /*************************************************************************/
292   /*************************************************************************/
293   /*************************************************************************/
294 
295 
296 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
297 
298   FT_CALLBACK_DEF( FT_Error )
tt_size_select(FT_Size size,FT_ULong strike_index)299   tt_size_select( FT_Size   size,
300                   FT_ULong  strike_index )
301   {
302     TT_Face   ttface = (TT_Face)size->face;
303     TT_Size   ttsize = (TT_Size)size;
304     FT_Error  error  = FT_Err_Ok;
305 
306 
307     ttsize->strike_index = strike_index;
308 
309     if ( FT_IS_SCALABLE( size->face ) )
310     {
311       /* use the scaled metrics, even when tt_size_reset fails */
312       FT_Select_Metrics( size->face, strike_index );
313 
314       tt_size_reset( ttsize ); /* ignore return value */
315     }
316     else
317     {
318       SFNT_Service      sfnt         = (SFNT_Service)ttface->sfnt;
319       FT_Size_Metrics*  size_metrics = &size->metrics;
320 
321 
322       error = sfnt->load_strike_metrics( ttface,
323                                          strike_index,
324                                          size_metrics );
325       if ( error )
326         ttsize->strike_index = 0xFFFFFFFFUL;
327     }
328 
329     return error;
330   }
331 
332 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
333 
334 
335   FT_CALLBACK_DEF( FT_Error )
tt_size_request(FT_Size size,FT_Size_Request req)336   tt_size_request( FT_Size          size,
337                    FT_Size_Request  req )
338   {
339     TT_Size   ttsize = (TT_Size)size;
340     FT_Error  error  = FT_Err_Ok;
341 
342 
343 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
344 
345     if ( FT_HAS_FIXED_SIZES( size->face ) )
346     {
347       TT_Face       ttface = (TT_Face)size->face;
348       SFNT_Service  sfnt   = (SFNT_Service)ttface->sfnt;
349       FT_ULong      strike_index;
350 
351 
352       error = sfnt->set_sbit_strike( ttface, req, &strike_index );
353 
354       if ( error )
355         ttsize->strike_index = 0xFFFFFFFFUL;
356       else
357         return tt_size_select( size, strike_index );
358     }
359 
360 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
361 
362     {
363       FT_Error  err = FT_Request_Metrics( size->face, req );
364 
365 
366       if ( err )
367       {
368         error = err;
369         goto Exit;
370       }
371     }
372 
373     if ( FT_IS_SCALABLE( size->face ) )
374     {
375       error = tt_size_reset( ttsize );
376 
377 #ifdef TT_USE_BYTECODE_INTERPRETER
378       /* for the `MPS' bytecode instruction we need the point size */
379       if ( !error )
380       {
381         FT_UInt  resolution =
382                    ttsize->metrics->x_ppem > ttsize->metrics->y_ppem
383                      ? req->horiResolution
384                      : req->vertResolution;
385 
386 
387         /* if we don't have a resolution value, assume 72dpi */
388         if ( req->type == FT_SIZE_REQUEST_TYPE_SCALES ||
389              !resolution                              )
390           resolution = 72;
391 
392         ttsize->point_size = FT_MulDiv( ttsize->ttmetrics.ppem,
393                                         64 * 72,
394                                         resolution );
395       }
396 #endif
397     }
398 
399   Exit:
400     return error;
401   }
402 
403 
404   /**************************************************************************
405    *
406    * @Function:
407    *   tt_glyph_load
408    *
409    * @Description:
410    *   A driver method used to load a glyph within a given glyph slot.
411    *
412    * @Input:
413    *   slot ::
414    *     A handle to the target slot object where the glyph
415    *     will be loaded.
416    *
417    *   size ::
418    *     A handle to the source face size at which the glyph
419    *     must be scaled, loaded, etc.
420    *
421    *   glyph_index ::
422    *     The index of the glyph in the font file.
423    *
424    *   load_flags ::
425    *     A flag indicating what to load for this glyph.  The
426    *     FT_LOAD_XXX constants can be used to control the
427    *     glyph loading process (e.g., whether the outline
428    *     should be scaled, whether to load bitmaps or not,
429    *     whether to hint the outline, etc).
430    *
431    * @Return:
432    *   FreeType error code.  0 means success.
433    */
434   FT_CALLBACK_DEF( FT_Error )
tt_glyph_load(FT_GlyphSlot slot,FT_Size size,FT_UInt glyph_index,FT_Int32 load_flags)435   tt_glyph_load( FT_GlyphSlot  slot,        /* TT_GlyphSlot */
436                  FT_Size       size,        /* TT_Size      */
437                  FT_UInt       glyph_index,
438                  FT_Int32      load_flags )
439   {
440     TT_GlyphSlot  ttslot = (TT_GlyphSlot)slot;
441     TT_Size       ttsize = (TT_Size)size;
442     FT_Face       face   = ttslot->face;
443     FT_Error      error;
444 
445 
446     if ( !slot )
447       return FT_THROW( Invalid_Slot_Handle );
448 
449     if ( !size )
450       return FT_THROW( Invalid_Size_Handle );
451 
452     if ( !face )
453       return FT_THROW( Invalid_Face_Handle );
454 
455 #ifdef FT_CONFIG_OPTION_INCREMENTAL
456     if ( glyph_index >= (FT_UInt)face->num_glyphs &&
457          !face->internal->incremental_interface   )
458 #else
459     if ( glyph_index >= (FT_UInt)face->num_glyphs )
460 #endif
461       return FT_THROW( Invalid_Argument );
462 
463     if ( load_flags & FT_LOAD_NO_HINTING )
464     {
465       /* both FT_LOAD_NO_HINTING and FT_LOAD_NO_AUTOHINT   */
466       /* are necessary to disable hinting for tricky fonts */
467 
468       if ( FT_IS_TRICKY( face ) )
469         load_flags &= ~FT_LOAD_NO_HINTING;
470 
471       if ( load_flags & FT_LOAD_NO_AUTOHINT )
472         load_flags |= FT_LOAD_NO_HINTING;
473     }
474 
475     if ( load_flags & ( FT_LOAD_NO_RECURSE | FT_LOAD_NO_SCALE ) )
476     {
477       load_flags |= FT_LOAD_NO_BITMAP | FT_LOAD_NO_SCALE;
478 
479       if ( !FT_IS_TRICKY( face ) )
480         load_flags |= FT_LOAD_NO_HINTING;
481     }
482 
483     /* use hinted metrics only if we load a glyph with hinting */
484     ttsize->metrics = ( load_flags & FT_LOAD_NO_HINTING )
485                         ? &size->metrics
486                         : &ttsize->hinted_metrics;
487 
488     /* now fill in the glyph slot with outline/bitmap/layered */
489     error = TT_Load_Glyph( ttsize, ttslot, glyph_index, load_flags );
490 
491     /* force drop-out mode to 2 - irrelevant now */
492     /* slot->outline.dropout_mode = 2; */
493 
494     return error;
495   }
496 
497 
498   /*************************************************************************/
499   /*************************************************************************/
500   /*************************************************************************/
501   /****                                                                 ****/
502   /****                                                                 ****/
503   /****                D R I V E R  I N T E R F A C E                   ****/
504   /****                                                                 ****/
505   /****                                                                 ****/
506   /*************************************************************************/
507   /*************************************************************************/
508   /*************************************************************************/
509 
510 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
511 
512   FT_DEFINE_SERVICE_MULTIMASTERSREC(
513     tt_service_gx_multi_masters,
514 
515     NULL,                  /* FT_Get_MM_Func              get_mm                     */
516     NULL,                  /* FT_Set_MM_Design_Func       set_mm_design              */
517     TT_Set_MM_Blend,       /* FT_Set_MM_Blend_Func        set_mm_blend               */
518     TT_Get_MM_Blend,       /* FT_Get_MM_Blend_Func        get_mm_blend               */
519     TT_Get_MM_Var,         /* FT_Get_MM_Var_Func          get_mm_var                 */
520     TT_Set_Var_Design,     /* FT_Set_Var_Design_Func      set_var_design             */
521     TT_Get_Var_Design,     /* FT_Get_Var_Design_Func      get_var_design             */
522     TT_Set_Named_Instance, /* FT_Set_Named_Instance_Func  set_named_instance         */
523     TT_Get_Default_Named_Instance,
524                     /* FT_Get_Default_Named_Instance_Func get_default_named_instance */
525     NULL,                  /* FT_Set_MM_WeightVector_Func set_mm_weightvector        */
526     NULL,                  /* FT_Get_MM_WeightVector_Func get_mm_weightvector        */
527 
528     tt_construct_ps_name,  /* FT_Construct_PS_Name_Func   construct_ps_name          */
529     tt_var_load_delta_set_index_mapping,
530                     /* FT_Var_Load_Delta_Set_Idx_Map_Func load_delta_set_idx_map     */
531     tt_var_load_item_variation_store,
532                     /* FT_Var_Load_Item_Var_Store_Func    load_item_variation_store  */
533     tt_var_get_item_delta, /* FT_Var_Get_Item_Delta_Func  get_item_delta             */
534     tt_var_done_item_variation_store,
535                     /* FT_Var_Done_Item_Var_Store_Func    done_item_variation_store  */
536     tt_var_done_delta_set_index_map,
537                     /* FT_Var_Done_Delta_Set_Idx_Map_Func done_delta_set_index_map   */
538     tt_get_var_blend,      /* FT_Get_Var_Blend_Func       get_var_blend              */
539     tt_done_blend          /* FT_Done_Blend_Func          done_blend                 */
540   )
541 
542   FT_DEFINE_SERVICE_METRICSVARIATIONSREC(
543     tt_service_metrics_variations,
544 
545     tt_hadvance_adjust,   /* FT_HAdvance_Adjust_Func hadvance_adjust */
546     NULL,                 /* FT_LSB_Adjust_Func      lsb_adjust      */
547     NULL,                 /* FT_RSB_Adjust_Func      rsb_adjust      */
548 
549     tt_vadvance_adjust,   /* FT_VAdvance_Adjust_Func vadvance_adjust */
550     NULL,                 /* FT_TSB_Adjust_Func      tsb_adjust      */
551     NULL,                 /* FT_BSB_Adjust_Func      bsb_adjust      */
552     NULL,                 /* FT_VOrg_Adjust_Func     vorg_adjust     */
553 
554     tt_apply_mvar,        /* FT_Metrics_Adjust_Func  metrics_adjust  */
555     tt_size_reset_height  /* FT_Size_Reset_Func      size_reset      */
556   )
557 
558 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
559 
560 
561   static const FT_Service_TrueTypeEngineRec  tt_service_truetype_engine =
562   {
563 #ifdef TT_USE_BYTECODE_INTERPRETER
564 
565     FT_TRUETYPE_ENGINE_TYPE_PATENTED
566 
567 #else /* !TT_USE_BYTECODE_INTERPRETER */
568 
569     FT_TRUETYPE_ENGINE_TYPE_NONE
570 
571 #endif /* TT_USE_BYTECODE_INTERPRETER */
572   };
573 
574 
575   FT_DEFINE_SERVICE_TTGLYFREC(
576     tt_service_truetype_glyf,
577 
578     (TT_Glyf_GetLocationFunc)tt_face_get_location      /* get_location */
579   )
580 
581 
582 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
583   FT_DEFINE_SERVICEDESCREC6(
584     tt_services,
585 
586     FT_SERVICE_ID_FONT_FORMAT,        FT_FONT_FORMAT_TRUETYPE,
587     FT_SERVICE_ID_MULTI_MASTERS,      &tt_service_gx_multi_masters,
588     FT_SERVICE_ID_METRICS_VARIATIONS, &tt_service_metrics_variations,
589     FT_SERVICE_ID_TRUETYPE_ENGINE,    &tt_service_truetype_engine,
590     FT_SERVICE_ID_TT_GLYF,            &tt_service_truetype_glyf,
591     FT_SERVICE_ID_PROPERTIES,         &tt_service_properties )
592 #else
593   FT_DEFINE_SERVICEDESCREC4(
594     tt_services,
595 
596     FT_SERVICE_ID_FONT_FORMAT,     FT_FONT_FORMAT_TRUETYPE,
597     FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine,
598     FT_SERVICE_ID_TT_GLYF,         &tt_service_truetype_glyf,
599     FT_SERVICE_ID_PROPERTIES,      &tt_service_properties )
600 #endif
601 
602 
FT_CALLBACK_DEF(FT_Module_Interface)603   FT_CALLBACK_DEF( FT_Module_Interface )
604   tt_get_interface( FT_Module    driver,    /* TT_Driver */
605                     const char*  tt_interface )
606   {
607     FT_Library           library;
608     FT_Module_Interface  result;
609     FT_Module            sfntd;
610     SFNT_Service         sfnt;
611 
612 
613     result = ft_service_list_lookup( tt_services, tt_interface );
614     if ( result )
615       return result;
616 
617     if ( !driver )
618       return NULL;
619     library = driver->library;
620     if ( !library )
621       return NULL;
622 
623     /* only return the default interface from the SFNT module */
624     sfntd = FT_Get_Module( library, "sfnt" );
625     if ( sfntd )
626     {
627       sfnt = (SFNT_Service)( sfntd->clazz->module_interface );
628       if ( sfnt )
629         return sfnt->get_interface( driver, tt_interface );
630     }
631 
632     return 0;
633   }
634 
635 
636   /* The FT_DriverInterface structure is defined in ftdriver.h. */
637 
638 #ifdef TT_USE_BYTECODE_INTERPRETER
639 #define TT_HINTER_FLAG  FT_MODULE_DRIVER_HAS_HINTER
640 #else
641 #define TT_HINTER_FLAG  0
642 #endif
643 
644 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
645 #define TT_SIZE_SELECT  tt_size_select
646 #else
647 #define TT_SIZE_SELECT  0
648 #endif
649 
650   FT_DEFINE_DRIVER(
651     tt_driver_class,
652 
653       FT_MODULE_FONT_DRIVER     |
654       FT_MODULE_DRIVER_SCALABLE |
655       TT_HINTER_FLAG,
656 
657       sizeof ( TT_DriverRec ),
658 
659       "truetype",      /* driver name                           */
660       0x10000L,        /* driver version == 1.0                 */
661       0x20000L,        /* driver requires FreeType 2.0 or above */
662 
663       NULL,    /* module-specific interface */
664 
665       tt_driver_init,           /* FT_Module_Constructor  module_init   */
666       tt_driver_done,           /* FT_Module_Destructor   module_done   */
667       tt_get_interface,         /* FT_Module_Requester    get_interface */
668 
669     sizeof ( TT_FaceRec ),
670     sizeof ( TT_SizeRec ),
671     sizeof ( FT_GlyphSlotRec ),
672 
673     tt_face_init,               /* FT_Face_InitFunc  init_face */
674     tt_face_done,               /* FT_Face_DoneFunc  done_face */
675     tt_size_init,               /* FT_Size_InitFunc  init_size */
676     tt_size_done,               /* FT_Size_DoneFunc  done_size */
677     tt_slot_init,               /* FT_Slot_InitFunc  init_slot */
678     NULL,                       /* FT_Slot_DoneFunc  done_slot */
679 
680     tt_glyph_load,              /* FT_Slot_LoadFunc  load_glyph */
681 
682     tt_get_kerning,             /* FT_Face_GetKerningFunc   get_kerning  */
683     NULL,                       /* FT_Face_AttachFunc       attach_file  */
684     tt_get_advances,            /* FT_Face_GetAdvancesFunc  get_advances */
685 
686     tt_size_request,            /* FT_Size_RequestFunc  request_size */
687     TT_SIZE_SELECT              /* FT_Size_SelectFunc   select_size  */
688   )
689 
690 
691 /* END */
692