Commit 2ef0a19842ae1172bec153225328aaaeaf130a18

Werner Lemberg 2012-12-23T21:14:37

[type1] Fix handling of /FontBBox in MM fonts. Problem reported by Del Merritt <del@alum.mit.edu> If we have /FontBBox { { 11 12 13 14 15 16 17 18 } { 21 22 23 24 25 26 27 28 } { 31 32 33 34 35 36 37 38 } { 41 42 43 44 45 46 47 48 } } in the /Blend dictionary, then the first BBox is { 11 21 31 41 }, the second { 12 22 32 42 }, etc. * include/freetype/internal/psaux.h (T1_FieldType): Add `T1_FIELD_TYPE_MM_BBOX' (for temporary use). * src/psaux/psobjs.c (ps_parser_load_field) <T1_FIELD_TYPE_MM_BBOX>: Implement it.

diff --git a/ChangeLog b/ChangeLog
index 1d978a9..6fab500 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2012-12-23  Werner Lemberg  <wl@gnu.org>
+
+	[type1] Fix handling of /FontBBox in MM fonts.
+	Problem reported by Del Merritt <del@alum.mit.edu>
+
+	If we have
+
+	  /FontBBox { { 11 12 13 14 15 16 17 18 }
+	              { 21 22 23 24 25 26 27 28 }
+	              { 31 32 33 34 35 36 37 38 }
+	              { 41 42 43 44 45 46 47 48 } }
+
+	in the /Blend dictionary,  then the first BBox is { 11 21 31 41 },
+	the second { 12 22 32 42 }, etc.
+
+	* include/freetype/internal/psaux.h (T1_FieldType): Add
+	`T1_FIELD_TYPE_MM_BBOX' (for temporary use).
+
+	* src/psaux/psobjs.c (ps_parser_load_field) <T1_FIELD_TYPE_MM_BBOX>:
+	Implement it.
+
 2012-12-21  Alexei Podtelezhnikov  <apodtele@gmail.com>
 
 	* src/tools/cordic.py: Bring up to date with trigonometric core.
diff --git a/include/freetype/internal/psaux.h b/include/freetype/internal/psaux.h
index dccf6fc..e903114 100644
--- a/include/freetype/internal/psaux.h
+++ b/include/freetype/internal/psaux.h
@@ -186,6 +186,7 @@ FT_BEGIN_HEADER
     T1_FIELD_TYPE_STRING,
     T1_FIELD_TYPE_KEY,
     T1_FIELD_TYPE_BBOX,
+    T1_FIELD_TYPE_MM_BBOX,
     T1_FIELD_TYPE_INTEGER_ARRAY,
     T1_FIELD_TYPE_FIXED_ARRAY,
     T1_FIELD_TYPE_CALLBACK,
diff --git a/src/psaux/psobjs.c b/src/psaux/psobjs.c
index 06df6e6..6f84325 100644
--- a/src/psaux/psobjs.c
+++ b/src/psaux/psobjs.c
@@ -1027,12 +1027,13 @@
                         FT_UInt         max_objects,
                         FT_ULong*       pflags )
   {
-    T1_TokenRec  token;
-    FT_Byte*     cur;
-    FT_Byte*     limit;
-    FT_UInt      count;
-    FT_UInt      idx;
-    FT_Error     error;
+    T1_TokenRec   token;
+    FT_Byte*      cur;
+    FT_Byte*      limit;
+    FT_UInt       count;
+    FT_UInt       idx;
+    FT_Error      error;
+    T1_FieldType  type;
 
 
     /* this also skips leading whitespace */
@@ -1045,8 +1046,10 @@
     cur   = token.start;
     limit = token.limit;
 
+    type = field->type;
+
     /* we must detect arrays in /FontBBox */
-    if ( field->type == T1_FIELD_TYPE_BBOX )
+    if ( type == T1_FIELD_TYPE_BBOX )
     {
       T1_TokenRec  token2;
       FT_Byte*     old_cur   = parser->cursor;
@@ -1062,17 +1065,21 @@
       parser->limit  = old_limit;
 
       if ( token2.type == T1_TOKEN_TYPE_ARRAY )
+      {
+        type = T1_FIELD_TYPE_MM_BBOX;
         goto FieldArray;
+      }
     }
     else if ( token.type == T1_TOKEN_TYPE_ARRAY )
     {
+      count = max_objects;
+
     FieldArray:
       /* if this is an array and we have no blend, an error occurs */
       if ( max_objects == 0 )
         goto Fail;
 
-      count = max_objects;
-      idx   = 1;
+      idx = 1;
 
       /* don't include delimiters */
       cur++;
@@ -1088,7 +1095,7 @@
 
       skip_spaces( &cur, limit );
 
-      switch ( field->type )
+      switch ( type )
       {
       case T1_FIELD_TYPE_BOOL:
         val = ps_tobool( &cur, limit );
@@ -1208,6 +1215,54 @@
         }
         break;
 
+      case T1_FIELD_TYPE_MM_BBOX:
+        {
+          FT_Memory  memory = parser->memory;
+          FT_Fixed*  temp;
+          FT_Int     result;
+          FT_UInt    i;
+
+
+          if ( FT_NEW_ARRAY( temp, max_objects * 4 ) )
+            goto Exit;
+
+          for ( i = 0; i < 4; i++ )
+          {
+            result = ps_tofixedarray( &cur, limit, max_objects,
+                                      temp + i * max_objects, 0 );
+            if ( result < 0 )
+            {
+              FT_ERROR(( "ps_parser_load_field:"
+                         " expected %d integers in the %s subarray\n"
+                         "                     "
+                         " of /FontBBox in the /Blend dictionary\n",
+                         max_objects,
+                         i == 0 ? "first"
+                                : ( i == 1 ? "second"
+                                           : ( i == 2 ? "third"
+                                                      : "fourth" ) ) ));
+              error = PSaux_Err_Invalid_File_Format;
+              goto Exit;
+            }
+
+            skip_spaces( &cur, limit );
+          }
+
+          for ( i = 0; i < max_objects; i++ )
+          {
+            FT_BBox*  bbox = (FT_BBox*)objects[i];
+
+
+            bbox->xMin = FT_RoundFix( temp[i                  ] );
+            bbox->yMin = FT_RoundFix( temp[i +     max_objects] );
+            bbox->xMax = FT_RoundFix( temp[i + 2 * max_objects] );
+            bbox->yMax = FT_RoundFix( temp[i + 3 * max_objects] );
+          }
+
+          FT_FREE( temp );
+        }
+        break;
+
       default:
         /* an error occurred */
         goto Fail;