shithub: freetype+ttf2subf

Download patch

ref: 9950adcc11cf94b7d42d236e07fb2be0fb0a695b
parent: 814839a6d8b88215b971227910005f8c5fd2a508
author: Jens Claudius <[email protected]>
date: Sun Aug 13 08:14:36 EDT 2006

* freetype2/include/freetype/internal/psaux.h: (enum T1_TokenType_):
add T1_TOKEN_TYPE_KEY. (struct T1_FieldRec_) add `dict'. Add macros
T1_FIELD_DICT_FONTDICT and  T1_FIELD_DICT_PRIVATE. Change T1_NEW_XXX and
T1_FIELD_XXX macros to take the dictionary where the PS keywords is
expected as an additional argument.

* freetype2/src/cid/cidload.c: (T1_FieldRec): Adjust invocations
of T1_FIELD_XXX.

* freetype2/src/cid/cidtoken.h: Adjust invocations of T1_FIELD_XXX.

* freetype2/src/psaux/psobjs.c: Add macro FT_COMPONENT for tracing.
(ps_parser_to_token): Report a PostScript key as T1_TOKEN_TYPE_KEY
instead as T1_TOKEN_TYPE_ANY. (ps_parser_load_field): Make sure a token
that should be a string or name is a string or name indeed. Avoid
memory leak if a keyword has been already encountered and its value
is overwritten.

* freetype2/src/type1/t1load.c: (T1_FieldRec): Adjust invocations of
T1_FIELD_XXX. (parse_dict): Ignore keywords that occur in the wrong
dictionary (e.g., in Private instead of FontDict).

* freetype2/src/type1/t1tokens.h: Adjust invocations of T1_FIELD_XXX.

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,29 @@
+2006-08-13  Jens Claudius  <[email protected]>
+
+	* freetype2/include/freetype/internal/psaux.h: (enum T1_TokenType_):
+	add T1_TOKEN_TYPE_KEY. (struct T1_FieldRec_) add `dict'. Add macros
+	T1_FIELD_DICT_FONTDICT and  T1_FIELD_DICT_PRIVATE. Change T1_NEW_XXX and
+	T1_FIELD_XXX macros to take the dictionary where the PS keywords is
+	expected as an additional argument.
+
+	* freetype2/src/cid/cidload.c: (T1_FieldRec): Adjust invocations
+	of T1_FIELD_XXX.
+
+	* freetype2/src/cid/cidtoken.h: Adjust invocations of T1_FIELD_XXX.
+
+	* freetype2/src/psaux/psobjs.c: Add macro FT_COMPONENT for tracing.
+	(ps_parser_to_token): Report a PostScript key as T1_TOKEN_TYPE_KEY
+	instead as T1_TOKEN_TYPE_ANY. (ps_parser_load_field): Make sure a token
+	that should be a string or name is a string or name indeed. Avoid
+	memory leak if a keyword has been already encountered and its value
+	is overwritten.
+
+	* freetype2/src/type1/t1load.c: (T1_FieldRec): Adjust invocations of
+	T1_FIELD_XXX. (parse_dict): Ignore keywords that occur in the wrong
+	dictionary (e.g., in Private instead of FontDict).
+
+	* freetype2/src/type1/t1tokens.h: Adjust invocations of T1_FIELD_XXX.
+
 2006-07-18  Jens Claudius  <[email protected]>
 
 	Move creation of field `buildchar' of T1_DecoderRec out of
--- a/include/freetype/internal/psaux.h
+++ b/include/freetype/internal/psaux.h
@@ -154,6 +154,7 @@
     T1_TOKEN_TYPE_ANY,
     T1_TOKEN_TYPE_STRING,
     T1_TOKEN_TYPE_ARRAY,
+    T1_TOKEN_TYPE_KEY, /* aka `name' */
 
     /* do not remove */
     T1_TOKEN_TYPE_MAX
@@ -227,86 +228,96 @@
                                       /* array                          */
     FT_UInt             count_offset; /* offset of element count for    */
                                       /* arrays                         */
+    FT_UInt             dict;         /* where we expect it             */
   } T1_FieldRec;
 
+#define T1_FIELD_DICT_FONTDICT ( 1 << 0 ) /* also FontInfo and FDArray */
+#define T1_FIELD_DICT_PRIVATE  ( 1 << 1 )
 
-#define T1_NEW_SIMPLE_FIELD( _ident, _type, _fname ) \
-          {                                          \
-            _ident, T1CODE, _type,                   \
-            0,                                       \
-            FT_FIELD_OFFSET( _fname ),               \
-            FT_FIELD_SIZE( _fname ),                 \
-            0, 0                                     \
+
+
+#define T1_NEW_SIMPLE_FIELD( _ident, _type, _fname, _dict ) \
+          {                                                 \
+            _ident, T1CODE, _type,                          \
+            0,                                              \
+            FT_FIELD_OFFSET( _fname ),                      \
+            FT_FIELD_SIZE( _fname ),                        \
+            0, 0,                                           \
+            _dict                                           \
           },
 
-#define T1_NEW_CALLBACK_FIELD( _ident, _reader )    \
-          {                                         \
-            _ident, T1CODE, T1_FIELD_TYPE_CALLBACK, \
-            (T1_Field_ParseFunc)_reader,            \
-            0, 0,                                   \
-            0, 0                                    \
+#define T1_NEW_CALLBACK_FIELD( _ident, _reader, _dict ) \
+          {                                             \
+            _ident, T1CODE, T1_FIELD_TYPE_CALLBACK,     \
+            (T1_Field_ParseFunc)_reader,                \
+            0, 0,                                       \
+            0, 0,                                       \
+            _dict                                       \
           },
 
-#define T1_NEW_TABLE_FIELD( _ident, _type, _fname, _max ) \
-          {                                               \
-            _ident, T1CODE, _type,                        \
-            0,                                            \
-            FT_FIELD_OFFSET( _fname ),                    \
-            FT_FIELD_SIZE_DELTA( _fname ),                \
-            _max,                                         \
-            FT_FIELD_OFFSET( num_ ## _fname )             \
+#define T1_NEW_TABLE_FIELD( _ident, _type, _fname, _max, _dict ) \
+          {                                                      \
+            _ident, T1CODE, _type,                               \
+            0,                                                   \
+            FT_FIELD_OFFSET( _fname ),                           \
+            FT_FIELD_SIZE_DELTA( _fname ),                       \
+            _max,                                                \
+            FT_FIELD_OFFSET( num_ ## _fname ),                   \
+            _dict                                                \
           },
 
-#define T1_NEW_TABLE_FIELD2( _ident, _type, _fname, _max ) \
-          {                                                \
-            _ident, T1CODE, _type,                         \
-            0,                                             \
-            FT_FIELD_OFFSET( _fname ),                     \
-            FT_FIELD_SIZE_DELTA( _fname ),                 \
-            _max, 0                                        \
+#define T1_NEW_TABLE_FIELD2( _ident, _type, _fname, _max, _dict ) \
+          {                                                       \
+            _ident, T1CODE, _type,                                \
+            0,                                                    \
+            FT_FIELD_OFFSET( _fname ),                            \
+            FT_FIELD_SIZE_DELTA( _fname ),                        \
+            _max, 0,                                              \
+            _dict                                                 \
           },
 
 
-#define T1_FIELD_BOOL( _ident, _fname )                             \
-          T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BOOL, _fname )
+#define T1_FIELD_BOOL( _ident, _fname, _dict )                             \
+          T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BOOL, _fname, _dict )
 
-#define T1_FIELD_NUM( _ident, _fname )                                 \
-          T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_INTEGER, _fname )
+#define T1_FIELD_NUM( _ident, _fname, _dict )                                 \
+          T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_INTEGER, _fname, _dict )
 
-#define T1_FIELD_FIXED( _ident, _fname )                             \
-          T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED, _fname )
+#define T1_FIELD_FIXED( _ident, _fname, _dict )                             \
+          T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED, _fname, _dict )
 
-#define T1_FIELD_FIXED_1000( _ident, _fname )                             \
-          T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED_1000, _fname )
+#define T1_FIELD_FIXED_1000( _ident, _fname, _dict )                     \
+          T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED_1000, _fname, \
+                               _dict )
 
-#define T1_FIELD_STRING( _ident, _fname )                             \
-          T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_STRING, _fname )
+#define T1_FIELD_STRING( _ident, _fname, _dict )                             \
+          T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_STRING, _fname, _dict )
 
-#define T1_FIELD_KEY( _ident, _fname )                             \
-          T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_KEY, _fname )
+#define T1_FIELD_KEY( _ident, _fname, _dict )                             \
+          T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_KEY, _fname, _dict )
 
-#define T1_FIELD_BBOX( _ident, _fname )                             \
-          T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BBOX, _fname )
+#define T1_FIELD_BBOX( _ident, _fname, _dict )                             \
+          T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BBOX, _fname, _dict )
 
 
-#define T1_FIELD_NUM_TABLE( _ident, _fname, _fmax )                \
+#define T1_FIELD_NUM_TABLE( _ident, _fname, _fmax, _dict )         \
           T1_NEW_TABLE_FIELD( _ident, T1_FIELD_TYPE_INTEGER_ARRAY, \
-                              _fname, _fmax )
+                              _fname, _fmax, _dict )
 
-#define T1_FIELD_FIXED_TABLE( _ident, _fname, _fmax )            \
+#define T1_FIELD_FIXED_TABLE( _ident, _fname, _fmax, _dict )     \
           T1_NEW_TABLE_FIELD( _ident, T1_FIELD_TYPE_FIXED_ARRAY, \
-                              _fname, _fmax )
+                              _fname, _fmax, _dict )
 
-#define T1_FIELD_NUM_TABLE2( _ident, _fname, _fmax )                \
+#define T1_FIELD_NUM_TABLE2( _ident, _fname, _fmax, _dict )         \
           T1_NEW_TABLE_FIELD2( _ident, T1_FIELD_TYPE_INTEGER_ARRAY, \
-                               _fname, _fmax )
+                               _fname, _fmax, _dict )
 
-#define T1_FIELD_FIXED_TABLE2( _ident, _fname, _fmax )            \
+#define T1_FIELD_FIXED_TABLE2( _ident, _fname, _fmax, _dict )     \
           T1_NEW_TABLE_FIELD2( _ident, T1_FIELD_TYPE_FIXED_ARRAY, \
-                               _fname, _fmax )
+                               _fname, _fmax, _dict )
 
-#define T1_FIELD_CALLBACK( _ident, _name )       \
-          T1_NEW_CALLBACK_FIELD( _ident, _name )
+#define T1_FIELD_CALLBACK( _ident, _name, _dict )       \
+          T1_NEW_CALLBACK_FIELD( _ident, _name, _dict )
 
 
   /*************************************************************************/
--- a/src/cid/cidload.c
+++ b/src/cid/cidload.c
@@ -240,10 +240,10 @@
 
 #include "cidtoken.h"
 
-    T1_FIELD_CALLBACK( "FDArray",    parse_fd_array )
-    T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix )
+    T1_FIELD_CALLBACK( "FDArray",    parse_fd_array, 0 )
+    T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix, 0 )
 
-    { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0 }
+    { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0, 0 }
   };
 
 
--- a/src/cid/cidtoken.h
+++ b/src/cid/cidtoken.h
@@ -21,17 +21,17 @@
 #undef  T1CODE
 #define T1CODE        T1_FIELD_LOCATION_CID_INFO
 
-  T1_FIELD_KEY   ( "CIDFontName", cid_font_name )
-  T1_FIELD_NUM   ( "CIDFontVersion", cid_version )
-  T1_FIELD_NUM   ( "CIDFontType", cid_font_type )
-  T1_FIELD_STRING( "Registry", registry )
-  T1_FIELD_STRING( "Ordering", ordering )
-  T1_FIELD_NUM   ( "Supplement", supplement )
-  T1_FIELD_NUM   ( "UIDBase", uid_base )
-  T1_FIELD_NUM   ( "CIDMapOffset", cidmap_offset )
-  T1_FIELD_NUM   ( "FDBytes", fd_bytes )
-  T1_FIELD_NUM   ( "GDBytes", gd_bytes )
-  T1_FIELD_NUM   ( "CIDCount", cid_count )
+  T1_FIELD_KEY   ( "CIDFontName", cid_font_name, 0 )
+  T1_FIELD_NUM   ( "CIDFontVersion", cid_version, 0 )
+  T1_FIELD_NUM   ( "CIDFontType", cid_font_type, 0 )
+  T1_FIELD_STRING( "Registry", registry, 0 )
+  T1_FIELD_STRING( "Ordering", ordering, 0 )
+  T1_FIELD_NUM   ( "Supplement", supplement, 0 )
+  T1_FIELD_NUM   ( "UIDBase", uid_base, 0 )
+  T1_FIELD_NUM   ( "CIDMapOffset", cidmap_offset, 0 )
+  T1_FIELD_NUM   ( "FDBytes", fd_bytes, 0 )
+  T1_FIELD_NUM   ( "GDBytes", gd_bytes, 0 )
+  T1_FIELD_NUM   ( "CIDCount", cid_count, 0 )
 
 
 #undef  FT_STRUCTURE
@@ -39,15 +39,15 @@
 #undef  T1CODE
 #define T1CODE        T1_FIELD_LOCATION_FONT_INFO
 
-  T1_FIELD_STRING( "version", version )
-  T1_FIELD_STRING( "Notice", notice )
-  T1_FIELD_STRING( "FullName", full_name )
-  T1_FIELD_STRING( "FamilyName", family_name )
-  T1_FIELD_STRING( "Weight", weight )
-  T1_FIELD_NUM   ( "ItalicAngle", italic_angle )
-  T1_FIELD_BOOL  ( "isFixedPitch", is_fixed_pitch )
-  T1_FIELD_NUM   ( "UnderlinePosition", underline_position )
-  T1_FIELD_NUM   ( "UnderlineThickness", underline_thickness )
+  T1_FIELD_STRING( "version", version, 0 )
+  T1_FIELD_STRING( "Notice", notice, 0 )
+  T1_FIELD_STRING( "FullName", full_name, 0 )
+  T1_FIELD_STRING( "FamilyName", family_name, 0 )
+  T1_FIELD_STRING( "Weight", weight, 0 )
+  T1_FIELD_NUM   ( "ItalicAngle", italic_angle, 0 )
+  T1_FIELD_BOOL  ( "isFixedPitch", is_fixed_pitch, 0 )
+  T1_FIELD_NUM   ( "UnderlinePosition", underline_position, 0 )
+  T1_FIELD_NUM   ( "UnderlineThickness", underline_thickness, 0 )
 
 
 #undef  FT_STRUCTURE
@@ -55,15 +55,15 @@
 #undef  T1CODE
 #define T1CODE        T1_FIELD_LOCATION_FONT_DICT
 
-  T1_FIELD_NUM  ( "PaintType", paint_type )
-  T1_FIELD_NUM  ( "FontType", font_type )
-  T1_FIELD_NUM  ( "SubrMapOffset", subrmap_offset )
-  T1_FIELD_NUM  ( "SDBytes", sd_bytes )
-  T1_FIELD_NUM  ( "SubrCount", num_subrs )
-  T1_FIELD_NUM  ( "lenBuildCharArray", len_buildchar )
-  T1_FIELD_FIXED( "ForceBoldThreshold", forcebold_threshold )
-  T1_FIELD_FIXED( "ExpansionFactor", expansion_factor )
-  T1_FIELD_FIXED( "StrokeWidth", stroke_width )
+  T1_FIELD_NUM  ( "PaintType", paint_type, 0 )
+  T1_FIELD_NUM  ( "FontType", font_type, 0 )
+  T1_FIELD_NUM  ( "SubrMapOffset", subrmap_offset, 0 )
+  T1_FIELD_NUM  ( "SDBytes", sd_bytes, 0 )
+  T1_FIELD_NUM  ( "SubrCount", num_subrs, 0 )
+  T1_FIELD_NUM  ( "lenBuildCharArray", len_buildchar, 0 )
+  T1_FIELD_FIXED( "ForceBoldThreshold", forcebold_threshold, 0 )
+  T1_FIELD_FIXED( "ExpansionFactor", expansion_factor, 0 )
+  T1_FIELD_FIXED( "StrokeWidth", stroke_width, 0 )
 
 
 #undef  FT_STRUCTURE
@@ -71,26 +71,26 @@
 #undef  T1CODE
 #define T1CODE        T1_FIELD_LOCATION_PRIVATE
 
-  T1_FIELD_NUM       ( "UniqueID", unique_id )
-  T1_FIELD_NUM       ( "lenIV", lenIV )
-  T1_FIELD_NUM       ( "LanguageGroup", language_group )
-  T1_FIELD_NUM       ( "password", password )
+  T1_FIELD_NUM       ( "UniqueID", unique_id, 0 )
+  T1_FIELD_NUM       ( "lenIV", lenIV, 0 )
+  T1_FIELD_NUM       ( "LanguageGroup", language_group, 0 )
+  T1_FIELD_NUM       ( "password", password, 0 )
 
-  T1_FIELD_FIXED_1000( "BlueScale", blue_scale )
-  T1_FIELD_NUM       ( "BlueShift", blue_shift )
-  T1_FIELD_NUM       ( "BlueFuzz",  blue_fuzz )
+  T1_FIELD_FIXED_1000( "BlueScale", blue_scale, 0 )
+  T1_FIELD_NUM       ( "BlueShift", blue_shift, 0 )
+  T1_FIELD_NUM       ( "BlueFuzz",  blue_fuzz, 0 )
 
-  T1_FIELD_NUM_TABLE ( "BlueValues", blue_values, 14 )
-  T1_FIELD_NUM_TABLE ( "OtherBlues", other_blues, 10 )
-  T1_FIELD_NUM_TABLE ( "FamilyBlues", family_blues, 14 )
-  T1_FIELD_NUM_TABLE ( "FamilyOtherBlues", family_other_blues, 10 )
+  T1_FIELD_NUM_TABLE ( "BlueValues", blue_values, 14, 0 )
+  T1_FIELD_NUM_TABLE ( "OtherBlues", other_blues, 10, 0 )
+  T1_FIELD_NUM_TABLE ( "FamilyBlues", family_blues, 14, 0 )
+  T1_FIELD_NUM_TABLE ( "FamilyOtherBlues", family_other_blues, 10, 0 )
 
-  T1_FIELD_NUM_TABLE2( "StdHW", standard_width,  1 )
-  T1_FIELD_NUM_TABLE2( "StdVW", standard_height, 1 )
-  T1_FIELD_NUM_TABLE2( "MinFeature", min_feature, 2 )
+  T1_FIELD_NUM_TABLE2( "StdHW", standard_width,  1, 0 )
+  T1_FIELD_NUM_TABLE2( "StdVW", standard_height, 1, 0 )
+  T1_FIELD_NUM_TABLE2( "MinFeature", min_feature, 2, 0 )
 
-  T1_FIELD_NUM_TABLE ( "StemSnapH", snap_widths, 12 )
-  T1_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12 )
+  T1_FIELD_NUM_TABLE ( "StemSnapH", snap_widths, 12, 0 )
+  T1_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12, 0 )
 
 #undef  FT_STRUCTURE
 #define FT_STRUCTURE  FT_BBox
@@ -97,7 +97,7 @@
 #undef  T1CODE
 #define T1CODE        T1_FIELD_LOCATION_BBOX
 
-  T1_FIELD_BBOX( "FontBBox", xMin )
+  T1_FIELD_BBOX( "FontBBox", xMin, 0 )
 
 
 /* END */
--- a/src/psaux/psobjs.c
+++ b/src/psaux/psobjs.c
@@ -27,7 +27,17 @@
 
 
   /*************************************************************************/
+  /*                                                                       */
+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
+  /* messages during execution.                                            */
+  /*                                                                       */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_psobjs
+
+
   /*************************************************************************/
+  /*************************************************************************/
   /*****                                                               *****/
   /*****                             PS_TABLE                          *****/
   /*****                                                               *****/
@@ -118,7 +128,7 @@
     }
 
     /* copy elements and shift offsets */
-    if (old_base )
+    if ( old_base )
     {
       FT_MEM_COPY( table->block, old_base, table->capacity );
       shift_elements( table, old_base );
@@ -681,7 +691,7 @@
       /* ************ otherwise, it is any token **************/
     default:
       token->start = cur;
-      token->type  = T1_TOKEN_TYPE_ANY;
+      token->type  = ( *cur == '/' ? T1_TOKEN_TYPE_KEY : T1_TOKEN_TYPE_ANY );
       ps_parser_skip_PS_token( parser );
       cur = parser->cursor;
       if ( !parser->error )
@@ -1101,17 +1111,40 @@
           if ( cur >= limit )
             break;
 
-          if ( field->type == T1_FIELD_TYPE_KEY )
+          /* we allow both a string or a name   */
+          /* for cases like /FontName (foo) def */
+          if ( token.type == T1_TOKEN_TYPE_KEY )
           {
             /* don't include leading `/' */
             len--;
             cur++;
           }
-          else
+          else if ( token.type == T1_TOKEN_TYPE_STRING )
           {
-            /* don't include delimiting parentheses */
+            /* don't include delimiting parentheses    */
+            /* XXX we don't handle <<...>> here        */
+            /* XXX should we convert octal escapes?    */
+            /*     if so, what encoding should we use? */
             cur++;
             len -= 2;
+          }
+          else
+          {
+            FT_ERROR(( "ps_parser_load_field: expected a name or string "
+                       "but found token of type %d instead\n",
+                       token.type ));
+            error = PSaux_Err_Invalid_File_Format;
+            goto Exit;
+          }
+
+          /* for this to work (FT_String**)q must have been */
+          /* initialized to NULL                            */
+          if ( *(FT_String**)q != NULL )
+          {
+            FT_TRACE0(( "ps_parser_load_field: overwriting field %s\n",
+                        field->ident ));
+            FT_FREE( *(FT_String**)q );
+            *(FT_String**)q = NULL;
           }
 
           if ( FT_ALLOC( string, len + 1 ) )
--- a/src/type1/t1load.c
+++ b/src/type1/t1load.c
@@ -1721,21 +1721,21 @@
 #include "t1tokens.h"
 
     /* now add the special functions... */
-    T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix )
-    T1_FIELD_CALLBACK( "Encoding", parse_encoding )
-    T1_FIELD_CALLBACK( "Subrs", parse_subrs )
-    T1_FIELD_CALLBACK( "CharStrings", parse_charstrings )
-    T1_FIELD_CALLBACK( "Private", parse_private )
+    T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix, T1_FIELD_DICT_FONTDICT )
+    T1_FIELD_CALLBACK( "Encoding", parse_encoding, T1_FIELD_DICT_FONTDICT )
+    T1_FIELD_CALLBACK( "Subrs", parse_subrs, T1_FIELD_DICT_PRIVATE )
+    T1_FIELD_CALLBACK( "CharStrings", parse_charstrings, T1_FIELD_DICT_PRIVATE )
+    T1_FIELD_CALLBACK( "Private", parse_private, T1_FIELD_DICT_FONTDICT )
 
 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
-    T1_FIELD_CALLBACK( "BlendDesignPositions", parse_blend_design_positions )
-    T1_FIELD_CALLBACK( "BlendDesignMap", parse_blend_design_map )
-    T1_FIELD_CALLBACK( "BlendAxisTypes", parse_blend_axis_types )
-    T1_FIELD_CALLBACK( "WeightVector", parse_weight_vector )
-    T1_FIELD_CALLBACK( "BuildCharArray", parse_buildchar )
+    T1_FIELD_CALLBACK( "BlendDesignPositions", parse_blend_design_positions, T1_FIELD_DICT_FONTDICT )
+    T1_FIELD_CALLBACK( "BlendDesignMap", parse_blend_design_map, T1_FIELD_DICT_FONTDICT )
+    T1_FIELD_CALLBACK( "BlendAxisTypes", parse_blend_axis_types, T1_FIELD_DICT_FONTDICT )
+    T1_FIELD_CALLBACK( "WeightVector", parse_weight_vector, T1_FIELD_DICT_FONTDICT )
+    T1_FIELD_CALLBACK( "BuildCharArray", parse_buildchar, T1_FIELD_DICT_PRIVATE )
 #endif
 
-    { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0 }
+    { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0, 0 }
   };
 
 
@@ -1874,9 +1874,34 @@
               /* interested in anything that follows this     */
               /* `FontDirectory'                              */
 
-              if ( !( loader->keywords_encountered                &
+              /* MM fonts have more than one /Private token at */
+              /* the top level; let's hope that all the junk   */
+              /* that follows the first /Private token is not  */
+              /* interesting to us                             */
+
+              /* According to Adobe Tech Note #5175 (CID-Keyed */
+              /* Font Installation for ATM Software) a `begin' */
+              /* must be followed by exactly one `end' and     */
+              /* `begin' -- `end' pairs must be accurately     */
+              /* paired. We could use this to dinstinguish     */
+              /* between the global Private and the Private    */
+              /* that is a member of the Blend dict.           */
+
+              const FT_UInt dict
+                = ( ( loader->keywords_encountered & T1_PRIVATE ) ? 
+                    T1_FIELD_DICT_PRIVATE : T1_FIELD_DICT_FONTDICT );
+
+              if ( ! ( dict & keyword->dict ) )
+              {
+                FT_TRACE1(( "parse_dict: found %s but ignore it "
+                            "since it is in the wrong dictionary\n",
+                            keyword->ident ));
+                break;
+              }
+
+              if ( !( loader->keywords_encountered                  &
                       T1_FONTDIR_AFTER_PRIVATE ) ||
-                   ft_strcmp((const char*)name, "CharStrings") == 0 )
+                   ft_strcmp( (const char*)name, "CharStrings" ) == 0 )
               {
                 parser->root.error = t1_load_keyword( face,
                                                       loader,
--- a/src/type1/t1tokens.h
+++ b/src/type1/t1tokens.h
@@ -21,17 +21,17 @@
 #undef  T1CODE
 #define T1CODE        T1_FIELD_LOCATION_FONT_INFO
 
-  T1_FIELD_STRING( "version", version )
-  T1_FIELD_STRING( "Notice", notice )
-  T1_FIELD_STRING( "FullName", full_name )
-  T1_FIELD_STRING( "FamilyName", family_name )
-  T1_FIELD_STRING( "Weight", weight )
+  T1_FIELD_STRING( "version", version, T1_FIELD_DICT_FONTDICT )
+  T1_FIELD_STRING( "Notice", notice, T1_FIELD_DICT_FONTDICT )
+  T1_FIELD_STRING( "FullName", full_name, T1_FIELD_DICT_FONTDICT )
+  T1_FIELD_STRING( "FamilyName", family_name, T1_FIELD_DICT_FONTDICT )
+  T1_FIELD_STRING( "Weight", weight, T1_FIELD_DICT_FONTDICT )
 
   /* we use pointers to detect modifications made by synthetic fonts */
-  T1_FIELD_NUM   ( "ItalicAngle", italic_angle )
-  T1_FIELD_BOOL  ( "isFixedPitch", is_fixed_pitch )
-  T1_FIELD_NUM   ( "UnderlinePosition", underline_position )
-  T1_FIELD_NUM   ( "UnderlineThickness", underline_thickness )
+  T1_FIELD_NUM   ( "ItalicAngle", italic_angle, T1_FIELD_DICT_FONTDICT )
+  T1_FIELD_BOOL  ( "isFixedPitch", is_fixed_pitch, T1_FIELD_DICT_FONTDICT )
+  T1_FIELD_NUM   ( "UnderlinePosition", underline_position, T1_FIELD_DICT_FONTDICT )
+  T1_FIELD_NUM   ( "UnderlineThickness", underline_thickness, T1_FIELD_DICT_FONTDICT )
 
 
 #undef  FT_STRUCTURE
@@ -39,28 +39,28 @@
 #undef  T1CODE
 #define T1CODE        T1_FIELD_LOCATION_PRIVATE
 
-  T1_FIELD_NUM       ( "UniqueID", unique_id )
-  T1_FIELD_NUM       ( "lenIV", lenIV )
-  T1_FIELD_NUM       ( "LanguageGroup", language_group )
-  T1_FIELD_NUM       ( "password", password )
+  T1_FIELD_NUM       ( "UniqueID", unique_id, T1_FIELD_DICT_FONTDICT | T1_FIELD_DICT_PRIVATE )
+  T1_FIELD_NUM       ( "lenIV", lenIV, T1_FIELD_DICT_PRIVATE )
+  T1_FIELD_NUM       ( "LanguageGroup", language_group, T1_FIELD_DICT_PRIVATE )
+  T1_FIELD_NUM       ( "password", password, T1_FIELD_DICT_PRIVATE )
 
-  T1_FIELD_FIXED_1000( "BlueScale", blue_scale )
-  T1_FIELD_NUM       ( "BlueShift", blue_shift )
-  T1_FIELD_NUM       ( "BlueFuzz",  blue_fuzz )
+  T1_FIELD_FIXED_1000( "BlueScale", blue_scale, T1_FIELD_DICT_PRIVATE )
+  T1_FIELD_NUM       ( "BlueShift", blue_shift, T1_FIELD_DICT_PRIVATE )
+  T1_FIELD_NUM       ( "BlueFuzz",  blue_fuzz, T1_FIELD_DICT_PRIVATE )
 
-  T1_FIELD_NUM_TABLE ( "BlueValues", blue_values, 14 )
-  T1_FIELD_NUM_TABLE ( "OtherBlues", other_blues, 10 )
-  T1_FIELD_NUM_TABLE ( "FamilyBlues", family_blues, 14 )
-  T1_FIELD_NUM_TABLE ( "FamilyOtherBlues", family_other_blues, 10 )
+  T1_FIELD_NUM_TABLE ( "BlueValues", blue_values, 14, T1_FIELD_DICT_PRIVATE )
+  T1_FIELD_NUM_TABLE ( "OtherBlues", other_blues, 10, T1_FIELD_DICT_PRIVATE )
+  T1_FIELD_NUM_TABLE ( "FamilyBlues", family_blues, 14, T1_FIELD_DICT_PRIVATE )
+  T1_FIELD_NUM_TABLE ( "FamilyOtherBlues", family_other_blues, 10, T1_FIELD_DICT_PRIVATE )
 
-  T1_FIELD_NUM_TABLE2( "StdHW", standard_width,  1 )
-  T1_FIELD_NUM_TABLE2( "StdVW", standard_height, 1 )
-  T1_FIELD_NUM_TABLE2( "MinFeature", min_feature, 2 )
+  T1_FIELD_NUM_TABLE2( "StdHW", standard_width,  1, T1_FIELD_DICT_PRIVATE )
+  T1_FIELD_NUM_TABLE2( "StdVW", standard_height, 1, T1_FIELD_DICT_PRIVATE )
+  T1_FIELD_NUM_TABLE2( "MinFeature", min_feature, 2, T1_FIELD_DICT_PRIVATE )
 
-  T1_FIELD_NUM_TABLE ( "StemSnapH", snap_widths, 12 )
-  T1_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12 )
+  T1_FIELD_NUM_TABLE ( "StemSnapH", snap_widths, 12, T1_FIELD_DICT_PRIVATE )
+  T1_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12, T1_FIELD_DICT_PRIVATE )
 
-  T1_FIELD_FIXED     ( "ExpansionFactor", expansion_factor )
+  T1_FIELD_FIXED     ( "ExpansionFactor", expansion_factor, T1_FIELD_DICT_PRIVATE )
 
 
 #undef  FT_STRUCTURE
@@ -68,10 +68,10 @@
 #undef  T1CODE
 #define T1CODE        T1_FIELD_LOCATION_FONT_DICT
 
-  T1_FIELD_KEY  ( "FontName", font_name )
-  T1_FIELD_NUM  ( "PaintType", paint_type )
-  T1_FIELD_NUM  ( "FontType", font_type )
-  T1_FIELD_FIXED( "StrokeWidth", stroke_width )
+  T1_FIELD_KEY  ( "FontName", font_name, T1_FIELD_DICT_FONTDICT )
+  T1_FIELD_NUM  ( "PaintType", paint_type, T1_FIELD_DICT_FONTDICT )
+  T1_FIELD_NUM  ( "FontType", font_type, T1_FIELD_DICT_FONTDICT )
+  T1_FIELD_FIXED( "StrokeWidth", stroke_width, T1_FIELD_DICT_FONTDICT )
 
 
 #undef  FT_STRUCTURE
@@ -79,7 +79,7 @@
 #undef  T1CODE
 #define T1CODE        T1_FIELD_LOCATION_BBOX
 
-  T1_FIELD_BBOX("FontBBox", xMin )
+  T1_FIELD_BBOX( "FontBBox", xMin, T1_FIELD_DICT_FONTDICT )
 
 
 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
@@ -89,8 +89,8 @@
 #undef  T1CODE
 #define T1CODE        T1_FIELD_LOCATION_FACE
 
-  T1_FIELD_NUM      ( "NDV", ndv_idx )
-  T1_FIELD_NUM      ( "CDV", cdv_idx )
+  T1_FIELD_NUM      ( "NDV", ndv_idx, T1_FIELD_DICT_PRIVATE )
+  T1_FIELD_NUM      ( "CDV", cdv_idx, T1_FIELD_DICT_PRIVATE )
 
 
 #undef  FT_STRUCTURE
@@ -98,7 +98,7 @@
 #undef  T1CODE
 #define T1CODE        T1_FIELD_LOCATION_BLEND
 
-  T1_FIELD_NUM_TABLE( "DesignVector", default_design_vector, T1_MAX_MM_DESIGNS )
+  T1_FIELD_NUM_TABLE( "DesignVector", default_design_vector, T1_MAX_MM_DESIGNS, T1_FIELD_DICT_FONTDICT )
 
 
 #endif /* T1_CONFIG_OPTION_NO_MM_SUPPORT */
--- a/src/type42/t42parse.c
+++ b/src/type42/t42parse.c
@@ -49,6 +49,8 @@
                    T42_Loader  loader );
 
 
+  /* as Type42 fonts have no Private dict,         */
+  /* we set the last argument of T1_FIELD_XXX to 0 */
   static const
   T1_FieldRec  t42_keywords[] = {
 
@@ -57,15 +59,15 @@
 #undef  T1CODE
 #define T1CODE        T1_FIELD_LOCATION_FONT_INFO
 
-    T1_FIELD_STRING( "version",            version )
-    T1_FIELD_STRING( "Notice",             notice )
-    T1_FIELD_STRING( "FullName",           full_name )
-    T1_FIELD_STRING( "FamilyName",         family_name )
-    T1_FIELD_STRING( "Weight",             weight )
-    T1_FIELD_NUM   ( "ItalicAngle",        italic_angle )
-    T1_FIELD_BOOL  ( "isFixedPitch",       is_fixed_pitch )
-    T1_FIELD_NUM   ( "UnderlinePosition",  underline_position )
-    T1_FIELD_NUM   ( "UnderlineThickness", underline_thickness )
+    T1_FIELD_STRING( "version",            version,             0 )
+    T1_FIELD_STRING( "Notice",             notice,              0 )
+    T1_FIELD_STRING( "FullName",           full_name,           0 )
+    T1_FIELD_STRING( "FamilyName",         family_name,         0 )
+    T1_FIELD_STRING( "Weight",             weight,              0 )
+    T1_FIELD_NUM   ( "ItalicAngle",        italic_angle,        0 )
+    T1_FIELD_BOOL  ( "isFixedPitch",       is_fixed_pitch,      0 )
+    T1_FIELD_NUM   ( "UnderlinePosition",  underline_position,  0 )
+    T1_FIELD_NUM   ( "UnderlineThickness", underline_thickness, 0 )
 
 #undef  FT_STRUCTURE
 #define FT_STRUCTURE  T1_FontRec
@@ -72,10 +74,10 @@
 #undef  T1CODE
 #define T1CODE        T1_FIELD_LOCATION_FONT_DICT
 
-    T1_FIELD_KEY  ( "FontName",    font_name )
-    T1_FIELD_NUM  ( "PaintType",   paint_type )
-    T1_FIELD_NUM  ( "FontType",    font_type )
-    T1_FIELD_FIXED( "StrokeWidth", stroke_width )
+    T1_FIELD_KEY  ( "FontName",    font_name,    0 )
+    T1_FIELD_NUM  ( "PaintType",   paint_type,   0 )
+    T1_FIELD_NUM  ( "FontType",    font_type,    0 )
+    T1_FIELD_FIXED( "StrokeWidth", stroke_width, 0 )
 
 #undef  FT_STRUCTURE
 #define FT_STRUCTURE  FT_BBox
@@ -82,14 +84,14 @@
 #undef  T1CODE
 #define T1CODE        T1_FIELD_LOCATION_BBOX
 
-    T1_FIELD_BBOX("FontBBox", xMin )
+    T1_FIELD_BBOX("FontBBox", xMin, 0 )
 
-    T1_FIELD_CALLBACK( "FontMatrix",  t42_parse_font_matrix )
-    T1_FIELD_CALLBACK( "Encoding",    t42_parse_encoding )
-    T1_FIELD_CALLBACK( "CharStrings", t42_parse_charstrings )
-    T1_FIELD_CALLBACK( "sfnts",       t42_parse_sfnts )
+    T1_FIELD_CALLBACK( "FontMatrix",  t42_parse_font_matrix, 0 )
+    T1_FIELD_CALLBACK( "Encoding",    t42_parse_encoding,    0 )
+    T1_FIELD_CALLBACK( "CharStrings", t42_parse_charstrings, 0 )
+    T1_FIELD_CALLBACK( "sfnts",       t42_parse_sfnts,       0 )
 
-    { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0 }
+    { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0, 0 }
   };