• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /****************************************************************************
2  *
3  * cffobjs.c
4  *
5  *   OpenType objects manager (body).
6  *
7  * Copyright (C) 1996-2020 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 
20 #include <freetype/internal/ftdebug.h>
21 #include <freetype/internal/ftcalc.h>
22 #include <freetype/internal/ftstream.h>
23 #include <freetype/fterrors.h>
24 #include <freetype/ttnameid.h>
25 #include <freetype/tttags.h>
26 #include <freetype/internal/sfnt.h>
27 #include <freetype/ftdriver.h>
28 
29 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
30 #include <freetype/ftmm.h>
31 #include <freetype/internal/services/svmm.h>
32 #include <freetype/internal/services/svmetric.h>
33 #endif
34 
35 #include <freetype/internal/cffotypes.h>
36 #include "cffobjs.h"
37 #include "cffload.h"
38 #include "cffcmap.h"
39 
40 #include "cfferrs.h"
41 
42 #include <freetype/internal/psaux.h>
43 #include <freetype/internal/services/svcfftl.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  cffobjs
54 
55 
56   /**************************************************************************
57    *
58    *                           SIZE FUNCTIONS
59    *
60    */
61 
62 
63   static PSH_Globals_Funcs
cff_size_get_globals_funcs(CFF_Size size)64   cff_size_get_globals_funcs( CFF_Size  size )
65   {
66     CFF_Face          face     = (CFF_Face)size->root.face;
67     CFF_Font          font     = (CFF_Font)face->extra.data;
68     PSHinter_Service  pshinter = font->pshinter;
69     FT_Module         module;
70 
71 
72     module = FT_Get_Module( size->root.face->driver->root.library,
73                             "pshinter" );
74     return ( module && pshinter && pshinter->get_globals_funcs )
75            ? pshinter->get_globals_funcs( module )
76            : 0;
77   }
78 
79 
80   FT_LOCAL_DEF( void )
cff_size_done(FT_Size cffsize)81   cff_size_done( FT_Size  cffsize )        /* CFF_Size */
82   {
83     FT_Memory     memory   = cffsize->face->memory;
84     CFF_Size      size     = (CFF_Size)cffsize;
85     CFF_Face      face     = (CFF_Face)size->root.face;
86     CFF_Font      font     = (CFF_Font)face->extra.data;
87     CFF_Internal  internal = (CFF_Internal)cffsize->internal->module_data;
88 
89 
90     if ( internal )
91     {
92       PSH_Globals_Funcs  funcs;
93 
94 
95       funcs = cff_size_get_globals_funcs( size );
96       if ( funcs )
97       {
98         FT_UInt  i;
99 
100 
101         funcs->destroy( internal->topfont );
102 
103         for ( i = font->num_subfonts; i > 0; i-- )
104           funcs->destroy( internal->subfonts[i - 1] );
105       }
106 
107       FT_FREE( internal );
108     }
109   }
110 
111 
112   /* CFF and Type 1 private dictionaries have slightly different      */
113   /* structures; we need to synthesize a Type 1 dictionary on the fly */
114 
115   static void
cff_make_private_dict(CFF_SubFont subfont,PS_Private priv)116   cff_make_private_dict( CFF_SubFont  subfont,
117                          PS_Private   priv )
118   {
119     CFF_Private  cpriv = &subfont->private_dict;
120     FT_UInt      n, count;
121 
122 
123     FT_ZERO( priv );
124 
125     count = priv->num_blue_values = cpriv->num_blue_values;
126     for ( n = 0; n < count; n++ )
127       priv->blue_values[n] = (FT_Short)cpriv->blue_values[n];
128 
129     count = priv->num_other_blues = cpriv->num_other_blues;
130     for ( n = 0; n < count; n++ )
131       priv->other_blues[n] = (FT_Short)cpriv->other_blues[n];
132 
133     count = priv->num_family_blues = cpriv->num_family_blues;
134     for ( n = 0; n < count; n++ )
135       priv->family_blues[n] = (FT_Short)cpriv->family_blues[n];
136 
137     count = priv->num_family_other_blues = cpriv->num_family_other_blues;
138     for ( n = 0; n < count; n++ )
139       priv->family_other_blues[n] = (FT_Short)cpriv->family_other_blues[n];
140 
141     priv->blue_scale = cpriv->blue_scale;
142     priv->blue_shift = (FT_Int)cpriv->blue_shift;
143     priv->blue_fuzz  = (FT_Int)cpriv->blue_fuzz;
144 
145     priv->standard_width[0]  = (FT_UShort)cpriv->standard_width;
146     priv->standard_height[0] = (FT_UShort)cpriv->standard_height;
147 
148     count = priv->num_snap_widths = cpriv->num_snap_widths;
149     for ( n = 0; n < count; n++ )
150       priv->snap_widths[n] = (FT_Short)cpriv->snap_widths[n];
151 
152     count = priv->num_snap_heights = cpriv->num_snap_heights;
153     for ( n = 0; n < count; n++ )
154       priv->snap_heights[n] = (FT_Short)cpriv->snap_heights[n];
155 
156     priv->force_bold     = cpriv->force_bold;
157     priv->language_group = cpriv->language_group;
158     priv->lenIV          = cpriv->lenIV;
159   }
160 
161 
162   FT_LOCAL_DEF( FT_Error )
cff_size_init(FT_Size cffsize)163   cff_size_init( FT_Size  cffsize )         /* CFF_Size */
164   {
165     CFF_Size           size  = (CFF_Size)cffsize;
166     FT_Error           error = FT_Err_Ok;
167     PSH_Globals_Funcs  funcs = cff_size_get_globals_funcs( size );
168 
169     FT_Memory     memory   = cffsize->face->memory;
170     CFF_Internal  internal = NULL;
171     CFF_Face      face     = (CFF_Face)cffsize->face;
172     CFF_Font      font     = (CFF_Font)face->extra.data;
173 
174     PS_PrivateRec priv;
175 
176     FT_UInt       i;
177 
178     if ( !funcs )
179       goto Exit;
180 
181     if ( FT_NEW( internal ) )
182       goto Exit;
183 
184     cff_make_private_dict( &font->top_font, &priv );
185     error = funcs->create( cffsize->face->memory, &priv,
186                              &internal->topfont );
187     if ( error )
188       goto Exit;
189 
190     for ( i = font->num_subfonts; i > 0; i-- )
191     {
192       CFF_SubFont  sub = font->subfonts[i - 1];
193 
194 
195       cff_make_private_dict( sub, &priv );
196       error = funcs->create( cffsize->face->memory, &priv,
197                                &internal->subfonts[i - 1] );
198       if ( error )
199         goto Exit;
200     }
201 
202     cffsize->internal->module_data = internal;
203 
204     size->strike_index = 0xFFFFFFFFUL;
205 
206   Exit:
207     if ( error )
208     {
209       if ( internal )
210       {
211         for ( i = font->num_subfonts; i > 0; i-- )
212           FT_FREE( internal->subfonts[i - 1] );
213         FT_FREE( internal->topfont );
214       }
215 
216       FT_FREE( internal );
217     }
218 
219     return error;
220   }
221 
222 
223 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
224 
225   FT_LOCAL_DEF( FT_Error )
cff_size_select(FT_Size size,FT_ULong strike_index)226   cff_size_select( FT_Size   size,
227                    FT_ULong  strike_index )
228   {
229     CFF_Size           cffsize = (CFF_Size)size;
230     PSH_Globals_Funcs  funcs;
231 
232 
233     cffsize->strike_index = strike_index;
234 
235     FT_Select_Metrics( size->face, strike_index );
236 
237     funcs = cff_size_get_globals_funcs( cffsize );
238 
239     if ( funcs )
240     {
241       CFF_Face      face     = (CFF_Face)size->face;
242       CFF_Font      font     = (CFF_Font)face->extra.data;
243       CFF_Internal  internal = (CFF_Internal)size->internal->module_data;
244 
245       FT_Long  top_upm  = (FT_Long)font->top_font.font_dict.units_per_em;
246       FT_UInt  i;
247 
248 
249       funcs->set_scale( internal->topfont,
250                         size->metrics.x_scale, size->metrics.y_scale,
251                         0, 0 );
252 
253       for ( i = font->num_subfonts; i > 0; i-- )
254       {
255         CFF_SubFont  sub     = font->subfonts[i - 1];
256         FT_Long      sub_upm = (FT_Long)sub->font_dict.units_per_em;
257         FT_Pos       x_scale, y_scale;
258 
259 
260         if ( top_upm != sub_upm )
261         {
262           x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm );
263           y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm );
264         }
265         else
266         {
267           x_scale = size->metrics.x_scale;
268           y_scale = size->metrics.y_scale;
269         }
270 
271         funcs->set_scale( internal->subfonts[i - 1],
272                           x_scale, y_scale, 0, 0 );
273       }
274     }
275 
276     return FT_Err_Ok;
277   }
278 
279 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
280 
281 
282   FT_LOCAL_DEF( FT_Error )
cff_size_request(FT_Size size,FT_Size_Request req)283   cff_size_request( FT_Size          size,
284                     FT_Size_Request  req )
285   {
286     CFF_Size           cffsize = (CFF_Size)size;
287     PSH_Globals_Funcs  funcs;
288 
289 
290 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
291 
292     if ( FT_HAS_FIXED_SIZES( size->face ) )
293     {
294       CFF_Face      cffface = (CFF_Face)size->face;
295       SFNT_Service  sfnt    = (SFNT_Service)cffface->sfnt;
296       FT_ULong      strike_index;
297 
298 
299       if ( sfnt->set_sbit_strike( cffface, req, &strike_index ) )
300         cffsize->strike_index = 0xFFFFFFFFUL;
301       else
302         return cff_size_select( size, strike_index );
303     }
304 
305 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
306 
307     FT_Request_Metrics( size->face, req );
308 
309     funcs = cff_size_get_globals_funcs( cffsize );
310 
311     if ( funcs )
312     {
313       CFF_Face      cffface  = (CFF_Face)size->face;
314       CFF_Font      font     = (CFF_Font)cffface->extra.data;
315       CFF_Internal  internal = (CFF_Internal)size->internal->module_data;
316 
317       FT_Long  top_upm  = (FT_Long)font->top_font.font_dict.units_per_em;
318       FT_UInt  i;
319 
320 
321       funcs->set_scale( internal->topfont,
322                         size->metrics.x_scale, size->metrics.y_scale,
323                         0, 0 );
324 
325       for ( i = font->num_subfonts; i > 0; i-- )
326       {
327         CFF_SubFont  sub     = font->subfonts[i - 1];
328         FT_Long      sub_upm = (FT_Long)sub->font_dict.units_per_em;
329         FT_Pos       x_scale, y_scale;
330 
331 
332         if ( top_upm != sub_upm )
333         {
334           x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm );
335           y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm );
336         }
337         else
338         {
339           x_scale = size->metrics.x_scale;
340           y_scale = size->metrics.y_scale;
341         }
342 
343         funcs->set_scale( internal->subfonts[i - 1],
344                           x_scale, y_scale, 0, 0 );
345       }
346     }
347 
348     return FT_Err_Ok;
349   }
350 
351 
352   /**************************************************************************
353    *
354    *                           SLOT  FUNCTIONS
355    *
356    */
357 
358   FT_LOCAL_DEF( void )
cff_slot_done(FT_GlyphSlot slot)359   cff_slot_done( FT_GlyphSlot  slot )
360   {
361     if ( slot->internal )
362       slot->internal->glyph_hints = NULL;
363   }
364 
365 
366   FT_LOCAL_DEF( FT_Error )
cff_slot_init(FT_GlyphSlot slot)367   cff_slot_init( FT_GlyphSlot  slot )
368   {
369     CFF_Face          face     = (CFF_Face)slot->face;
370     CFF_Font          font     = (CFF_Font)face->extra.data;
371     PSHinter_Service  pshinter = font->pshinter;
372 
373 
374     if ( pshinter )
375     {
376       FT_Module  module;
377 
378 
379       module = FT_Get_Module( slot->face->driver->root.library,
380                               "pshinter" );
381       if ( module )
382       {
383         T2_Hints_Funcs  funcs;
384 
385 
386         funcs = pshinter->get_t2_funcs( module );
387         slot->internal->glyph_hints = (void*)funcs;
388       }
389     }
390 
391     return FT_Err_Ok;
392   }
393 
394 
395   /**************************************************************************
396    *
397    *                          FACE  FUNCTIONS
398    *
399    */
400 
401   static FT_String*
cff_strcpy(FT_Memory memory,const FT_String * source)402   cff_strcpy( FT_Memory         memory,
403               const FT_String*  source )
404   {
405     FT_Error    error;
406     FT_String*  result;
407 
408 
409     (void)FT_STRDUP( result, source );
410 
411     FT_UNUSED( error );
412 
413     return result;
414   }
415 
416 
417   /* Strip all subset prefixes of the form `ABCDEF+'.  Usually, there */
418   /* is only one, but font names like `APCOOG+JFABTD+FuturaBQ-Bold'   */
419   /* have been seen in the wild.                                      */
420 
421   static void
remove_subset_prefix(FT_String * name)422   remove_subset_prefix( FT_String*  name )
423   {
424     FT_Int32  idx             = 0;
425     FT_Int32  length          = (FT_Int32)ft_strlen( name ) + 1;
426     FT_Bool   continue_search = 1;
427 
428 
429     while ( continue_search )
430     {
431       if ( length >= 7 && name[6] == '+' )
432       {
433         for ( idx = 0; idx < 6; idx++ )
434         {
435           /* ASCII uppercase letters */
436           if ( !( 'A' <= name[idx] && name[idx] <= 'Z' ) )
437             continue_search = 0;
438         }
439 
440         if ( continue_search )
441         {
442           for ( idx = 7; idx < length; idx++ )
443             name[idx - 7] = name[idx];
444           length -= 7;
445         }
446       }
447       else
448         continue_search = 0;
449     }
450   }
451 
452 
453   /* Remove the style part from the family name (if present). */
454 
455   static void
remove_style(FT_String * family_name,const FT_String * style_name)456   remove_style( FT_String*        family_name,
457                 const FT_String*  style_name )
458   {
459     FT_Int32  family_name_length, style_name_length;
460 
461 
462     family_name_length = (FT_Int32)ft_strlen( family_name );
463     style_name_length  = (FT_Int32)ft_strlen( style_name );
464 
465     if ( family_name_length > style_name_length )
466     {
467       FT_Int  idx;
468 
469 
470       for ( idx = 1; idx <= style_name_length; idx++ )
471       {
472         if ( family_name[family_name_length - idx] !=
473              style_name[style_name_length - idx] )
474           break;
475       }
476 
477       if ( idx > style_name_length )
478       {
479         /* family_name ends with style_name; remove it */
480         idx = family_name_length - style_name_length - 1;
481 
482         /* also remove special characters     */
483         /* between real family name and style */
484         while ( idx > 0                     &&
485                 ( family_name[idx] == '-' ||
486                   family_name[idx] == ' ' ||
487                   family_name[idx] == '_' ||
488                   family_name[idx] == '+' ) )
489           idx--;
490 
491         if ( idx > 0 )
492           family_name[idx + 1] = '\0';
493       }
494     }
495   }
496 
497 
498   FT_LOCAL_DEF( FT_Error )
cff_face_init(FT_Stream stream,FT_Face cffface,FT_Int face_index,FT_Int num_params,FT_Parameter * params)499   cff_face_init( FT_Stream      stream,
500                  FT_Face        cffface,        /* CFF_Face */
501                  FT_Int         face_index,
502                  FT_Int         num_params,
503                  FT_Parameter*  params )
504   {
505     CFF_Face            face        = (CFF_Face)cffface;
506     FT_Error            error;
507     SFNT_Service        sfnt;
508     FT_Service_PsCMaps  psnames;
509     PSHinter_Service    pshinter;
510     PSAux_Service       psaux;
511     FT_Service_CFFLoad  cffload;
512     FT_Bool             pure_cff    = 1;
513     FT_Bool             cff2        = 0;
514     FT_Bool             sfnt_format = 0;
515     FT_Library          library     = cffface->driver->root.library;
516 
517 
518     sfnt = (SFNT_Service)FT_Get_Module_Interface( library,
519                                                   "sfnt" );
520     if ( !sfnt )
521     {
522       FT_ERROR(( "cff_face_init: cannot access `sfnt' module\n" ));
523       error = FT_THROW( Missing_Module );
524       goto Exit;
525     }
526 
527     FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
528 
529     pshinter = (PSHinter_Service)FT_Get_Module_Interface( library,
530                                                           "pshinter" );
531 
532     psaux = (PSAux_Service)FT_Get_Module_Interface( library,
533                                                     "psaux" );
534     if ( !psaux )
535     {
536       FT_ERROR(( "cff_face_init: cannot access `psaux' module\n" ));
537       error = FT_THROW( Missing_Module );
538       goto Exit;
539     }
540     face->psaux = psaux;
541 
542     FT_FACE_FIND_GLOBAL_SERVICE( face, cffload, CFF_LOAD );
543 
544     FT_TRACE2(( "CFF driver\n" ));
545 
546     /* create input stream from resource */
547     if ( FT_STREAM_SEEK( 0 ) )
548       goto Exit;
549 
550     /* check whether we have a valid OpenType file */
551     FT_TRACE2(( "  " ));
552     error = sfnt->init_face( stream, face, face_index, num_params, params );
553     if ( !error )
554     {
555       if ( face->format_tag != TTAG_OTTO )  /* `OTTO'; OpenType/CFF font */
556       {
557         FT_TRACE2(( "  not an OpenType/CFF font\n" ));
558         error = FT_THROW( Unknown_File_Format );
559         goto Exit;
560       }
561 
562       /* if we are performing a simple font format check, exit immediately */
563       if ( face_index < 0 )
564         return FT_Err_Ok;
565 
566       sfnt_format = 1;
567 
568       /* now, the font can be either an OpenType/CFF font, or an SVG CEF */
569       /* font; in the latter case it doesn't have a `head' table         */
570       error = face->goto_table( face, TTAG_head, stream, 0 );
571       if ( !error )
572       {
573         pure_cff = 0;
574 
575         /* load font directory */
576         error = sfnt->load_face( stream, face, face_index,
577                                  num_params, params );
578         if ( error )
579           goto Exit;
580       }
581       else
582       {
583         /* load the `cmap' table explicitly */
584         error = sfnt->load_cmap( face, stream );
585         if ( error )
586           goto Exit;
587       }
588 
589       /* now load the CFF part of the file; */
590       /* give priority to CFF2              */
591       error = face->goto_table( face, TTAG_CFF2, stream, 0 );
592       if ( !error )
593       {
594         cff2          = 1;
595         face->is_cff2 = cff2;
596       }
597 
598       if ( FT_ERR_EQ( error, Table_Missing ) )
599         error = face->goto_table( face, TTAG_CFF, stream, 0 );
600 
601       if ( error )
602         goto Exit;
603     }
604     else
605     {
606       /* rewind to start of file; we are going to load a pure-CFF font */
607       if ( FT_STREAM_SEEK( 0 ) )
608         goto Exit;
609       error = FT_Err_Ok;
610     }
611 
612     /* now load and parse the CFF table in the file */
613     {
614       CFF_Font         cff = NULL;
615       CFF_FontRecDict  dict;
616       FT_Memory        memory = cffface->memory;
617       FT_Int32         flags;
618       FT_UInt          i;
619 
620 
621       if ( FT_NEW( cff ) )
622         goto Exit;
623 
624       face->extra.data = cff;
625       error = cff_font_load( library,
626                              stream,
627                              face_index,
628                              cff,
629                              face,
630                              pure_cff,
631                              cff2 );
632       if ( error )
633         goto Exit;
634 
635       /* if we are performing a simple font format check, exit immediately */
636       /* (this is here for pure CFF)                                       */
637       if ( face_index < 0 )
638       {
639         cffface->num_faces = (FT_Long)cff->num_faces;
640         return FT_Err_Ok;
641       }
642 
643       cff->pshinter = pshinter;
644       cff->psnames  = psnames;
645       cff->cffload  = cffload;
646 
647       cffface->face_index = face_index & 0xFFFF;
648 
649       /* Complement the root flags with some interesting information. */
650       /* Note that this is only necessary for pure CFF and CEF fonts; */
651       /* SFNT based fonts use the `name' table instead.               */
652 
653       cffface->num_glyphs = (FT_Long)cff->num_glyphs;
654 
655       dict = &cff->top_font.font_dict;
656 
657       /* we need the `psnames' module for CFF and CEF formats */
658       /* which aren't CID-keyed                               */
659       if ( dict->cid_registry == 0xFFFFU && !psnames )
660       {
661         FT_ERROR(( "cff_face_init:"
662                    " cannot open CFF & CEF fonts\n"
663                    "              "
664                    " without the `psnames' module\n" ));
665         error = FT_THROW( Missing_Module );
666         goto Exit;
667       }
668 
669 #ifdef FT_DEBUG_LEVEL_TRACE
670       {
671         FT_UInt     idx;
672         FT_String*  s;
673 
674 
675         FT_TRACE4(( "SIDs\n" ));
676 
677         /* dump string index, including default strings for convenience */
678         for ( idx = 0; idx <= 390; idx++ )
679         {
680           s = cff_index_get_sid_string( cff, idx );
681           if ( s )
682             FT_TRACE4(( "  %5d %s\n", idx, s ));
683         }
684 
685         /* In Multiple Master CFFs, two SIDs hold the Normalize Design  */
686         /* Vector (NDV) and Convert Design Vector (CDV) charstrings,    */
687         /* which may contain NULL bytes in the middle of the data, too. */
688         /* We thus access `cff->strings' directly.                      */
689         for ( idx = 1; idx < cff->num_strings; idx++ )
690         {
691           FT_Byte*    s1    = cff->strings[idx - 1];
692           FT_Byte*    s2    = cff->strings[idx];
693           FT_PtrDist  s1len = s2 - s1 - 1; /* without the final NULL byte */
694           FT_PtrDist  l;
695 
696 
697           FT_TRACE4(( "  %5d ", idx + 390 ));
698           for ( l = 0; l < s1len; l++ )
699             FT_TRACE4(( "%c", s1[l] ));
700           FT_TRACE4(( "\n" ));
701         }
702 
703         /* print last element */
704         if ( cff->num_strings )
705         {
706           FT_Byte*    s1    = cff->strings[cff->num_strings - 1];
707           FT_Byte*    s2    = cff->string_pool + cff->string_pool_size;
708           FT_PtrDist  s1len = s2 - s1 - 1;
709           FT_PtrDist  l;
710 
711 
712           FT_TRACE4(( "  %5d ", cff->num_strings + 390 ));
713           for ( l = 0; l < s1len; l++ )
714             FT_TRACE4(( "%c", s1[l] ));
715           FT_TRACE4(( "\n" ));
716         }
717       }
718 #endif /* FT_DEBUG_LEVEL_TRACE */
719 
720 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
721       {
722         FT_Service_MultiMasters       mm  = (FT_Service_MultiMasters)face->mm;
723         FT_Service_MetricsVariations  var = (FT_Service_MetricsVariations)face->var;
724 
725         FT_UInt  instance_index = (FT_UInt)face_index >> 16;
726 
727 
728         if ( FT_HAS_MULTIPLE_MASTERS( cffface ) &&
729              mm                                 &&
730              instance_index > 0                 )
731         {
732           error = mm->set_instance( cffface, instance_index );
733           if ( error )
734             goto Exit;
735 
736           if ( var )
737             var->metrics_adjust( cffface );
738         }
739       }
740 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
741 
742       if ( !dict->has_font_matrix )
743         dict->units_per_em = pure_cff ? 1000 : face->root.units_per_EM;
744 
745       /* Normalize the font matrix so that `matrix->yy' is 1; if  */
746       /* it is zero, we use `matrix->yx' instead.  The scaling is */
747       /* done with `units_per_em' then (at this point, it already */
748       /* contains the scaling factor, but without normalization   */
749       /* of the matrix).                                          */
750       /*                                                          */
751       /* Note that the offsets must be expressed in integer font  */
752       /* units.                                                   */
753 
754       {
755         FT_Matrix*  matrix = &dict->font_matrix;
756         FT_Vector*  offset = &dict->font_offset;
757         FT_ULong*   upm    = &dict->units_per_em;
758         FT_Fixed    temp;
759 
760 
761         temp = matrix->yy ? FT_ABS( matrix->yy )
762                           : FT_ABS( matrix->yx );
763 
764         if ( temp != 0x10000L )
765         {
766           *upm = (FT_ULong)FT_DivFix( (FT_Long)*upm, temp );
767 
768           matrix->xx = FT_DivFix( matrix->xx, temp );
769           matrix->yx = FT_DivFix( matrix->yx, temp );
770           matrix->xy = FT_DivFix( matrix->xy, temp );
771           matrix->yy = FT_DivFix( matrix->yy, temp );
772           offset->x  = FT_DivFix( offset->x,  temp );
773           offset->y  = FT_DivFix( offset->y,  temp );
774         }
775 
776         offset->x >>= 16;
777         offset->y >>= 16;
778       }
779 
780       for ( i = cff->num_subfonts; i > 0; i-- )
781       {
782         CFF_FontRecDict  sub = &cff->subfonts[i - 1]->font_dict;
783         CFF_FontRecDict  top = &cff->top_font.font_dict;
784 
785         FT_Matrix*  matrix;
786         FT_Vector*  offset;
787         FT_ULong*   upm;
788         FT_Fixed    temp;
789 
790 
791         if ( sub->has_font_matrix )
792         {
793           FT_Long  scaling;
794 
795 
796           /* if we have a top-level matrix, */
797           /* concatenate the subfont matrix */
798 
799           if ( top->has_font_matrix )
800           {
801             if ( top->units_per_em > 1 && sub->units_per_em > 1 )
802               scaling = (FT_Long)FT_MIN( top->units_per_em,
803                                          sub->units_per_em );
804             else
805               scaling = 1;
806 
807             FT_Matrix_Multiply_Scaled( &top->font_matrix,
808                                        &sub->font_matrix,
809                                        scaling );
810             FT_Vector_Transform_Scaled( &sub->font_offset,
811                                         &top->font_matrix,
812                                         scaling );
813 
814             sub->units_per_em = (FT_ULong)
815                                   FT_MulDiv( (FT_Long)sub->units_per_em,
816                                              (FT_Long)top->units_per_em,
817                                              scaling );
818           }
819         }
820         else
821         {
822           sub->font_matrix = top->font_matrix;
823           sub->font_offset = top->font_offset;
824 
825           sub->units_per_em = top->units_per_em;
826         }
827 
828         matrix = &sub->font_matrix;
829         offset = &sub->font_offset;
830         upm    = &sub->units_per_em;
831 
832         temp = matrix->yy ? FT_ABS( matrix->yy )
833                           : FT_ABS( matrix->yx );
834 
835 
836         if ( temp != 0x10000L )
837         {
838           *upm = (FT_ULong)FT_DivFix( (FT_Long)*upm, temp );
839 
840           matrix->xx = FT_DivFix( matrix->xx, temp );
841           matrix->yx = FT_DivFix( matrix->yx, temp );
842           matrix->xy = FT_DivFix( matrix->xy, temp );
843           matrix->yy = FT_DivFix( matrix->yy, temp );
844           offset->x  = FT_DivFix( offset->x,  temp );
845           offset->y  = FT_DivFix( offset->y,  temp );
846         }
847 
848         offset->x >>= 16;
849         offset->y >>= 16;
850       }
851 
852       if ( pure_cff )
853       {
854         char*  style_name = NULL;
855 
856 
857         /* set up num_faces */
858         cffface->num_faces = (FT_Long)cff->num_faces;
859 
860         /* compute number of glyphs */
861         if ( dict->cid_registry != 0xFFFFU )
862           cffface->num_glyphs = (FT_Long)( cff->charset.max_cid + 1 );
863         else
864           cffface->num_glyphs = (FT_Long)cff->charstrings_index.count;
865 
866         /* set global bbox, as well as EM size */
867         cffface->bbox.xMin =   dict->font_bbox.xMin            >> 16;
868         cffface->bbox.yMin =   dict->font_bbox.yMin            >> 16;
869         /* no `U' suffix here to 0xFFFF! */
870         cffface->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFF ) >> 16;
871         cffface->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFF ) >> 16;
872 
873         cffface->units_per_EM = (FT_UShort)( dict->units_per_em );
874 
875         cffface->ascender  = (FT_Short)( cffface->bbox.yMax );
876         cffface->descender = (FT_Short)( cffface->bbox.yMin );
877 
878         cffface->height = (FT_Short)( ( cffface->units_per_EM * 12 ) / 10 );
879         if ( cffface->height < cffface->ascender - cffface->descender )
880           cffface->height = (FT_Short)( cffface->ascender -
881                                         cffface->descender );
882 
883         cffface->underline_position  =
884           (FT_Short)( dict->underline_position >> 16 );
885         cffface->underline_thickness =
886           (FT_Short)( dict->underline_thickness >> 16 );
887 
888         /* retrieve font family & style name */
889         if ( dict->family_name )
890         {
891           char*  family_name;
892 
893 
894           family_name = cff_index_get_sid_string( cff, dict->family_name );
895           if ( family_name )
896             cffface->family_name = cff_strcpy( memory, family_name );
897         }
898 
899         if ( !cffface->family_name )
900         {
901           cffface->family_name = cff_index_get_name(
902                                    cff,
903                                    (FT_UInt)( face_index & 0xFFFF ) );
904           if ( cffface->family_name )
905             remove_subset_prefix( cffface->family_name );
906         }
907 
908         if ( cffface->family_name )
909         {
910           char*  full   = cff_index_get_sid_string( cff,
911                                                     dict->full_name );
912           char*  fullp  = full;
913           char*  family = cffface->family_name;
914 
915 
916           /* We try to extract the style name from the full name.   */
917           /* We need to ignore spaces and dashes during the search. */
918           if ( full && family )
919           {
920             while ( *fullp )
921             {
922               /* skip common characters at the start of both strings */
923               if ( *fullp == *family )
924               {
925                 family++;
926                 fullp++;
927                 continue;
928               }
929 
930               /* ignore spaces and dashes in full name during comparison */
931               if ( *fullp == ' ' || *fullp == '-' )
932               {
933                 fullp++;
934                 continue;
935               }
936 
937               /* ignore spaces and dashes in family name during comparison */
938               if ( *family == ' ' || *family == '-' )
939               {
940                 family++;
941                 continue;
942               }
943 
944               if ( !*family && *fullp )
945               {
946                 /* The full name begins with the same characters as the  */
947                 /* family name, with spaces and dashes removed.  In this */
948                 /* case, the remaining string in `fullp' will be used as */
949                 /* the style name.                                       */
950                 style_name = cff_strcpy( memory, fullp );
951 
952                 /* remove the style part from the family name (if present) */
953                 if ( style_name )
954                   remove_style( cffface->family_name, style_name );
955               }
956               break;
957             }
958           }
959         }
960         else
961         {
962           char  *cid_font_name =
963                    cff_index_get_sid_string( cff,
964                                              dict->cid_font_name );
965 
966 
967           /* do we have a `/FontName' for a CID-keyed font? */
968           if ( cid_font_name )
969             cffface->family_name = cff_strcpy( memory, cid_font_name );
970         }
971 
972         if ( style_name )
973           cffface->style_name = style_name;
974         else
975           /* assume "Regular" style if we don't know better */
976           cffface->style_name = cff_strcpy( memory, "Regular" );
977 
978         /********************************************************************
979          *
980          * Compute face flags.
981          */
982         flags = FT_FACE_FLAG_SCALABLE   | /* scalable outlines */
983                 FT_FACE_FLAG_HORIZONTAL | /* horizontal data   */
984                 FT_FACE_FLAG_HINTER;      /* has native hinter */
985 
986         if ( sfnt_format )
987           flags |= FT_FACE_FLAG_SFNT;
988 
989         /* fixed width font? */
990         if ( dict->is_fixed_pitch )
991           flags |= FT_FACE_FLAG_FIXED_WIDTH;
992 
993   /* XXX: WE DO NOT SUPPORT KERNING METRICS IN THE GPOS TABLE FOR NOW */
994 #if 0
995         /* kerning available? */
996         if ( face->kern_pairs )
997           flags |= FT_FACE_FLAG_KERNING;
998 #endif
999 
1000         cffface->face_flags |= flags;
1001 
1002         /********************************************************************
1003          *
1004          * Compute style flags.
1005          */
1006         flags = 0;
1007 
1008         if ( dict->italic_angle )
1009           flags |= FT_STYLE_FLAG_ITALIC;
1010 
1011         {
1012           char  *weight = cff_index_get_sid_string( cff,
1013                                                     dict->weight );
1014 
1015 
1016           if ( weight )
1017             if ( !ft_strcmp( weight, "Bold"  ) ||
1018                  !ft_strcmp( weight, "Black" ) )
1019               flags |= FT_STYLE_FLAG_BOLD;
1020         }
1021 
1022         /* double check */
1023         if ( !(flags & FT_STYLE_FLAG_BOLD) && cffface->style_name )
1024           if ( !ft_strncmp( cffface->style_name, "Bold", 4 )  ||
1025                !ft_strncmp( cffface->style_name, "Black", 5 ) )
1026             flags |= FT_STYLE_FLAG_BOLD;
1027 
1028         cffface->style_flags = flags;
1029       }
1030 
1031 #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
1032       /* CID-keyed CFF or CFF2 fonts don't have glyph names -- the SFNT */
1033       /* loader has unset this flag because of the 3.0 `post' table.    */
1034       if ( dict->cid_registry == 0xFFFFU && !cff2 )
1035         cffface->face_flags |= FT_FACE_FLAG_GLYPH_NAMES;
1036 #endif
1037 
1038       if ( dict->cid_registry != 0xFFFFU && pure_cff )
1039         cffface->face_flags |= FT_FACE_FLAG_CID_KEYED;
1040 
1041       /********************************************************************
1042        *
1043        * Compute char maps.
1044        */
1045 
1046       /* Try to synthesize a Unicode charmap if there is none available */
1047       /* already.  If an OpenType font contains a Unicode "cmap", we    */
1048       /* will use it, whatever be in the CFF part of the file.          */
1049       {
1050         FT_CharMapRec  cmaprec;
1051         FT_CharMap     cmap;
1052         FT_UInt        nn;
1053         CFF_Encoding   encoding = &cff->encoding;
1054 
1055 
1056         for ( nn = 0; nn < (FT_UInt)cffface->num_charmaps; nn++ )
1057         {
1058           cmap = cffface->charmaps[nn];
1059 
1060           /* Windows Unicode? */
1061           if ( cmap->platform_id == TT_PLATFORM_MICROSOFT &&
1062                cmap->encoding_id == TT_MS_ID_UNICODE_CS   )
1063             goto Skip_Unicode;
1064 
1065           /* Apple Unicode platform id? */
1066           if ( cmap->platform_id == TT_PLATFORM_APPLE_UNICODE )
1067             goto Skip_Unicode; /* Apple Unicode */
1068         }
1069 
1070         /* since CID-keyed fonts don't contain glyph names, we can't */
1071         /* construct a cmap                                          */
1072         if ( pure_cff && cff->top_font.font_dict.cid_registry != 0xFFFFU )
1073           goto Exit;
1074 
1075         /* we didn't find a Unicode charmap -- synthesize one */
1076         cmaprec.face        = cffface;
1077         cmaprec.platform_id = TT_PLATFORM_MICROSOFT;
1078         cmaprec.encoding_id = TT_MS_ID_UNICODE_CS;
1079         cmaprec.encoding    = FT_ENCODING_UNICODE;
1080 
1081         nn = (FT_UInt)cffface->num_charmaps;
1082 
1083         error = FT_CMap_New( &cff_cmap_unicode_class_rec, NULL,
1084                              &cmaprec, NULL );
1085         if ( error                                      &&
1086              FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) &&
1087              FT_ERR_NEQ( error, Unimplemented_Feature ) )
1088           goto Exit;
1089         error = FT_Err_Ok;
1090 
1091         /* if no Unicode charmap was previously selected, select this one */
1092         if ( !cffface->charmap && nn != (FT_UInt)cffface->num_charmaps )
1093           cffface->charmap = cffface->charmaps[nn];
1094 
1095       Skip_Unicode:
1096         if ( encoding->count > 0 )
1097         {
1098           FT_CMap_Class  clazz;
1099 
1100 
1101           cmaprec.face        = cffface;
1102           cmaprec.platform_id = TT_PLATFORM_ADOBE;  /* Adobe platform id */
1103 
1104           if ( encoding->offset == 0 )
1105           {
1106             cmaprec.encoding_id = TT_ADOBE_ID_STANDARD;
1107             cmaprec.encoding    = FT_ENCODING_ADOBE_STANDARD;
1108             clazz               = &cff_cmap_encoding_class_rec;
1109           }
1110           else if ( encoding->offset == 1 )
1111           {
1112             cmaprec.encoding_id = TT_ADOBE_ID_EXPERT;
1113             cmaprec.encoding    = FT_ENCODING_ADOBE_EXPERT;
1114             clazz               = &cff_cmap_encoding_class_rec;
1115           }
1116           else
1117           {
1118             cmaprec.encoding_id = TT_ADOBE_ID_CUSTOM;
1119             cmaprec.encoding    = FT_ENCODING_ADOBE_CUSTOM;
1120             clazz               = &cff_cmap_encoding_class_rec;
1121           }
1122 
1123           error = FT_CMap_New( clazz, NULL, &cmaprec, NULL );
1124         }
1125       }
1126     }
1127 
1128   Exit:
1129     return error;
1130   }
1131 
1132 
1133   FT_LOCAL_DEF( void )
cff_face_done(FT_Face cffface)1134   cff_face_done( FT_Face  cffface )         /* CFF_Face */
1135   {
1136     CFF_Face      face = (CFF_Face)cffface;
1137     FT_Memory     memory;
1138     SFNT_Service  sfnt;
1139 
1140 
1141     if ( !face )
1142       return;
1143 
1144     memory = cffface->memory;
1145     sfnt   = (SFNT_Service)face->sfnt;
1146 
1147     if ( sfnt )
1148       sfnt->done_face( face );
1149 
1150     {
1151       CFF_Font  cff = (CFF_Font)face->extra.data;
1152 
1153 
1154       if ( cff )
1155       {
1156         cff_font_done( cff );
1157         FT_FREE( face->extra.data );
1158       }
1159     }
1160 
1161 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1162     cff_done_blend( face );
1163     face->blend = NULL;
1164 #endif
1165   }
1166 
1167 
1168   FT_LOCAL_DEF( FT_Error )
cff_driver_init(FT_Module module)1169   cff_driver_init( FT_Module  module )        /* CFF_Driver */
1170   {
1171     PS_Driver  driver = (PS_Driver)module;
1172 
1173     FT_UInt32  seed;
1174 
1175 
1176     /* set default property values, cf. `ftcffdrv.h' */
1177 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
1178     driver->hinting_engine = FT_HINTING_FREETYPE;
1179 #else
1180     driver->hinting_engine = FT_HINTING_ADOBE;
1181 #endif
1182 
1183     driver->no_stem_darkening = TRUE;
1184 
1185     driver->darken_params[0] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1;
1186     driver->darken_params[1] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1;
1187     driver->darken_params[2] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2;
1188     driver->darken_params[3] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2;
1189     driver->darken_params[4] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3;
1190     driver->darken_params[5] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3;
1191     driver->darken_params[6] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4;
1192     driver->darken_params[7] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4;
1193 
1194     /* compute random seed from some memory addresses */
1195     seed = (FT_UInt32)( (FT_Offset)(char*)&seed          ^
1196                         (FT_Offset)(char*)&module        ^
1197                         (FT_Offset)(char*)module->memory );
1198     seed = seed ^ ( seed >> 10 ) ^ ( seed >> 20 );
1199 
1200     driver->random_seed = (FT_Int32)seed;
1201     if ( driver->random_seed < 0 )
1202       driver->random_seed = -driver->random_seed;
1203     else if ( driver->random_seed == 0 )
1204       driver->random_seed = 123456789;
1205 
1206     return FT_Err_Ok;
1207   }
1208 
1209 
1210   FT_LOCAL_DEF( void )
cff_driver_done(FT_Module module)1211   cff_driver_done( FT_Module  module )        /* CFF_Driver */
1212   {
1213     FT_UNUSED( module );
1214   }
1215 
1216 
1217 /* END */
1218