src/java.desktop/share/native/libfreetype/src/type1/t1load.c
changeset 54876 da3834261f0c
parent 50479 70e706c85f1d
equal deleted inserted replaced
54875:bcfedddcf4ce 54876:da3834261f0c
     1 /***************************************************************************/
     1 /****************************************************************************
     2 /*                                                                         */
     2  *
     3 /*  t1load.c                                                               */
     3  * t1load.c
     4 /*                                                                         */
     4  *
     5 /*    Type 1 font loader (body).                                           */
     5  *   Type 1 font loader (body).
     6 /*                                                                         */
     6  *
     7 /*  Copyright 1996-2018 by                                                 */
     7  * Copyright (C) 1996-2019 by
     8 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
     8  * David Turner, Robert Wilhelm, and Werner Lemberg.
     9 /*                                                                         */
     9  *
    10 /*  This file is part of the FreeType project, and may only be used,       */
    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      */
    11  * modified, and distributed under the terms of the FreeType project
    12 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
    12  * license, LICENSE.TXT.  By continuing to use, modify, or distribute
    13 /*  this file you indicate that you have read the license and              */
    13  * this file you indicate that you have read the license and
    14 /*  understand and accept it fully.                                        */
    14  * understand and accept it fully.
    15 /*                                                                         */
    15  *
    16 /***************************************************************************/
    16  */
    17 
    17 
    18 
    18 
    19   /*************************************************************************/
    19   /**************************************************************************
    20   /*                                                                       */
    20    *
    21   /* This is the new and improved Type 1 data loader for FreeType 2.  The  */
    21    * This is the new and improved Type 1 data loader for FreeType 2.  The
    22   /* old loader has several problems: it is slow, complex, difficult to    */
    22    * old loader has several problems: it is slow, complex, difficult to
    23   /* maintain, and contains incredible hacks to make it accept some        */
    23    * maintain, and contains incredible hacks to make it accept some
    24   /* ill-formed Type 1 fonts without hiccup-ing.  Moreover, about 5% of    */
    24    * ill-formed Type 1 fonts without hiccup-ing.  Moreover, about 5% of
    25   /* the Type 1 fonts on my machine still aren't loaded correctly by it.   */
    25    * the Type 1 fonts on my machine still aren't loaded correctly by it.
    26   /*                                                                       */
    26    *
    27   /* This version is much simpler, much faster and also easier to read and */
    27    * This version is much simpler, much faster and also easier to read and
    28   /* maintain by a great order of magnitude.  The idea behind it is to     */
    28    * maintain by a great order of magnitude.  The idea behind it is to
    29   /* _not_ try to read the Type 1 token stream with a state machine (i.e.  */
    29    * _not_ try to read the Type 1 token stream with a state machine (i.e.
    30   /* a Postscript-like interpreter) but rather to perform simple pattern   */
    30    * a Postscript-like interpreter) but rather to perform simple pattern
    31   /* matching.                                                             */
    31    * matching.
    32   /*                                                                       */
    32    *
    33   /* Indeed, nearly all data definitions follow a simple pattern like      */
    33    * Indeed, nearly all data definitions follow a simple pattern like
    34   /*                                                                       */
    34    *
    35   /*  ... /Field <data> ...                                                */
    35    * ... /Field <data> ...
    36   /*                                                                       */
    36    *
    37   /* where <data> can be a number, a boolean, a string, or an array of     */
    37    * where <data> can be a number, a boolean, a string, or an array of
    38   /* numbers.  There are a few exceptions, namely the encoding, font name, */
    38    * numbers.  There are a few exceptions, namely the encoding, font name,
    39   /* charstrings, and subrs; they are handled with a special pattern       */
    39    * charstrings, and subrs; they are handled with a special pattern
    40   /* matching routine.                                                     */
    40    * matching routine.
    41   /*                                                                       */
    41    *
    42   /* All other common cases are handled very simply.  The matching rules   */
    42    * All other common cases are handled very simply.  The matching rules
    43   /* are defined in the file `t1tokens.h' through the use of several       */
    43    * are defined in the file `t1tokens.h' through the use of several
    44   /* macros calls PARSE_XXX.  This file is included twice here; the first  */
    44    * macros calls PARSE_XXX.  This file is included twice here; the first
    45   /* time to generate parsing callback functions, the second time to       */
    45    * time to generate parsing callback functions, the second time to
    46   /* generate a table of keywords (with pointers to the associated         */
    46    * generate a table of keywords (with pointers to the associated
    47   /* callback functions).                                                  */
    47    * callback functions).
    48   /*                                                                       */
    48    *
    49   /* The function `parse_dict' simply scans *linearly* a given dictionary  */
    49    * The function `parse_dict' simply scans *linearly* a given dictionary
    50   /* (either the top-level or private one) and calls the appropriate       */
    50    * (either the top-level or private one) and calls the appropriate
    51   /* callback when it encounters an immediate keyword.                     */
    51    * callback when it encounters an immediate keyword.
    52   /*                                                                       */
    52    *
    53   /* This is by far the fastest way one can find to parse and read all     */
    53    * This is by far the fastest way one can find to parse and read all
    54   /* data.                                                                 */
    54    * data.
    55   /*                                                                       */
    55    *
    56   /* This led to tremendous code size reduction.  Note that later, the     */
    56    * This led to tremendous code size reduction.  Note that later, the
    57   /* glyph loader will also be _greatly_ simplified, and the automatic     */
    57    * glyph loader will also be _greatly_ simplified, and the automatic
    58   /* hinter will replace the clumsy `t1hinter'.                            */
    58    * hinter will replace the clumsy `t1hinter'.
    59   /*                                                                       */
    59    *
    60   /*************************************************************************/
    60    */
    61 
    61 
    62 
    62 
    63 #include <ft2build.h>
    63 #include <ft2build.h>
    64 #include FT_INTERNAL_DEBUG_H
    64 #include FT_INTERNAL_DEBUG_H
    65 #include FT_CONFIG_CONFIG_H
    65 #include FT_CONFIG_CONFIG_H
    71 #include "t1load.h"
    71 #include "t1load.h"
    72 #include "t1errors.h"
    72 #include "t1errors.h"
    73 
    73 
    74 
    74 
    75 #ifdef FT_CONFIG_OPTION_INCREMENTAL
    75 #ifdef FT_CONFIG_OPTION_INCREMENTAL
    76 #define IS_INCREMENTAL  (FT_Bool)( face->root.internal->incremental_interface != 0 )
    76 #define IS_INCREMENTAL  FT_BOOL( face->root.internal->incremental_interface )
    77 #else
    77 #else
    78 #define IS_INCREMENTAL  0
    78 #define IS_INCREMENTAL  0
    79 #endif
    79 #endif
    80 
    80 
    81 
    81 
    82   /*************************************************************************/
    82   /**************************************************************************
    83   /*                                                                       */
    83    *
    84   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
    84    * The macro FT_COMPONENT is used in trace mode.  It is an implicit
    85   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
    85    * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
    86   /* messages during execution.                                            */
    86    * messages during execution.
    87   /*                                                                       */
    87    */
    88 #undef  FT_COMPONENT
    88 #undef  FT_COMPONENT
    89 #define FT_COMPONENT  trace_t1load
    89 #define FT_COMPONENT  t1load
    90 
    90 
    91 
    91 
    92 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
    92 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
    93 
    93 
    94 
    94 
   220 
   220 
   221     return error;
   221     return error;
   222   }
   222   }
   223 
   223 
   224 
   224 
   225   /*************************************************************************/
   225   /**************************************************************************
   226   /*                                                                       */
   226    *
   227   /* Given a normalized (blend) coordinate, figure out the design          */
   227    * Given a normalized (blend) coordinate, figure out the design
   228   /* coordinate appropriate for that value.                                */
   228    * coordinate appropriate for that value.
   229   /*                                                                       */
   229    */
   230   static FT_Fixed
   230   static FT_Fixed
   231   mm_axis_unmap( PS_DesignMap  axismap,
   231   mm_axis_unmap( PS_DesignMap  axismap,
   232                  FT_Fixed      ncv )
   232                  FT_Fixed      ncv )
   233   {
   233   {
   234     int  j;
   234     int  j;
   249 
   249 
   250     return INT_TO_FIXED( axismap->design_points[axismap->num_points - 1] );
   250     return INT_TO_FIXED( axismap->design_points[axismap->num_points - 1] );
   251   }
   251   }
   252 
   252 
   253 
   253 
   254   /*************************************************************************/
   254   /**************************************************************************
   255   /*                                                                       */
   255    *
   256   /* Given a vector of weights, one for each design, figure out the        */
   256    * Given a vector of weights, one for each design, figure out the
   257   /* normalized axis coordinates which gave rise to those weights.         */
   257    * normalized axis coordinates which gave rise to those weights.
   258   /*                                                                       */
   258    */
   259   static void
   259   static void
   260   mm_weights_unmap( FT_Fixed*  weights,
   260   mm_weights_unmap( FT_Fixed*  weights,
   261                     FT_Fixed*  axiscoords,
   261                     FT_Fixed*  axiscoords,
   262                     FT_UInt    axis_count )
   262                     FT_UInt    axis_count )
   263   {
   263   {
   291                         weights[11] + weights[10] + weights[9] + weights[8];
   291                         weights[11] + weights[10] + weights[9] + weights[8];
   292     }
   292     }
   293   }
   293   }
   294 
   294 
   295 
   295 
   296   /*************************************************************************/
   296   /**************************************************************************
   297   /*                                                                       */
   297    *
   298   /* Just a wrapper around T1_Get_Multi_Master to support the different    */
   298    * Just a wrapper around T1_Get_Multi_Master to support the different
   299   /*  arguments needed by the GX var distortable fonts.                    */
   299    * arguments needed by the GX var distortable fonts.
   300   /*                                                                       */
   300    */
   301   FT_LOCAL_DEF( FT_Error )
   301   FT_LOCAL_DEF( FT_Error )
   302   T1_Get_MM_Var( T1_Face      face,
   302   T1_Get_MM_Var( T1_Face      face,
   303                  FT_MM_Var*  *master )
   303                  FT_MM_Var*  *master )
   304   {
   304   {
   305     FT_Memory        memory = face->root.memory;
   305     FT_Memory        memory = face->root.memory;
   346         mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'd', 't', 'h' );
   346         mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'd', 't', 'h' );
   347       else if ( ft_strcmp( mmvar->axis[i].name, "OpticalSize" ) == 0 )
   347       else if ( ft_strcmp( mmvar->axis[i].name, "OpticalSize" ) == 0 )
   348         mmvar->axis[i].tag = FT_MAKE_TAG( 'o', 'p', 's', 'z' );
   348         mmvar->axis[i].tag = FT_MAKE_TAG( 'o', 'p', 's', 'z' );
   349     }
   349     }
   350 
   350 
   351     if ( blend->num_designs == ( 1U << blend->num_axis ) )
   351     mm_weights_unmap( blend->default_weight_vector,
   352     {
   352                       axiscoords,
   353       mm_weights_unmap( blend->default_weight_vector,
   353                       blend->num_axis );
   354                         axiscoords,
   354 
   355                         blend->num_axis );
   355     for ( i = 0; i < mmaster.num_axis; i++ )
   356 
   356       mmvar->axis[i].def = mm_axis_unmap( &blend->design_map[i],
   357       for ( i = 0; i < mmaster.num_axis; i++ )
   357                                           axiscoords[i] );
   358         mmvar->axis[i].def = mm_axis_unmap( &blend->design_map[i],
       
   359                                             axiscoords[i] );
       
   360     }
       
   361 
   358 
   362     *master = mmvar;
   359     *master = mmvar;
   363 
   360 
   364   Exit:
   361   Exit:
   365     return error;
   362     return error;
   385 
   382 
   386     /* recompute the weight vector from the blend coordinates */
   383     /* recompute the weight vector from the blend coordinates */
   387     for ( n = 0; n < blend->num_designs; n++ )
   384     for ( n = 0; n < blend->num_designs; n++ )
   388     {
   385     {
   389       FT_Fixed  result = 0x10000L;  /* 1.0 fixed */
   386       FT_Fixed  result = 0x10000L;  /* 1.0 fixed */
       
   387       FT_Fixed  factor;
   390 
   388 
   391 
   389 
   392       for ( m = 0; m < blend->num_axis; m++ )
   390       for ( m = 0; m < blend->num_axis; m++ )
   393       {
   391       {
   394         FT_Fixed  factor;
       
   395 
       
   396 
       
   397         /* get current blend axis position;                  */
       
   398         /* use a default value if we don't have a coordinate */
   392         /* use a default value if we don't have a coordinate */
   399         factor = m < num_coords ? coords[m] : 0x8000;
   393         if ( m >= num_coords )
   400         if ( factor < 0 )
   394         {
   401           factor = 0;
   395           result >>= 1;
   402         if ( factor > 0x10000L )
   396           continue;
   403           factor = 0x10000L;
   397         }
   404 
   398 
       
   399         /* get current blend axis position */
       
   400         factor = coords[m];
   405         if ( ( n & ( 1 << m ) ) == 0 )
   401         if ( ( n & ( 1 << m ) ) == 0 )
   406           factor = 0x10000L - factor;
   402           factor = 0x10000L - factor;
       
   403 
       
   404         if ( factor <= 0 )
       
   405         {
       
   406           result = 0;
       
   407           break;
       
   408         }
       
   409         else if ( factor >= 0x10000L )
       
   410           continue;
   407 
   411 
   408         result = FT_MulFix( result, factor );
   412         result = FT_MulFix( result, factor );
   409       }
   413       }
   410 
   414 
   411       if ( blend->weight_vector[n] != result )
   415       if ( blend->weight_vector[n] != result )
   469 
   473 
   470     for ( i = 0; i < nc; i++ )
   474     for ( i = 0; i < nc; i++ )
   471       coords[i] = axiscoords[i];
   475       coords[i] = axiscoords[i];
   472     for ( ; i < num_coords; i++ )
   476     for ( ; i < num_coords; i++ )
   473       coords[i] = 0x8000;
   477       coords[i] = 0x8000;
       
   478 
       
   479     return FT_Err_Ok;
       
   480   }
       
   481 
       
   482 
       
   483   FT_LOCAL_DEF( FT_Error )
       
   484   T1_Set_MM_WeightVector( T1_Face    face,
       
   485                           FT_UInt    len,
       
   486                           FT_Fixed*  weightvector )
       
   487   {
       
   488     PS_Blend  blend = face->blend;
       
   489     FT_UInt   i, n;
       
   490 
       
   491 
       
   492     if ( !blend )
       
   493      return FT_THROW( Invalid_Argument );
       
   494 
       
   495     if ( !len && !weightvector )
       
   496     {
       
   497       for ( i = 0; i < blend->num_designs; i++ )
       
   498         blend->weight_vector[i] = blend->default_weight_vector[i];
       
   499     }
       
   500     else
       
   501     {
       
   502       if ( !weightvector )
       
   503         return FT_THROW( Invalid_Argument );
       
   504 
       
   505       n = len < blend->num_designs ? len : blend->num_designs;
       
   506 
       
   507       for ( i = 0; i < n; i++ )
       
   508         blend->weight_vector[i] = weightvector[i];
       
   509 
       
   510       for ( ; i < blend->num_designs; i++ )
       
   511         blend->weight_vector[i] = (FT_Fixed)0;
       
   512 
       
   513       if ( len )
       
   514         face->root.face_flags |= FT_FACE_FLAG_VARIATION;
       
   515       else
       
   516         face->root.face_flags &= ~FT_FACE_FLAG_VARIATION;
       
   517     }
       
   518 
       
   519     return FT_Err_Ok;
       
   520   }
       
   521 
       
   522 
       
   523   FT_LOCAL_DEF( FT_Error )
       
   524   T1_Get_MM_WeightVector( T1_Face    face,
       
   525                           FT_UInt*   len,
       
   526                           FT_Fixed*  weightvector )
       
   527   {
       
   528     PS_Blend  blend = face->blend;
       
   529     FT_UInt   i;
       
   530 
       
   531 
       
   532     if ( !blend )
       
   533       return FT_THROW( Invalid_Argument );
       
   534 
       
   535     if ( *len < blend->num_designs )
       
   536     {
       
   537       *len = blend->num_designs;
       
   538       return FT_THROW( Invalid_Argument );
       
   539     }
       
   540 
       
   541     for ( i = 0; i < blend->num_designs; i++ )
       
   542       weightvector[i] = blend->weight_vector[i];
       
   543     for ( ; i < *len; i++ )
       
   544       weightvector[i] = (FT_Fixed)0;
       
   545 
       
   546     *len = blend->num_designs;
   474 
   547 
   475     return FT_Err_Ok;
   548     return FT_Err_Ok;
   476   }
   549   }
   477 
   550 
   478 
   551 
   571 
   644 
   572     return T1_Set_MM_Blend( face, 0, NULL );
   645     return T1_Set_MM_Blend( face, 0, NULL );
   573   }
   646   }
   574 
   647 
   575 
   648 
   576   /*************************************************************************/
   649   /**************************************************************************
   577   /*                                                                       */
   650    *
   578   /* Just a wrapper around T1_Set_MM_Design to support the different       */
   651    * Just a wrapper around T1_Set_MM_Design to support the different
   579   /* arguments needed by the GX var distortable fonts.                     */
   652    * arguments needed by the GX var distortable fonts.
   580   /*                                                                       */
   653    */
   581   FT_LOCAL_DEF( FT_Error )
   654   FT_LOCAL_DEF( FT_Error )
   582   T1_Set_Var_Design( T1_Face    face,
   655   T1_Set_Var_Design( T1_Face    face,
   583                      FT_UInt    num_coords,
   656                      FT_UInt    num_coords,
   584                      FT_Fixed*  coords )
   657                      FT_Fixed*  coords )
   585   {
   658   {
   717     /* allocate blend if necessary */
   790     /* allocate blend if necessary */
   718     error = t1_allocate_blend( face, 0, (FT_UInt)num_axis );
   791     error = t1_allocate_blend( face, 0, (FT_UInt)num_axis );
   719     if ( error )
   792     if ( error )
   720       goto Exit;
   793       goto Exit;
   721 
   794 
       
   795     FT_TRACE4(( " [" ));
       
   796 
   722     blend  = face->blend;
   797     blend  = face->blend;
   723     memory = face->root.memory;
   798     memory = face->root.memory;
   724 
   799 
   725     /* each token is an immediate containing the name of the axis */
   800     /* each token is an immediate containing the name of the axis */
   726     for ( n = 0; n < num_axis; n++ )
   801     for ( n = 0; n < num_axis; n++ )
   739       {
   814       {
   740         error = FT_THROW( Invalid_File_Format );
   815         error = FT_THROW( Invalid_File_Format );
   741         goto Exit;
   816         goto Exit;
   742       }
   817       }
   743 
   818 
       
   819       FT_TRACE4(( " /%.*s", len, token->start ));
       
   820 
   744       name = (FT_Byte*)blend->axis_names[n];
   821       name = (FT_Byte*)blend->axis_names[n];
   745       if ( name )
   822       if ( name )
   746       {
   823       {
   747         FT_TRACE0(( "parse_blend_axis_types:"
   824         FT_TRACE0(( "parse_blend_axis_types:"
   748                     " overwriting axis name `%s' with `%*.s'\n",
   825                     " overwriting axis name `%s' with `%.*s'\n",
   749                     name, len, token->start ));
   826                     name, len, token->start ));
   750         FT_FREE( name );
   827         FT_FREE( name );
   751       }
   828       }
   752 
   829 
   753       if ( FT_ALLOC( blend->axis_names[n], len + 1 ) )
   830       if ( FT_ALLOC( blend->axis_names[n], len + 1 ) )
   755 
   832 
   756       name = (FT_Byte*)blend->axis_names[n];
   833       name = (FT_Byte*)blend->axis_names[n];
   757       FT_MEM_COPY( name, token->start, len );
   834       FT_MEM_COPY( name, token->start, len );
   758       name[len] = '\0';
   835       name[len] = '\0';
   759     }
   836     }
       
   837 
       
   838     FT_TRACE4(( "]\n" ));
   760 
   839 
   761   Exit:
   840   Exit:
   762     loader->parser.root.error = error;
   841     loader->parser.root.error = error;
   763   }
   842   }
   764 
   843 
   799       FT_Int    n;
   878       FT_Int    n;
   800 
   879 
   801 
   880 
   802       blend    = face->blend;
   881       blend    = face->blend;
   803       num_axis = 0;  /* make compiler happy */
   882       num_axis = 0;  /* make compiler happy */
       
   883 
       
   884       FT_TRACE4(( " [" ));
   804 
   885 
   805       for ( n = 0; n < num_designs; n++ )
   886       for ( n = 0; n < num_designs; n++ )
   806       {
   887       {
   807         T1_TokenRec  axis_tokens[T1_MAX_MM_AXIS];
   888         T1_TokenRec  axis_tokens[T1_MAX_MM_AXIS];
   808         T1_Token     token;
   889         T1_Token     token;
   840           error = FT_THROW( Invalid_File_Format );
   921           error = FT_THROW( Invalid_File_Format );
   841           goto Exit;
   922           goto Exit;
   842         }
   923         }
   843 
   924 
   844         /* now read each axis token into the design position */
   925         /* now read each axis token into the design position */
       
   926         FT_TRACE4(( " [" )) ;
   845         for ( axis = 0; axis < n_axis; axis++ )
   927         for ( axis = 0; axis < n_axis; axis++ )
   846         {
   928         {
   847           T1_Token  token2 = axis_tokens + axis;
   929           T1_Token  token2 = axis_tokens + axis;
   848 
   930 
   849 
   931 
   850           parser->root.cursor = token2->start;
   932           parser->root.cursor = token2->start;
   851           parser->root.limit  = token2->limit;
   933           parser->root.limit  = token2->limit;
   852           blend->design_pos[n][axis] = T1_ToFixed( parser, 0 );
   934           blend->design_pos[n][axis] = T1_ToFixed( parser, 0 );
       
   935           FT_TRACE4(( " %f", (double)blend->design_pos[n][axis] / 65536 ));
   853         }
   936         }
   854       }
   937         FT_TRACE4(( "]" )) ;
       
   938       }
       
   939 
       
   940       FT_TRACE4(( "]\n" ));
   855 
   941 
   856       loader->parser.root.cursor = old_cursor;
   942       loader->parser.root.cursor = old_cursor;
   857       loader->parser.root.limit  = old_limit;
   943       loader->parser.root.limit  = old_limit;
   858     }
   944     }
   859 
   945 
   897     error = t1_allocate_blend( face, 0, (FT_UInt)num_axis );
   983     error = t1_allocate_blend( face, 0, (FT_UInt)num_axis );
   898     if ( error )
   984     if ( error )
   899       goto Exit;
   985       goto Exit;
   900     blend = face->blend;
   986     blend = face->blend;
   901 
   987 
       
   988     FT_TRACE4(( " [" ));
       
   989 
   902     /* now read each axis design map */
   990     /* now read each axis design map */
   903     for ( n = 0; n < num_axis; n++ )
   991     for ( n = 0; n < num_axis; n++ )
   904     {
   992     {
   905       PS_DesignMap  map = blend->design_map + n;
   993       PS_DesignMap  map = blend->design_map + n;
   906       T1_Token      axis_token;
   994       T1_Token      axis_token;
   912 
  1000 
   913       parser->root.cursor = axis_token->start;
  1001       parser->root.cursor = axis_token->start;
   914       parser->root.limit  = axis_token->limit;
  1002       parser->root.limit  = axis_token->limit;
   915       T1_ToTokenArray( parser, point_tokens,
  1003       T1_ToTokenArray( parser, point_tokens,
   916                        T1_MAX_MM_MAP_POINTS, &num_points );
  1004                        T1_MAX_MM_MAP_POINTS, &num_points );
       
  1005 
       
  1006       FT_TRACE4(( " [" ));
   917 
  1007 
   918       if ( num_points <= 0 || num_points > T1_MAX_MM_MAP_POINTS )
  1008       if ( num_points <= 0 || num_points > T1_MAX_MM_MAP_POINTS )
   919       {
  1009       {
   920         FT_ERROR(( "parse_blend_design_map: incorrect table\n" ));
  1010         FT_ERROR(( "parse_blend_design_map: incorrect table\n" ));
   921         error = FT_THROW( Invalid_File_Format );
  1011         error = FT_THROW( Invalid_File_Format );
   946         parser->root.cursor = point_token->start + 1;
  1036         parser->root.cursor = point_token->start + 1;
   947         parser->root.limit  = point_token->limit - 1;
  1037         parser->root.limit  = point_token->limit - 1;
   948 
  1038 
   949         map->design_points[p] = T1_ToInt( parser );
  1039         map->design_points[p] = T1_ToInt( parser );
   950         map->blend_points [p] = T1_ToFixed( parser, 0 );
  1040         map->blend_points [p] = T1_ToFixed( parser, 0 );
   951       }
  1041 
   952     }
  1042         FT_TRACE4(( " [%d %f]",
       
  1043                     map->design_points[p],
       
  1044                     (double)map->blend_points[p] / 65536 ));
       
  1045       }
       
  1046 
       
  1047       FT_TRACE4(( "]" ));
       
  1048     }
       
  1049 
       
  1050     FT_TRACE4(( "]\n" ));
   953 
  1051 
   954     parser->root.cursor = old_cursor;
  1052     parser->root.cursor = old_cursor;
   955     parser->root.limit  = old_limit;
  1053     parser->root.limit  = old_limit;
   956 
  1054 
   957   Exit:
  1055   Exit:
  1008     }
  1106     }
  1009 
  1107 
  1010     old_cursor = parser->root.cursor;
  1108     old_cursor = parser->root.cursor;
  1011     old_limit  = parser->root.limit;
  1109     old_limit  = parser->root.limit;
  1012 
  1110 
       
  1111     FT_TRACE4(( "[" ));
       
  1112 
  1013     for ( n = 0; n < num_designs; n++ )
  1113     for ( n = 0; n < num_designs; n++ )
  1014     {
  1114     {
  1015       token = design_tokens + n;
  1115       token = design_tokens + n;
  1016       parser->root.cursor = token->start;
  1116       parser->root.cursor = token->start;
  1017       parser->root.limit  = token->limit;
  1117       parser->root.limit  = token->limit;
  1018 
  1118 
  1019       blend->default_weight_vector[n] =
  1119       blend->default_weight_vector[n] =
  1020       blend->weight_vector[n]         = T1_ToFixed( parser, 0 );
  1120       blend->weight_vector[n]         = T1_ToFixed( parser, 0 );
  1021     }
  1121 
       
  1122       FT_TRACE4(( " %f", (double)blend->weight_vector[n] / 65536 ));
       
  1123     }
       
  1124 
       
  1125     FT_TRACE4(( "]\n" ));
  1022 
  1126 
  1023     parser->root.cursor = old_cursor;
  1127     parser->root.cursor = old_cursor;
  1024     parser->root.limit  = old_limit;
  1128     parser->root.limit  = old_limit;
  1025 
  1129 
  1026   Exit:
  1130   Exit:
  1034   parse_buildchar( T1_Face    face,
  1138   parse_buildchar( T1_Face    face,
  1035                    T1_Loader  loader )
  1139                    T1_Loader  loader )
  1036   {
  1140   {
  1037     face->len_buildchar = (FT_UInt)T1_ToFixedArray( &loader->parser,
  1141     face->len_buildchar = (FT_UInt)T1_ToFixedArray( &loader->parser,
  1038                                                     0, NULL, 0 );
  1142                                                     0, NULL, 0 );
       
  1143 
       
  1144 #ifdef FT_DEBUG_LEVEL_TRACE
       
  1145     {
       
  1146       FT_UInt  i;
       
  1147 
       
  1148 
       
  1149       FT_TRACE4(( " [" ));
       
  1150       for ( i = 0; i < face->len_buildchar; i++ )
       
  1151         FT_TRACE4(( " 0" ));
       
  1152 
       
  1153       FT_TRACE4(( "]\n" ));
       
  1154     }
       
  1155 #endif
       
  1156 
  1039     return;
  1157     return;
  1040   }
  1158   }
  1041 
  1159 
  1042 
  1160 
  1043 #endif /* !T1_CONFIG_OPTION_NO_MM_SUPPORT */
  1161 #endif /* !T1_CONFIG_OPTION_NO_MM_SUPPORT */
  1069       blend = NULL;
  1187       blend = NULL;
  1070 
  1188 
  1071     /* if the keyword has a dedicated callback, call it */
  1189     /* if the keyword has a dedicated callback, call it */
  1072     if ( field->type == T1_FIELD_TYPE_CALLBACK )
  1190     if ( field->type == T1_FIELD_TYPE_CALLBACK )
  1073     {
  1191     {
       
  1192       FT_TRACE4(( "  %s", field->ident ));
       
  1193 
  1074       field->reader( (FT_Face)face, loader );
  1194       field->reader( (FT_Face)face, loader );
  1075       error = loader->parser.root.error;
  1195       error = loader->parser.root.error;
  1076       goto Exit;
  1196       goto Exit;
  1077     }
  1197     }
  1078 
  1198 
  1146       dummy_object = &face->type1;
  1266       dummy_object = &face->type1;
  1147       objects      = &dummy_object;
  1267       objects      = &dummy_object;
  1148       max_objects  = 0;
  1268       max_objects  = 0;
  1149     }
  1269     }
  1150 
  1270 
       
  1271     FT_TRACE4(( "  %s", field->ident ));
       
  1272 
  1151     if ( *objects )
  1273     if ( *objects )
  1152     {
  1274     {
  1153       if ( field->type == T1_FIELD_TYPE_INTEGER_ARRAY ||
  1275       if ( field->type == T1_FIELD_TYPE_INTEGER_ARRAY ||
  1154            field->type == T1_FIELD_TYPE_FIXED_ARRAY   )
  1276            field->type == T1_FIELD_TYPE_FIXED_ARRAY   )
  1155         error = T1_Load_Field_Table( &loader->parser, field,
  1277         error = T1_Load_Field_Table( &loader->parser, field,
  1165                   "                 (probably due to missing keywords)\n",
  1287                   "                 (probably due to missing keywords)\n",
  1166                  field->ident ));
  1288                  field->ident ));
  1167       error = FT_Err_Ok;
  1289       error = FT_Err_Ok;
  1168     }
  1290     }
  1169 
  1291 
       
  1292     FT_TRACE4(( "\n" ));
       
  1293 
  1170   Exit:
  1294   Exit:
  1171     return error;
  1295     return error;
  1172   }
  1296   }
  1173 
  1297 
  1174 
  1298 
  1177                  T1_Loader  loader )
  1301                  T1_Loader  loader )
  1178   {
  1302   {
  1179     FT_UNUSED( face );
  1303     FT_UNUSED( face );
  1180 
  1304 
  1181     loader->keywords_encountered |= T1_PRIVATE;
  1305     loader->keywords_encountered |= T1_PRIVATE;
       
  1306 
       
  1307     FT_TRACE4(( "\n" ));
  1182   }
  1308   }
  1183 
  1309 
  1184 
  1310 
  1185   /* return 1 in case of success */
  1311   /* return 1 in case of success */
  1186 
  1312 
  1256     {
  1382     {
  1257       parser->root.error = FT_THROW( Invalid_File_Format );
  1383       parser->root.error = FT_THROW( Invalid_File_Format );
  1258       return;
  1384       return;
  1259     }
  1385     }
  1260 
  1386 
       
  1387     FT_TRACE4(( " [%f %f %f %f %f %f]\n",
       
  1388                 (double)temp[0] / 65536 / 1000,
       
  1389                 (double)temp[1] / 65536 / 1000,
       
  1390                 (double)temp[2] / 65536 / 1000,
       
  1391                 (double)temp[3] / 65536 / 1000,
       
  1392                 (double)temp[4] / 65536 / 1000,
       
  1393                 (double)temp[5] / 65536 / 1000 ));
       
  1394 
  1261     temp_scale = FT_ABS( temp[3] );
  1395     temp_scale = FT_ABS( temp[3] );
  1262 
  1396 
  1263     if ( temp_scale == 0 )
  1397     if ( temp_scale == 0 )
  1264     {
  1398     {
  1265       FT_ERROR(( "t1_parse_font_matrix: invalid font matrix\n" ));
  1399       FT_ERROR(( "t1_parse_font_matrix: invalid font matrix\n" ));
  1278       temp[2] = FT_DivFix( temp[2], temp_scale );
  1412       temp[2] = FT_DivFix( temp[2], temp_scale );
  1279       temp[4] = FT_DivFix( temp[4], temp_scale );
  1413       temp[4] = FT_DivFix( temp[4], temp_scale );
  1280       temp[5] = FT_DivFix( temp[5], temp_scale );
  1414       temp[5] = FT_DivFix( temp[5], temp_scale );
  1281       temp[3] = temp[3] < 0 ? -0x10000L : 0x10000L;
  1415       temp[3] = temp[3] < 0 ? -0x10000L : 0x10000L;
  1282     }
  1416     }
  1283 
       
  1284     matrix->xx = temp[0];
  1417     matrix->xx = temp[0];
  1285     matrix->yx = temp[1];
  1418     matrix->yx = temp[1];
  1286     matrix->xy = temp[2];
  1419     matrix->xy = temp[2];
  1287     matrix->yy = temp[3];
  1420     matrix->yy = temp[3];
       
  1421 
       
  1422     if ( !FT_Matrix_Check( matrix ) )
       
  1423     {
       
  1424       FT_ERROR(( "t1_parse_font_matrix: invalid font matrix\n" ));
       
  1425       parser->root.error = FT_THROW( Invalid_File_Format );
       
  1426       return;
       
  1427     }
  1288 
  1428 
  1289     /* note that the offsets must be expressed in integer font units */
  1429     /* note that the offsets must be expressed in integer font units */
  1290     offset->x = temp[4] >> 16;
  1430     offset->x = temp[4] >> 16;
  1291     offset->y = temp[5] >> 16;
  1431     offset->y = temp[5] >> 16;
  1292   }
  1432   }
  1492         }
  1632         }
  1493 
  1633 
  1494         T1_Skip_Spaces( parser );
  1634         T1_Skip_Spaces( parser );
  1495       }
  1635       }
  1496 
  1636 
       
  1637 #ifdef FT_DEBUG_LEVEL_TRACE
       
  1638       FT_TRACE4(( " [" ));
       
  1639 
       
  1640       /* XXX show encoding vector */
       
  1641       FT_TRACE4(( "..." ));
       
  1642 
       
  1643       FT_TRACE4(( "]\n" ));
       
  1644 #endif
       
  1645 
  1497       face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY;
  1646       face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY;
  1498       parser->root.cursor       = cur;
  1647       parser->root.cursor       = cur;
  1499     }
  1648     }
  1500 
  1649 
  1501     /* Otherwise, we should have either `StandardEncoding', */
  1650     /* Otherwise, we should have either `StandardEncoding', */
  1502     /* `ExpertEncoding', or `ISOLatin1Encoding'             */
  1651     /* `ExpertEncoding', or `ISOLatin1Encoding'             */
  1503     else
  1652     else
  1504     {
  1653     {
  1505       if ( cur + 17 < limit                                            &&
  1654       if ( cur + 17 < limit                                            &&
  1506            ft_strncmp( (const char*)cur, "StandardEncoding", 16 ) == 0 )
  1655            ft_strncmp( (const char*)cur, "StandardEncoding", 16 ) == 0 )
       
  1656       {
  1507         face->type1.encoding_type = T1_ENCODING_TYPE_STANDARD;
  1657         face->type1.encoding_type = T1_ENCODING_TYPE_STANDARD;
       
  1658         FT_TRACE4(( " StandardEncoding\n" ));
       
  1659       }
  1508 
  1660 
  1509       else if ( cur + 15 < limit                                          &&
  1661       else if ( cur + 15 < limit                                          &&
  1510                 ft_strncmp( (const char*)cur, "ExpertEncoding", 14 ) == 0 )
  1662                 ft_strncmp( (const char*)cur, "ExpertEncoding", 14 ) == 0 )
       
  1663       {
  1511         face->type1.encoding_type = T1_ENCODING_TYPE_EXPERT;
  1664         face->type1.encoding_type = T1_ENCODING_TYPE_EXPERT;
       
  1665         FT_TRACE4(( " ExpertEncoding\n" ));
       
  1666       }
  1512 
  1667 
  1513       else if ( cur + 18 < limit                                             &&
  1668       else if ( cur + 18 < limit                                             &&
  1514                 ft_strncmp( (const char*)cur, "ISOLatin1Encoding", 17 ) == 0 )
  1669                 ft_strncmp( (const char*)cur, "ISOLatin1Encoding", 17 ) == 0 )
       
  1670       {
  1515         face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1;
  1671         face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1;
       
  1672         FT_TRACE4(( " ISOLatin1Encoding\n" ));
       
  1673       }
  1516 
  1674 
  1517       else
  1675       else
       
  1676       {
  1518         parser->root.error = FT_ERR( Ignore );
  1677         parser->root.error = FT_ERR( Ignore );
       
  1678         FT_TRACE4(( "<unknown>\n" ));
       
  1679       }
  1519     }
  1680     }
  1520   }
  1681   }
  1521 
  1682 
  1522 
  1683 
  1523   static void
  1684   static void
  1693         goto Fail;
  1854         goto Fail;
  1694     }
  1855     }
  1695 
  1856 
  1696     if ( !loader->num_subrs )
  1857     if ( !loader->num_subrs )
  1697       loader->num_subrs = num_subrs;
  1858       loader->num_subrs = num_subrs;
       
  1859 
       
  1860 #ifdef FT_DEBUG_LEVEL_TRACE
       
  1861       FT_TRACE4(( " <" ));
       
  1862 
       
  1863       /* XXX show subrs? */
       
  1864       FT_TRACE4(( "%d elements", num_subrs ));
       
  1865 
       
  1866       FT_TRACE4(( ">\n" ));
       
  1867 #endif
  1698 
  1868 
  1699     return;
  1869     return;
  1700 
  1870 
  1701   Fail:
  1871   Fail:
  1702     parser->root.error = error;
  1872     parser->root.error = error;
  2015 
  2185 
  2016       /* we added a glyph. */
  2186       /* we added a glyph. */
  2017       loader->num_glyphs += 1;
  2187       loader->num_glyphs += 1;
  2018     }
  2188     }
  2019 
  2189 
       
  2190 #ifdef FT_DEBUG_LEVEL_TRACE
       
  2191       FT_TRACE4(( " <" ));
       
  2192 
       
  2193       /* XXX show charstrings? */
       
  2194       FT_TRACE4(( "%d elements", loader->num_glyphs ));
       
  2195 
       
  2196       FT_TRACE4(( ">\n" ));
       
  2197 #endif
       
  2198 
  2020     return;
  2199     return;
  2021 
  2200 
  2022   Fail:
  2201   Fail:
  2023     parser->root.error = error;
  2202     parser->root.error = error;
  2024   }
  2203   }
  2025 
  2204 
  2026 
  2205 
  2027   /*************************************************************************/
  2206   /**************************************************************************
  2028   /*                                                                       */
  2207    *
  2029   /* Define the token field static variables.  This is a set of            */
  2208    * Define the token field static variables.  This is a set of
  2030   /* T1_FieldRec variables.                                                */
  2209    * T1_FieldRec variables.
  2031   /*                                                                       */
  2210    *
  2032   /*************************************************************************/
  2211    */
  2033 
  2212 
  2034 
  2213 
  2035   static
  2214   static
  2036   const T1_FieldRec  t1_keywords[] =
  2215   const T1_FieldRec  t1_keywords[] =
  2037   {
  2216   {
  2213 
  2392 
  2214               const FT_UInt dict =
  2393               const FT_UInt dict =
  2215                 ( loader->keywords_encountered & T1_PRIVATE )
  2394                 ( loader->keywords_encountered & T1_PRIVATE )
  2216                     ? T1_FIELD_DICT_PRIVATE
  2395                     ? T1_FIELD_DICT_PRIVATE
  2217                     : T1_FIELD_DICT_FONTDICT;
  2396                     : T1_FIELD_DICT_FONTDICT;
       
  2397 
  2218 
  2398 
  2219               if ( !( dict & keyword->dict ) )
  2399               if ( !( dict & keyword->dict ) )
  2220               {
  2400               {
  2221                 FT_TRACE1(( "parse_dict: found `%s' but ignoring it"
  2401                 FT_TRACE1(( "parse_dict: found `%s' but ignoring it"
  2222                             " since it is in the wrong dictionary\n",
  2402                             " since it is in the wrong dictionary\n",
  2328                             face->root.memory,
  2508                             face->root.memory,
  2329                             psaux );
  2509                             psaux );
  2330     if ( error )
  2510     if ( error )
  2331       goto Exit;
  2511       goto Exit;
  2332 
  2512 
       
  2513     FT_TRACE4(( " top dictionary:\n" ));
  2333     error = parse_dict( face, &loader,
  2514     error = parse_dict( face, &loader,
  2334                         parser->base_dict, parser->base_len );
  2515                         parser->base_dict, parser->base_len );
  2335     if ( error )
  2516     if ( error )
  2336       goto Exit;
  2517       goto Exit;
  2337 
  2518 
  2338     error = T1_Get_Private_Dict( parser, psaux );
  2519     error = T1_Get_Private_Dict( parser, psaux );
  2339     if ( error )
  2520     if ( error )
  2340       goto Exit;
  2521       goto Exit;
  2341 
  2522 
       
  2523     FT_TRACE4(( " private dictionary:\n" ));
  2342     error = parse_dict( face, &loader,
  2524     error = parse_dict( face, &loader,
  2343                         parser->private_dict, parser->private_len );
  2525                         parser->private_dict, parser->private_len );
  2344     if ( error )
  2526     if ( error )
  2345       goto Exit;
  2527       goto Exit;
  2346 
  2528 
  2347     /* ensure even-ness of `num_blue_values' */
  2529     /* ensure even-ness of `num_blue_values' */
  2348     priv->num_blue_values &= ~1;
  2530     priv->num_blue_values &= ~1;
  2349 
  2531 
  2350 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
  2532 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
       
  2533 
       
  2534     /* we don't support Multiple Master fonts with intermediate designs; */
       
  2535     /* this implies that `num_designs' must be equal to `2^^num_axis'    */
       
  2536     if ( face->blend                                                 &&
       
  2537          face->blend->num_designs != ( 1U << face->blend->num_axis ) )
       
  2538     {
       
  2539       FT_ERROR(( "T1_Open_Face:"
       
  2540                  " number-of-designs != 2 ^^ number-of-axes\n" ));
       
  2541       T1_Done_Blend( face );
       
  2542     }
  2351 
  2543 
  2352     if ( face->blend                                                     &&
  2544     if ( face->blend                                                     &&
  2353          face->blend->num_default_design_vector != 0                     &&
  2545          face->blend->num_default_design_vector != 0                     &&
  2354          face->blend->num_default_design_vector != face->blend->num_axis )
  2546          face->blend->num_default_design_vector != face->blend->num_axis )
  2355     {
  2547     {