(root)/
freetype-2.13.2/
src/
cff/
cffobjs.c
       1  /****************************************************************************
       2   *
       3   * cffobjs.c
       4   *
       5   *   OpenType objects manager (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  
      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
      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( font->library, "pshinter" );
      73  
      74      return ( module && pshinter && pshinter->get_globals_funcs )
      75             ? pshinter->get_globals_funcs( module )
      76             : 0;
      77    }
      78  
      79  
      80    FT_LOCAL_DEF( void )
      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
     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 )
     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( memory, &priv, &internal->topfont );
     186      if ( error )
     187        goto Exit;
     188  
     189      for ( i = font->num_subfonts; i > 0; i-- )
     190      {
     191        CFF_SubFont  sub = font->subfonts[i - 1];
     192  
     193  
     194        cff_make_private_dict( sub, &priv );
     195        error = funcs->create( memory, &priv, &internal->subfonts[i - 1] );
     196        if ( error )
     197          goto Exit;
     198      }
     199  
     200      cffsize->internal->module_data = internal;
     201  
     202      size->strike_index = 0xFFFFFFFFUL;
     203  
     204    Exit:
     205      if ( error )
     206      {
     207        if ( internal )
     208        {
     209          for ( i = font->num_subfonts; i > 0; i-- )
     210            FT_FREE( internal->subfonts[i - 1] );
     211          FT_FREE( internal->topfont );
     212        }
     213  
     214        FT_FREE( internal );
     215      }
     216  
     217      return error;
     218    }
     219  
     220  
     221  #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
     222  
     223    FT_LOCAL_DEF( FT_Error )
     224    cff_size_select( FT_Size   size,
     225                     FT_ULong  strike_index )
     226    {
     227      CFF_Size           cffsize = (CFF_Size)size;
     228      PSH_Globals_Funcs  funcs;
     229  
     230  
     231      cffsize->strike_index = strike_index;
     232  
     233      FT_Select_Metrics( size->face, strike_index );
     234  
     235      funcs = cff_size_get_globals_funcs( cffsize );
     236  
     237      if ( funcs )
     238      {
     239        CFF_Face      face     = (CFF_Face)size->face;
     240        CFF_Font      font     = (CFF_Font)face->extra.data;
     241        CFF_Internal  internal = (CFF_Internal)size->internal->module_data;
     242  
     243        FT_Long  top_upm  = (FT_Long)font->top_font.font_dict.units_per_em;
     244        FT_UInt  i;
     245  
     246  
     247        funcs->set_scale( internal->topfont,
     248                          size->metrics.x_scale, size->metrics.y_scale,
     249                          0, 0 );
     250  
     251        for ( i = font->num_subfonts; i > 0; i-- )
     252        {
     253          CFF_SubFont  sub     = font->subfonts[i - 1];
     254          FT_Long      sub_upm = (FT_Long)sub->font_dict.units_per_em;
     255          FT_Pos       x_scale, y_scale;
     256  
     257  
     258          if ( top_upm != sub_upm )
     259          {
     260            x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm );
     261            y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm );
     262          }
     263          else
     264          {
     265            x_scale = size->metrics.x_scale;
     266            y_scale = size->metrics.y_scale;
     267          }
     268  
     269          funcs->set_scale( internal->subfonts[i - 1],
     270                            x_scale, y_scale, 0, 0 );
     271        }
     272      }
     273  
     274      return FT_Err_Ok;
     275    }
     276  
     277  #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
     278  
     279  
     280    FT_LOCAL_DEF( FT_Error )
     281    cff_size_request( FT_Size          size,
     282                      FT_Size_Request  req )
     283    {
     284      FT_Error  error;
     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      error = FT_Request_Metrics( size->face, req );
     308      if ( error )
     309        goto Exit;
     310  
     311      funcs = cff_size_get_globals_funcs( cffsize );
     312  
     313      if ( funcs )
     314      {
     315        CFF_Face      cffface  = (CFF_Face)size->face;
     316        CFF_Font      font     = (CFF_Font)cffface->extra.data;
     317        CFF_Internal  internal = (CFF_Internal)size->internal->module_data;
     318  
     319        FT_Long  top_upm  = (FT_Long)font->top_font.font_dict.units_per_em;
     320        FT_UInt  i;
     321  
     322  
     323        funcs->set_scale( internal->topfont,
     324                          size->metrics.x_scale, size->metrics.y_scale,
     325                          0, 0 );
     326  
     327        for ( i = font->num_subfonts; i > 0; i-- )
     328        {
     329          CFF_SubFont  sub     = font->subfonts[i - 1];
     330          FT_Long      sub_upm = (FT_Long)sub->font_dict.units_per_em;
     331          FT_Pos       x_scale, y_scale;
     332  
     333  
     334          if ( top_upm != sub_upm )
     335          {
     336            x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm );
     337            y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm );
     338          }
     339          else
     340          {
     341            x_scale = size->metrics.x_scale;
     342            y_scale = size->metrics.y_scale;
     343          }
     344  
     345          funcs->set_scale( internal->subfonts[i - 1],
     346                            x_scale, y_scale, 0, 0 );
     347        }
     348      }
     349  
     350    Exit:
     351      return error;
     352    }
     353  
     354  
     355    /**************************************************************************
     356     *
     357     *                           SLOT  FUNCTIONS
     358     *
     359     */
     360  
     361    FT_LOCAL_DEF( void )
     362    cff_slot_done( FT_GlyphSlot  slot )
     363    {
     364      if ( slot->internal )
     365        slot->internal->glyph_hints = NULL;
     366    }
     367  
     368  
     369    FT_LOCAL_DEF( FT_Error )
     370    cff_slot_init( FT_GlyphSlot  slot )
     371    {
     372      CFF_Face          face     = (CFF_Face)slot->face;
     373      CFF_Font          font     = (CFF_Font)face->extra.data;
     374      PSHinter_Service  pshinter = font->pshinter;
     375  
     376  
     377      if ( pshinter )
     378      {
     379        FT_Module  module;
     380  
     381  
     382        module = FT_Get_Module( slot->library, "pshinter" );
     383        if ( module )
     384        {
     385          T2_Hints_Funcs  funcs;
     386  
     387  
     388          funcs = pshinter->get_t2_funcs( module );
     389          slot->internal->glyph_hints = (void*)funcs;
     390        }
     391      }
     392  
     393      return FT_Err_Ok;
     394    }
     395  
     396  
     397    /**************************************************************************
     398     *
     399     *                          FACE  FUNCTIONS
     400     *
     401     */
     402  
     403    static FT_String*
     404    cff_strcpy( FT_Memory         memory,
     405                const FT_String*  source )
     406    {
     407      FT_Error    error;
     408      FT_String*  result;
     409  
     410  
     411      FT_MEM_STRDUP( result, source );
     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
     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
     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 )
     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          FT_ERROR(( "              "
     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_UInt  instance_index = (FT_UInt)face_index >> 16;
     723  
     724  
     725          if ( FT_HAS_MULTIPLE_MASTERS( cffface ) &&
     726               instance_index > 0                 )
     727          {
     728            error = FT_Set_Named_Instance( cffface, instance_index );
     729            if ( error )
     730              goto Exit;
     731          }
     732        }
     733  #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
     734  
     735        if ( !dict->has_font_matrix )
     736          dict->units_per_em = pure_cff ? 1000 : face->root.units_per_EM;
     737  
     738        /* Normalize the font matrix so that `matrix->yy' is 1; if  */
     739        /* it is zero, we use `matrix->yx' instead.  The scaling is */
     740        /* done with `units_per_em' then (at this point, it already */
     741        /* contains the scaling factor, but without normalization   */
     742        /* of the matrix).                                          */
     743        /*                                                          */
     744        /* Note that the offsets must be expressed in integer font  */
     745        /* units.                                                   */
     746  
     747        {
     748          FT_Matrix*  matrix = &dict->font_matrix;
     749          FT_Vector*  offset = &dict->font_offset;
     750          FT_ULong*   upm    = &dict->units_per_em;
     751          FT_Fixed    temp;
     752  
     753  
     754          temp = matrix->yy ? FT_ABS( matrix->yy )
     755                            : FT_ABS( matrix->yx );
     756  
     757          if ( temp != 0x10000L )
     758          {
     759            *upm = (FT_ULong)FT_DivFix( (FT_Long)*upm, temp );
     760  
     761            matrix->xx = FT_DivFix( matrix->xx, temp );
     762            matrix->yx = FT_DivFix( matrix->yx, temp );
     763            matrix->xy = FT_DivFix( matrix->xy, temp );
     764            matrix->yy = FT_DivFix( matrix->yy, temp );
     765            offset->x  = FT_DivFix( offset->x,  temp );
     766            offset->y  = FT_DivFix( offset->y,  temp );
     767          }
     768  
     769          offset->x >>= 16;
     770          offset->y >>= 16;
     771        }
     772  
     773        for ( i = cff->num_subfonts; i > 0; i-- )
     774        {
     775          CFF_FontRecDict  sub = &cff->subfonts[i - 1]->font_dict;
     776          CFF_FontRecDict  top = &cff->top_font.font_dict;
     777  
     778          FT_Matrix*  matrix;
     779          FT_Vector*  offset;
     780          FT_ULong*   upm;
     781          FT_Fixed    temp;
     782  
     783  
     784          if ( sub->has_font_matrix )
     785          {
     786            FT_Long  scaling;
     787  
     788  
     789            /* if we have a top-level matrix, */
     790            /* concatenate the subfont matrix */
     791  
     792            if ( top->has_font_matrix )
     793            {
     794              if ( top->units_per_em > 1 && sub->units_per_em > 1 )
     795                scaling = (FT_Long)FT_MIN( top->units_per_em,
     796                                           sub->units_per_em );
     797              else
     798                scaling = 1;
     799  
     800              FT_Matrix_Multiply_Scaled( &top->font_matrix,
     801                                         &sub->font_matrix,
     802                                         scaling );
     803              FT_Vector_Transform_Scaled( &sub->font_offset,
     804                                          &top->font_matrix,
     805                                          scaling );
     806  
     807              sub->units_per_em = (FT_ULong)
     808                                    FT_MulDiv( (FT_Long)sub->units_per_em,
     809                                               (FT_Long)top->units_per_em,
     810                                               scaling );
     811            }
     812          }
     813          else
     814          {
     815            sub->font_matrix = top->font_matrix;
     816            sub->font_offset = top->font_offset;
     817  
     818            sub->units_per_em = top->units_per_em;
     819          }
     820  
     821          matrix = &sub->font_matrix;
     822          offset = &sub->font_offset;
     823          upm    = &sub->units_per_em;
     824  
     825          temp = matrix->yy ? FT_ABS( matrix->yy )
     826                            : FT_ABS( matrix->yx );
     827  
     828  
     829          if ( temp != 0x10000L )
     830          {
     831            *upm = (FT_ULong)FT_DivFix( (FT_Long)*upm, temp );
     832  
     833            matrix->xx = FT_DivFix( matrix->xx, temp );
     834            matrix->yx = FT_DivFix( matrix->yx, temp );
     835            matrix->xy = FT_DivFix( matrix->xy, temp );
     836            matrix->yy = FT_DivFix( matrix->yy, temp );
     837            offset->x  = FT_DivFix( offset->x,  temp );
     838            offset->y  = FT_DivFix( offset->y,  temp );
     839          }
     840  
     841          offset->x >>= 16;
     842          offset->y >>= 16;
     843        }
     844  
     845        if ( pure_cff )
     846        {
     847          char*  style_name = NULL;
     848  
     849  
     850          /* set up num_faces */
     851          cffface->num_faces = (FT_Long)cff->num_faces;
     852  
     853          /* compute number of glyphs */
     854          if ( dict->cid_registry != 0xFFFFU )
     855            cffface->num_glyphs = (FT_Long)( cff->charset.max_cid + 1 );
     856          else
     857            cffface->num_glyphs = (FT_Long)cff->charstrings_index.count;
     858  
     859          /* set global bbox, as well as EM size */
     860          cffface->bbox.xMin =   dict->font_bbox.xMin            >> 16;
     861          cffface->bbox.yMin =   dict->font_bbox.yMin            >> 16;
     862          /* no `U' suffix here to 0xFFFF! */
     863          cffface->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFF ) >> 16;
     864          cffface->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFF ) >> 16;
     865  
     866          cffface->units_per_EM = (FT_UShort)( dict->units_per_em );
     867  
     868          cffface->ascender  = (FT_Short)( cffface->bbox.yMax );
     869          cffface->descender = (FT_Short)( cffface->bbox.yMin );
     870  
     871          cffface->height = (FT_Short)( ( cffface->units_per_EM * 12 ) / 10 );
     872          if ( cffface->height < cffface->ascender - cffface->descender )
     873            cffface->height = (FT_Short)( cffface->ascender -
     874                                          cffface->descender );
     875  
     876          cffface->underline_position  =
     877            (FT_Short)( dict->underline_position >> 16 );
     878          cffface->underline_thickness =
     879            (FT_Short)( dict->underline_thickness >> 16 );
     880  
     881          /* retrieve font family & style name */
     882          if ( dict->family_name )
     883          {
     884            char*  family_name;
     885  
     886  
     887            family_name = cff_index_get_sid_string( cff, dict->family_name );
     888            if ( family_name )
     889              cffface->family_name = cff_strcpy( memory, family_name );
     890          }
     891  
     892          if ( !cffface->family_name )
     893          {
     894            cffface->family_name = cff_index_get_name(
     895                                     cff,
     896                                     (FT_UInt)( face_index & 0xFFFF ) );
     897            if ( cffface->family_name )
     898              remove_subset_prefix( cffface->family_name );
     899          }
     900  
     901          if ( cffface->family_name )
     902          {
     903            char*  full   = cff_index_get_sid_string( cff,
     904                                                      dict->full_name );
     905            char*  fullp  = full;
     906            char*  family = cffface->family_name;
     907  
     908  
     909            /* We try to extract the style name from the full name.   */
     910            /* We need to ignore spaces and dashes during the search. */
     911            if ( full && family )
     912            {
     913              while ( *fullp )
     914              {
     915                /* skip common characters at the start of both strings */
     916                if ( *fullp == *family )
     917                {
     918                  family++;
     919                  fullp++;
     920                  continue;
     921                }
     922  
     923                /* ignore spaces and dashes in full name during comparison */
     924                if ( *fullp == ' ' || *fullp == '-' )
     925                {
     926                  fullp++;
     927                  continue;
     928                }
     929  
     930                /* ignore spaces and dashes in family name during comparison */
     931                if ( *family == ' ' || *family == '-' )
     932                {
     933                  family++;
     934                  continue;
     935                }
     936  
     937                if ( !*family && *fullp )
     938                {
     939                  /* The full name begins with the same characters as the  */
     940                  /* family name, with spaces and dashes removed.  In this */
     941                  /* case, the remaining string in `fullp' will be used as */
     942                  /* the style name.                                       */
     943                  style_name = cff_strcpy( memory, fullp );
     944  
     945                  /* remove the style part from the family name (if present) */
     946                  if ( style_name )
     947                    remove_style( cffface->family_name, style_name );
     948                }
     949                break;
     950              }
     951            }
     952          }
     953          else
     954          {
     955            char  *cid_font_name =
     956                     cff_index_get_sid_string( cff,
     957                                               dict->cid_font_name );
     958  
     959  
     960            /* do we have a `/FontName' for a CID-keyed font? */
     961            if ( cid_font_name )
     962              cffface->family_name = cff_strcpy( memory, cid_font_name );
     963          }
     964  
     965          if ( style_name )
     966            cffface->style_name = style_name;
     967          else
     968            /* assume "Regular" style if we don't know better */
     969            cffface->style_name = cff_strcpy( memory, "Regular" );
     970  
     971          /********************************************************************
     972           *
     973           * Compute face flags.
     974           */
     975          flags = FT_FACE_FLAG_SCALABLE   | /* scalable outlines */
     976                  FT_FACE_FLAG_HORIZONTAL | /* horizontal data   */
     977                  FT_FACE_FLAG_HINTER;      /* has native hinter */
     978  
     979          if ( sfnt_format )
     980            flags |= FT_FACE_FLAG_SFNT;
     981  
     982          /* fixed width font? */
     983          if ( dict->is_fixed_pitch )
     984            flags |= FT_FACE_FLAG_FIXED_WIDTH;
     985  
     986    /* XXX: WE DO NOT SUPPORT KERNING METRICS IN THE GPOS TABLE FOR NOW */
     987  #if 0
     988          /* kerning available? */
     989          if ( face->kern_pairs )
     990            flags |= FT_FACE_FLAG_KERNING;
     991  #endif
     992  
     993          cffface->face_flags |= flags;
     994  
     995          /********************************************************************
     996           *
     997           * Compute style flags.
     998           */
     999          flags = 0;
    1000  
    1001          if ( dict->italic_angle )
    1002            flags |= FT_STYLE_FLAG_ITALIC;
    1003  
    1004          {
    1005            char  *weight = cff_index_get_sid_string( cff,
    1006                                                      dict->weight );
    1007  
    1008  
    1009            if ( weight )
    1010              if ( !ft_strcmp( weight, "Bold"  ) ||
    1011                   !ft_strcmp( weight, "Black" ) )
    1012                flags |= FT_STYLE_FLAG_BOLD;
    1013          }
    1014  
    1015          /* double check */
    1016          if ( !(flags & FT_STYLE_FLAG_BOLD) && cffface->style_name )
    1017            if ( !ft_strncmp( cffface->style_name, "Bold", 4 )  ||
    1018                 !ft_strncmp( cffface->style_name, "Black", 5 ) )
    1019              flags |= FT_STYLE_FLAG_BOLD;
    1020  
    1021          cffface->style_flags = flags;
    1022        }
    1023  
    1024        /* CID-keyed CFF or CFF2 fonts don't have glyph names -- the SFNT */
    1025        /* loader has unset this flag because of the 3.0 `post' table.    */
    1026        if ( dict->cid_registry == 0xFFFFU && !cff2 )
    1027          cffface->face_flags |= FT_FACE_FLAG_GLYPH_NAMES;
    1028  
    1029        if ( dict->cid_registry != 0xFFFFU && pure_cff )
    1030          cffface->face_flags |= FT_FACE_FLAG_CID_KEYED;
    1031  
    1032        /********************************************************************
    1033         *
    1034         * Compute char maps.
    1035         */
    1036  
    1037        /* Try to synthesize a Unicode charmap if there is none available */
    1038        /* already.  If an OpenType font contains a Unicode "cmap", we    */
    1039        /* will use it, whatever be in the CFF part of the file.          */
    1040        {
    1041          FT_CharMapRec  cmaprec;
    1042          FT_CharMap     cmap;
    1043          FT_Int         nn;
    1044          CFF_Encoding   encoding = &cff->encoding;
    1045  
    1046  
    1047          for ( nn = 0; nn < cffface->num_charmaps; nn++ )
    1048          {
    1049            cmap = cffface->charmaps[nn];
    1050  
    1051            /* Windows Unicode? */
    1052            if ( cmap->platform_id == TT_PLATFORM_MICROSOFT &&
    1053                 cmap->encoding_id == TT_MS_ID_UNICODE_CS   )
    1054              goto Skip_Unicode;
    1055  
    1056            /* Apple Unicode platform id? */
    1057            if ( cmap->platform_id == TT_PLATFORM_APPLE_UNICODE )
    1058              goto Skip_Unicode; /* Apple Unicode */
    1059          }
    1060  
    1061          /* since CID-keyed fonts don't contain glyph names, we can't */
    1062          /* construct a cmap                                          */
    1063          if ( pure_cff && cff->top_font.font_dict.cid_registry != 0xFFFFU )
    1064            goto Exit;
    1065  
    1066          /* we didn't find a Unicode charmap -- synthesize one */
    1067          cmaprec.face        = cffface;
    1068          cmaprec.platform_id = TT_PLATFORM_MICROSOFT;
    1069          cmaprec.encoding_id = TT_MS_ID_UNICODE_CS;
    1070          cmaprec.encoding    = FT_ENCODING_UNICODE;
    1071  
    1072          nn = cffface->num_charmaps;
    1073  
    1074          error = FT_CMap_New( &cff_cmap_unicode_class_rec, NULL,
    1075                               &cmaprec, NULL );
    1076          if ( error                                      &&
    1077               FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) &&
    1078               FT_ERR_NEQ( error, Unimplemented_Feature ) )
    1079            goto Exit;
    1080          error = FT_Err_Ok;
    1081  
    1082          /* if no Unicode charmap was previously selected, select this one */
    1083          if ( !cffface->charmap && nn != cffface->num_charmaps )
    1084            cffface->charmap = cffface->charmaps[nn];
    1085  
    1086        Skip_Unicode:
    1087          if ( encoding->count > 0 )
    1088          {
    1089            FT_CMap_Class  clazz;
    1090  
    1091  
    1092            cmaprec.face        = cffface;
    1093            cmaprec.platform_id = TT_PLATFORM_ADOBE;  /* Adobe platform id */
    1094  
    1095            if ( encoding->offset == 0 )
    1096            {
    1097              cmaprec.encoding_id = TT_ADOBE_ID_STANDARD;
    1098              cmaprec.encoding    = FT_ENCODING_ADOBE_STANDARD;
    1099              clazz               = &cff_cmap_encoding_class_rec;
    1100            }
    1101            else if ( encoding->offset == 1 )
    1102            {
    1103              cmaprec.encoding_id = TT_ADOBE_ID_EXPERT;
    1104              cmaprec.encoding    = FT_ENCODING_ADOBE_EXPERT;
    1105              clazz               = &cff_cmap_encoding_class_rec;
    1106            }
    1107            else
    1108            {
    1109              cmaprec.encoding_id = TT_ADOBE_ID_CUSTOM;
    1110              cmaprec.encoding    = FT_ENCODING_ADOBE_CUSTOM;
    1111              clazz               = &cff_cmap_encoding_class_rec;
    1112            }
    1113  
    1114            error = FT_CMap_New( clazz, NULL, &cmaprec, NULL );
    1115          }
    1116        }
    1117      }
    1118  
    1119    Exit:
    1120      return error;
    1121    }
    1122  
    1123  
    1124    FT_LOCAL_DEF( void )
    1125    cff_face_done( FT_Face  cffface )         /* CFF_Face */
    1126    {
    1127      CFF_Face      face = (CFF_Face)cffface;
    1128      FT_Memory     memory;
    1129      SFNT_Service  sfnt;
    1130  
    1131  
    1132      if ( !face )
    1133        return;
    1134  
    1135      memory = cffface->memory;
    1136      sfnt   = (SFNT_Service)face->sfnt;
    1137  
    1138      if ( sfnt )
    1139        sfnt->done_face( face );
    1140  
    1141      {
    1142        CFF_Font  cff = (CFF_Font)face->extra.data;
    1143  
    1144  
    1145        if ( cff )
    1146        {
    1147          cff_font_done( cff );
    1148          FT_FREE( face->extra.data );
    1149        }
    1150      }
    1151  
    1152  #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    1153      cff_done_blend( cffface );
    1154      face->blend = NULL;
    1155  #endif
    1156    }
    1157  
    1158  
    1159    FT_LOCAL_DEF( FT_Error )
    1160    cff_driver_init( FT_Module  module )        /* CFF_Driver */
    1161    {
    1162      PS_Driver  driver = (PS_Driver)module;
    1163  
    1164      FT_UInt32  seed;
    1165  
    1166  
    1167      /* set default property values, cf. `ftcffdrv.h' */
    1168      driver->hinting_engine = FT_HINTING_ADOBE;
    1169  
    1170      driver->no_stem_darkening = TRUE;
    1171  
    1172      driver->darken_params[0] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1;
    1173      driver->darken_params[1] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1;
    1174      driver->darken_params[2] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2;
    1175      driver->darken_params[3] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2;
    1176      driver->darken_params[4] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3;
    1177      driver->darken_params[5] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3;
    1178      driver->darken_params[6] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4;
    1179      driver->darken_params[7] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4;
    1180  
    1181      /* compute random seed from some memory addresses */
    1182      seed = (FT_UInt32)( (FT_Offset)(char*)&seed          ^
    1183                          (FT_Offset)(char*)&module        ^
    1184                          (FT_Offset)(char*)module->memory );
    1185      seed = seed ^ ( seed >> 10 ) ^ ( seed >> 20 );
    1186  
    1187      driver->random_seed = (FT_Int32)seed;
    1188      if ( driver->random_seed < 0 )
    1189        driver->random_seed = -driver->random_seed;
    1190      else if ( driver->random_seed == 0 )
    1191        driver->random_seed = 123456789;
    1192  
    1193      return FT_Err_Ok;
    1194    }
    1195  
    1196  
    1197    FT_LOCAL_DEF( void )
    1198    cff_driver_done( FT_Module  module )        /* CFF_Driver */
    1199    {
    1200      FT_UNUSED( module );
    1201    }
    1202  
    1203  
    1204  /* END */