Fix Savannah bug #33816.

* src/cff/cfftypes.h (CFF_FontRecDictRec): New member
`has_font_matrix'.
* src/cff/cffparse.c (cff_parse_font_matrix): Set it.
Update tracing output.
* src/cff/cffobjs.c (cff_face_init): Use it so that the heuristics
can be removed.
diff --git a/ChangeLog b/ChangeLog
index fe89097..68617b4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2011-09-07  Werner Lemberg  <wl@gnu.org>
+
+	Fix Savannah bug #33816.
+
+	* src/cff/cfftypes.h (CFF_FontRecDictRec): New member
+	`has_font_matrix'.
+	* src/cff/cffparse.c (cff_parse_font_matrix): Set it.
+	Update tracing output.
+	* src/cff/cffobjs.c (cff_face_init): Use it so that the heuristics
+	can be removed.
+
 2011-08-30  Werner Lemberg  <wl@gnu.org>
 
 	Better tracing of metrics.
diff --git a/src/cff/cffobjs.c b/src/cff/cffobjs.c
index cd38676..f20292f 100644
--- a/src/cff/cffobjs.c
+++ b/src/cff/cffobjs.c
@@ -607,7 +607,7 @@
         goto Bad_Format;
       }
 
-      if ( !dict->units_per_em )
+      if ( !dict->has_font_matrix )
         dict->units_per_em = pure_cff ? 1000 : face->root.units_per_EM;
 
       /* Normalize the font matrix so that `matrix->xx' is 1; the */
@@ -652,26 +652,32 @@
         FT_Fixed    temp;
 
 
-        if ( sub->units_per_em )
+        if ( sub->has_font_matrix )
         {
           FT_Long  scaling;
 
 
-          if ( top->units_per_em > 1 && sub->units_per_em > 1 )
-            scaling = FT_MIN( top->units_per_em, sub->units_per_em );
-          else
-            scaling = 1;
+          /* if we have a top-level matrix, */
+          /* concatenate the subfont matrix */
 
-          FT_Matrix_Multiply_Scaled( &top->font_matrix,
-                                     &sub->font_matrix,
-                                     scaling );
-          FT_Vector_Transform_Scaled( &sub->font_offset,
-                                      &top->font_matrix,
-                                      scaling );
+          if ( top->has_font_matrix )
+          {
+            if ( top->units_per_em > 1 && sub->units_per_em > 1 )
+              scaling = FT_MIN( top->units_per_em, sub->units_per_em );
+            else
+              scaling = 1;
 
-          sub->units_per_em = FT_MulDiv( sub->units_per_em,
-                                         top->units_per_em,
-                                         scaling );
+            FT_Matrix_Multiply_Scaled( &top->font_matrix,
+                                       &sub->font_matrix,
+                                       scaling );
+            FT_Vector_Transform_Scaled( &sub->font_offset,
+                                        &top->font_matrix,
+                                        scaling );
+
+            sub->units_per_em = FT_MulDiv( sub->units_per_em,
+                                           top->units_per_em,
+                                           scaling );
+          }
         }
         else
         {
@@ -690,16 +696,6 @@
         {
           *upm = FT_DivFix( *upm, temp );
 
-          /* if *upm is larger than 100*1000 we divide by 1000 --     */
-          /* this can happen if e.g. there is no top-font FontMatrix  */
-          /* and the subfont FontMatrix already contains the complete */
-          /* scaling for the subfont (see section 5.11 of the PLRM)   */
-
-          /* 100 is a heuristic value */
-
-          if ( *upm > 100L * 1000L )
-            *upm = ( *upm + 500 ) / 1000;
-
           matrix->xx = FT_DivFix( matrix->xx, temp );
           matrix->yx = FT_DivFix( matrix->yx, temp );
           matrix->xy = FT_DivFix( matrix->xy, temp );
diff --git a/src/cff/cffparse.c b/src/cff/cffparse.c
index abe2f2c..5e33677 100644
--- a/src/cff/cffparse.c
+++ b/src/cff/cffparse.c
@@ -460,6 +460,8 @@
 
       error = CFF_Err_Ok;
 
+      dict->has_font_matrix = TRUE;
+
       /* We expect a well-formed font matrix, this is, the matrix elements */
       /* `xx' and `yy' are of approximately the same magnitude.  To avoid  */
       /* loss of precision, we use the magnitude of element `xx' to scale  */
@@ -498,11 +500,13 @@
 
       *upm = power_tens[scaling];
 
-      FT_TRACE4(( " [%f %f %f %f]\n",
+      FT_TRACE4(( " [%f %f %f %f %f %f]\n",
                   (double)matrix->xx / *upm / 65536,
                   (double)matrix->xy / *upm / 65536,
                   (double)matrix->yx / *upm / 65536,
-                  (double)matrix->yy / *upm / 65536 ));
+                  (double)matrix->yy / *upm / 65536,
+                  (double)offset->x  / *upm / 65536,
+                  (double)offset->y  / *upm / 65536 ));
     }
 
   Exit:
diff --git a/src/cff/cfftypes.h b/src/cff/cfftypes.h
index 665ab6f..cae3689 100644
--- a/src/cff/cfftypes.h
+++ b/src/cff/cfftypes.h
@@ -117,6 +117,7 @@
     FT_Int     paint_type;
     FT_Int     charstring_type;
     FT_Matrix  font_matrix;
+    FT_Bool    has_font_matrix;
     FT_ULong   units_per_em;  /* temporarily used as scaling value also */
     FT_Vector  font_offset;
     FT_ULong   unique_id;