Commit 1474f439b54ef1553d0aac57ebde6261f1b2ed81

Werner Lemberg 2008-12-09T06:51:56

Really fix Savannah bug #25010: An SFNT font with neither outlines nor bitmaps can be considered as containing space `glyphs' only. * src/truetype/ttpload.c (tt_face_load_loca): Handle the case where a `glyf' table is missing. * src/truetype/ttgload.c (load_truetype_glyph): Abort if we have no `glyf' table but a non-zero `loca' entry. (tt_loader_init): Handle missing `glyf' table. * src/base/ftobjs.c (FT_Load_Glyph): Undo change 2008-12-05. * src/sfnt/sfobjs.c (sfnt_load_face): A font with neither outlines nor bitmaps is scalable.

diff --git a/ChangeLog b/ChangeLog
index 67f99bb..fa65c7c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2008-12-09  Werner Lemberg  <wl@gnu.org>
+
+	Really fix Savannah bug #25010: An SFNT font with neither outlines
+	nor bitmaps can be considered as containing space `glyphs' only.
+
+	* src/truetype/ttpload.c (tt_face_load_loca): Handle the case where
+	a `glyf' table is missing.
+
+	* src/truetype/ttgload.c (load_truetype_glyph): Abort if we have no
+	`glyf' table but a non-zero `loca' entry.
+	(tt_loader_init): Handle missing `glyf' table.
+
+	* src/base/ftobjs.c (FT_Load_Glyph): Undo change 2008-12-05.
+
+	* src/sfnt/sfobjs.c (sfnt_load_face): A font with neither outlines
+	nor bitmaps is scalable.
+
 2008-12-05  Werner Lemberg  <wl@nu.org>
 
 	* src/autofit/aflatin.c (af_latin_uniranges): Add more ranges.  This
diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c
index e32b934..cb5ed42 100644
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -559,10 +559,6 @@
     if ( !face || !face->size || !face->glyph )
       return FT_Err_Invalid_Face_Handle;
 
-    /* fonts with neither outlines nor bitmaps can be found in PDFs */
-    if ( !FT_IS_SCALABLE( face ) && !FT_HAS_FIXED_SIZES( face ) )
-      return FT_Err_Invalid_Glyph_Index;
-
     /* The validity test for `glyph_index' is performed by the */
     /* font drivers.                                           */
 
diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c
index b469c15..1221fa0 100644
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -1012,6 +1012,10 @@
 
 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
 
+      /* a font with no bitmaps and no outlines is scalable; */
+      /* it has only empty glyphs then                       */
+      if ( !FT_HAS_FIXED_SIZES( root ) && !FT_IS_SCALABLE( root ) )
+        root->face_flags |= FT_FACE_FLAG_SCALABLE;
     }
 
   Exit:
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index 1399181..06e9ccd 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -1245,6 +1245,13 @@
 
     if ( loader->byte_len > 0 )
     {
+      if ( !loader->glyf_offset )
+      {
+        FT_TRACE2(( "no `glyf' table but non-zero `loca' entry!\n" ));
+        error = TT_Err_Invalid_Table;
+        goto Exit;
+      }
+
       error = face->access_glyph_frame( loader, glyph_index,
                                         loader->glyf_offset + offset,
                                         loader->byte_len );
@@ -1840,12 +1847,15 @@
       FT_Error  error = face->goto_table( face, TTAG_glyf, stream, 0 );
 
 
-      if ( error )
+      if ( error == TT_Err_Table_Missing )
+        loader->glyf_offset = 0;
+      else if ( error )
       {
         FT_ERROR(( "TT_Load_Glyph: could not access glyph table\n" ));
         return error;
       }
-      loader->glyf_offset = FT_STREAM_POS();
+      else
+        loader->glyf_offset = FT_STREAM_POS();
     }
 
     /* get face's glyph loader */
@@ -1857,7 +1867,7 @@
       loader->gloader = gloader;
     }
 
-    loader->load_flags    = load_flags;
+    loader->load_flags = load_flags;
 
     loader->face   = (FT_Face)face;
     loader->size   = (FT_Size)size;
diff --git a/src/truetype/ttpload.c b/src/truetype/ttpload.c
index 520fc87..dc538fb 100644
--- a/src/truetype/ttpload.c
+++ b/src/truetype/ttpload.c
@@ -70,7 +70,12 @@
 
     /* we need the size of the `glyf' table for malformed `loca' tables */
     error = face->goto_table( face, TTAG_glyf, stream, &face->glyf_len );
-    if ( error )
+
+    /* it is possible that a font doesn't have a glyf table at all */
+    /* or its size is zero                                         */
+    if ( error == TT_Err_Table_Missing )
+      face->glyf_len = 0;
+    else if ( error )
       goto Exit;
 
     FT_TRACE2(( "Locations " ));
@@ -205,6 +210,9 @@
     /* Anyway, there do exist (malformed) fonts which don't obey    */
     /* this rule, so we are only able to provide an upper bound for */
     /* the size.                                                    */
+    /*                                                              */
+    /* We get (intentionally) a wrong, non-zero result in case the  */
+    /* `glyf' table is missing.                                     */
     if ( pos2 >= pos1 )
       *asize = (FT_UInt)( pos2 - pos1 );
     else