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