Commit 98d802b83a3e4f6a62ef58dcc2269e199b13a27a

Wu, Chia-I (吳佳一) 2006-01-31T07:01:24

* include/freetype/internal/t1types.h (AFM_FontInfo), src/psaux/afmparse.c, src/tools/test_afm.c: Read `FontBBox', `Ascender', and `Descender' from an AFM. * src/type1/t1afm.c (T1_Read_Metrics): Use the metrics from the AFM. * include/freetype/freetype.h (FT_FaceRec): Mention that fields may be changed after file attachment.

diff --git a/ChangeLog b/ChangeLog
index 7e7a971..3aeffcf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2006-01-31  Chia-I Wu  <b90201047@ntu.edu.tw>
+
+	* include/freetype/internal/t1types.h (AFM_FontInfo),
+	src/psaux/afmparse.c, src/tools/test_afm.c: Read `FontBBox',
+	`Ascender', and `Descender' from an AFM.
+
+	* src/type1/t1afm.c (T1_Read_Metrics): Use the metrics from the AFM.
+
+	* include/freetype/freetype.h (FT_FaceRec): Mention that fields may be
+	changed after file attachment.
+
 2006-01-28  Werner Lemberg  <wl@gnu.org>
 
 	* src/*/module.mk (.PHONY): Add.
diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h
index a079c8c..131a1c5 100644
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -826,11 +826,7 @@ FT_BEGIN_HEADER
   /*                                                                       */
   /*    num_charmaps        :: The number of charmaps in the face.         */
   /*                                                                       */
-  /*    charmaps            :: An array of the charmaps of the face.  The  */
-  /*                           array might change after a call to          */
-  /*                           @FT_Attach_File or @FT_Attach_Stream (e.g., */
-  /*                           if used to hook an additional encoding or   */
-  /*                           CMap to the face object).                   */
+  /*    charmaps            :: An array of the charmaps of the face.       */
   /*                                                                       */
   /*    generic             :: A field reserved for client uses.  See the  */
   /*                           @FT_Generic type description.               */
@@ -895,6 +891,10 @@ FT_BEGIN_HEADER
   /*                                                                       */
   /*    charmap             :: The current active charmap for this face.   */
   /*                                                                       */
+  /* <Note>                                                                */
+  /*   Fields may be changed after a call to @FT_Attach_File or            */
+  /*   @FT_Attach_Stream.                                                  */
+  /*                                                                       */
   typedef struct  FT_FaceRec_
   {
     FT_Long           num_faces;
diff --git a/include/freetype/internal/t1types.h b/include/freetype/internal/t1types.h
index 0a16453..66bf0d9 100644
--- a/include/freetype/internal/t1types.h
+++ b/include/freetype/internal/t1types.h
@@ -163,6 +163,9 @@ FT_BEGIN_HEADER
   typedef struct  AFM_FontInfoRec_
   {
     FT_Bool        IsCIDFont;
+    FT_BBox        FontBBox;
+    FT_Fixed       Ascender;
+    FT_Fixed       Descender;
     AFM_TrackKern  TrackKerns;   /* free if non-NULL */
     FT_Int         NumTrackKern;
     AFM_KernPair   KernPairs;    /* free if non-NULL */
diff --git a/src/psaux/afmparse.c b/src/psaux/afmparse.c
index 33fbded..eae048b 100644
--- a/src/psaux/afmparse.c
+++ b/src/psaux/afmparse.c
@@ -607,6 +607,7 @@
     {
       AFM_ValueRec  shared_vals[5];
       
+
       switch ( afm_tokenize( key, len ) )
       {
       case AFM_TOKEN_TRACKKERN:
@@ -863,6 +864,9 @@
 
     while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 )
     {
+      AFM_ValueRec  shared_vals[4];
+
+
       switch ( afm_tokenize( key, len ) )
       {
       case AFM_TOKEN_METRICSSETS:
@@ -878,16 +882,41 @@
         break;
 
       case AFM_TOKEN_ISCIDFONT:
-        {
-          AFM_ValueRec  shared_vals[1];
-          
+        shared_vals[0].type = AFM_VALUE_TYPE_BOOL;
+        if ( afm_parser_read_vals( parser, shared_vals, 1 ) != 1 )
+          goto Fail;
 
-          shared_vals[0].type = AFM_VALUE_TYPE_BOOL;
-          if ( afm_parser_read_vals( parser, shared_vals, 1 ) != 1 )
-            goto Fail;
+        fi->IsCIDFont = shared_vals[0].u.b;
+        break;
 
-          fi->IsCIDFont = shared_vals[0].u.b;
-        }
+      case AFM_TOKEN_FONTBBOX:
+        shared_vals[0].type = AFM_VALUE_TYPE_FIXED;
+        shared_vals[1].type = AFM_VALUE_TYPE_FIXED;
+        shared_vals[2].type = AFM_VALUE_TYPE_FIXED;
+        shared_vals[3].type = AFM_VALUE_TYPE_FIXED;
+        if ( afm_parser_read_vals( parser, shared_vals, 4 ) != 4 )
+          goto Fail;
+
+        fi->FontBBox.xMin = shared_vals[0].u.f;
+        fi->FontBBox.yMin = shared_vals[1].u.f;
+        fi->FontBBox.xMax = shared_vals[2].u.f;
+        fi->FontBBox.yMax = shared_vals[3].u.f;
+        break;
+
+      case AFM_TOKEN_ASCENDER:
+        shared_vals[0].type = AFM_VALUE_TYPE_FIXED;
+        if ( afm_parser_read_vals( parser, shared_vals, 1 ) != 1 )
+          goto Fail;
+
+        fi->Ascender = shared_vals[0].u.f;
+        break;
+
+      case AFM_TOKEN_DESCENDER:
+        shared_vals[0].type = AFM_VALUE_TYPE_FIXED;
+        if ( afm_parser_read_vals( parser, shared_vals, 1 ) != 1 )
+          goto Fail;
+
+        fi->Descender = shared_vals[0].u.f;
         break;
 
       case AFM_TOKEN_STARTCHARMETRICS:
diff --git a/src/tools/test_afm.c b/src/tools/test_afm.c
index 0056442..40764b9 100644
--- a/src/tools/test_afm.c
+++ b/src/tools/test_afm.c
@@ -1,5 +1,5 @@
 /*
- * gcc -I../../include -o test_afm test_afm.c \
+ * gcc -DFT2_BUILD_LIBRARY -I../../include -o test_afm test_afm.c \
  *     -L../../objs/.libs -lfreetype -lz -static
  */
 #include <ft2build.h>
@@ -15,6 +15,13 @@
     printf( "This AFM is for %sCID font.\n\n",
             ( fi->IsCIDFont ) ? "" : "non-" );
 
+    printf( "FontBBox: %.2f %.2f %.2f %.2f\n", fi->FontBBox.xMin / 65536.,
+                                               fi->FontBBox.yMin / 65536.,
+                                               fi->FontBBox.xMax / 65536.,
+                                               fi->FontBBox.yMax / 65536. );
+    printf( "Ascender: %.2f\n", fi->Ascender / 65536. );
+    printf( "Descender: %.2f\n\n", fi->Descender / 65536. );
+
     if ( fi->NumTrackKern )
       printf( "There are %d sets of track kernings:\n",
               fi->NumTrackKern );
diff --git a/src/type1/t1afm.c b/src/type1/t1afm.c
index e1c98ec..4071fff 100644
--- a/src/type1/t1afm.c
+++ b/src/type1/t1afm.c
@@ -230,6 +230,7 @@
     AFM_ParserRec  parser;
     AFM_FontInfo   fi;
     FT_Error       error = T1_Err_Unknown_File_Format;
+    T1_Font        t1_font = &( (T1_Face)t1_face )->type1;
 
 
     if ( FT_NEW( fi ) )
@@ -241,6 +242,10 @@
       return error;
     }
 
+    fi->FontBBox  = t1_font->font_bbox;
+    fi->Ascender  = t1_font->font_bbox.yMax;
+    fi->Descender = t1_font->font_bbox.yMin;
+
     psaux = (PSAux_Service)( (T1_Face)t1_face )->psaux;
     if ( psaux && psaux->afm_parser_funcs )
     {
@@ -253,7 +258,7 @@
       {
         parser.FontInfo  = fi;
         parser.get_index = t1_get_index;
-        parser.user_data = &( (T1_Face)t1_face )->type1;
+        parser.user_data = t1_font;
 
         error = psaux->afm_parser_funcs->parse( &parser );
         psaux->afm_parser_funcs->done( &parser );
@@ -271,10 +276,23 @@
         error = T1_Read_PFM( t1_face, stream, fi );
     }
 
-    if ( !error && fi->NumKernPair )
+    if ( !error )
     {
-      t1_face->face_flags |= FT_FACE_FLAG_KERNING;
-      ( (T1_Face)t1_face )->afm_data = fi;
+      t1_font->font_bbox = fi->FontBBox;
+
+      t1_face->bbox.xMin =   fi->FontBBox.xMin             >> 16;
+      t1_face->bbox.yMin =   fi->FontBBox.yMin             >> 16;
+      t1_face->bbox.xMax = ( fi->FontBBox.xMax + 0xFFFFU ) >> 16;
+      t1_face->bbox.yMax = ( fi->FontBBox.yMax + 0xFFFFU ) >> 16;
+
+      t1_face->ascender  = ( fi->Ascender  + 0x8000U ) >> 16;
+      t1_face->descender = ( fi->Descender + 0x8000U ) >> 16;
+
+      if ( fi->NumKernPair )
+      {
+        t1_face->face_flags |= FT_FACE_FLAG_KERNING;
+        ( (T1_Face)t1_face )->afm_data = fi;
+      }
     }
 
     FT_FRAME_EXIT();