freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[freetype2] master b45043c: [sfnt, truetype] Improve handling of missing


From: Werner LEMBERG
Subject: [freetype2] master b45043c: [sfnt, truetype] Improve handling of missing sbits.
Date: Fri, 11 Aug 2017 03:35:19 -0400 (EDT)

branch: master
commit b45043c44030337c1f7006f8c3d19fdfffe541f6
Author: Werner Lemberg <address@hidden>
Commit: Werner Lemberg <address@hidden>

    [sfnt, truetype] Improve handling of missing sbits.
    
    Requested by Behdad.
    
    Modern bitmap-only SFNTs like `NotoColorEmoji.ttf' don't contain
    entries in the bitmap strike(s) for empty glyphs.  Instead, they
    rely that a space glyph gets created from the font's metrics data.
    This commit makes FreeType behave accordingly.
    
    * include/freetype/fterrdef.h (FT_Err_Missing_Bitmap): New error
    code.
    
    * src/sfnt/ttsbit.c (tt_sbit_decoder_load_image): Change error codes
    to make a distinction between a missing bitmap in a composite and a
    simple missing bitmap.
    
    * src/truetype/ttgload.c (TT_Load_Glyph): For a missing bitmap (in a
    bitmap-only font), synthesize an empty bitmap glyph if metrics are
    available.
---
 ChangeLog                   | 22 ++++++++++++++++++
 include/freetype/fterrdef.h |  2 ++
 src/sfnt/ttsbit.c           | 11 +++++++--
 src/truetype/ttgload.c      | 55 +++++++++++++++++++++++++++++++++++++++++++--
 4 files changed, 86 insertions(+), 4 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 7fc94e7..4091498 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2017-08-11  Werner Lemberg  <address@hidden>
+
+       [sfnt, truetype] Improve handling of missing sbits.
+
+       Requested by Behdad.
+
+       Modern bitmap-only SFNTs like `NotoColorEmoji.ttf' don't contain
+       entries in the bitmap strike(s) for empty glyphs.  Instead, they
+       rely that a space glyph gets created from the font's metrics data.
+       This commit makes FreeType behave accordingly.
+
+       * include/freetype/fterrdef.h (FT_Err_Missing_Bitmap): New error
+       code.
+
+       * src/sfnt/ttsbit.c (tt_sbit_decoder_load_image): Change error codes
+       to make a distinction between a missing bitmap in a composite and a
+       simple missing bitmap.
+
+       * src/truetype/ttgload.c (TT_Load_Glyph): For a missing bitmap (in a
+       bitmap-only font), synthesize an empty bitmap glyph if metrics are
+       available.
+
 2017-08-10  Werner Lemberg  <address@hidden>
 
        [base] Minor API improvement for default variation axis setting.
diff --git a/include/freetype/fterrdef.h b/include/freetype/fterrdef.h
index cabbac8..6a6dc85 100644
--- a/include/freetype/fterrdef.h
+++ b/include/freetype/fterrdef.h
@@ -233,6 +233,8 @@
                 "invalid PostScript (post) table" )
   FT_ERRORDEF_( DEF_In_Glyf_Bytecode,                        0x9C,
                 "found FDEF or IDEF opcode in glyf bytecode" )
+  FT_ERRORDEF_( Missing_Bitmap,                              0x9D,
+                "missing bitmap in strike" )
 
   /* CFF, CID, and Type 1 errors */
 
diff --git a/src/sfnt/ttsbit.c b/src/sfnt/ttsbit.c
index 59b2168..f41847b 100644
--- a/src/sfnt/ttsbit.c
+++ b/src/sfnt/ttsbit.c
@@ -1448,10 +1448,17 @@
     return FT_THROW( Invalid_Table );
 
   NoBitmap:
+    if ( recurse_count )
+    {
+      FT_TRACE4(( "tt_sbit_decoder_load_image:"
+                  " missing subglyph sbit with glyph index %d\n",
+                  glyph_index ));
+      return FT_THROW( Invalid_Composite );
+    }
+
     FT_TRACE4(( "tt_sbit_decoder_load_image:"
                 " no sbit found for glyph index %d\n", glyph_index ));
-
-    return FT_THROW( Invalid_Argument );
+    return FT_THROW( Missing_Bitmap );
   }
 
 
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index bfda761..5e102c6 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -87,7 +87,7 @@
   /*************************************************************************/
   /*                                                                       */
   /* Return the vertical metrics in font units for a given glyph.          */
-  /* See macro `TT_LOADER_SET_PP' below for explanations.                  */
+  /* See function `tt_loader_set_pp' below for explanations.               */
   /*                                                                       */
   FT_LOCAL_DEF( void )
   TT_Get_VMetrics( TT_Face     face,
@@ -2625,7 +2625,58 @@
          IS_DEFAULT_INSTANCE                     )
     {
       error = load_sbit_image( size, glyph, glyph_index, load_flags );
-      if ( error )
+      if ( FT_ERR_EQ( error, Missing_Bitmap ) )
+      {
+        /* the bitmap strike is incomplete and misses the requested glyph; */
+        /* if we have a bitmap-only font, return an empty glyph            */
+        if ( !FT_IS_SCALABLE( glyph->face ) )
+        {
+          TT_Face    face = (TT_Face)glyph->face;
+          FT_Short   left_bearing = 0, top_bearing = 0;
+          FT_UShort  advance_width = 0, advance_height = 0;
+
+
+          /* to return an empty glyph, however, we need metrics data   */
+          /* from the `hmtx' (or `vmtx') table; the assumption is that */
+          /* empty glyphs are missing intentionally, representing      */
+          /* whitespace - not having at least horizontal metrics is    */
+          /* thus considered an error                                  */
+          if ( !face->horz_metrics_size )
+            return error;
+
+          /* we now construct an empty bitmap glyph */
+          TT_Get_HMetrics( face, glyph_index,
+                           &left_bearing,
+                           &advance_width );
+          TT_Get_VMetrics( face, glyph_index,
+                           0,
+                           &top_bearing,
+                           &advance_height );
+
+          glyph->outline.n_points   = 0;
+          glyph->outline.n_contours = 0;
+
+          glyph->metrics.width  = 0;
+          glyph->metrics.height = 0;
+
+          glyph->metrics.horiBearingX = left_bearing;
+          glyph->metrics.horiBearingY = 0;
+          glyph->metrics.horiAdvance  = advance_width;
+
+          glyph->metrics.vertBearingX = 0;
+          glyph->metrics.vertBearingY = top_bearing;
+          glyph->metrics.vertAdvance  = advance_height;
+
+          glyph->format            = FT_GLYPH_FORMAT_BITMAP;
+          glyph->bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
+
+          glyph->bitmap_left = 0;
+          glyph->bitmap_top  = 0;
+
+          return FT_Err_Ok;
+        }
+      }
+      else if ( error )
       {
         /* return error if font is not scalable */
         if ( !FT_IS_SCALABLE( glyph->face ) )



reply via email to

[Prev in Thread] Current Thread [Next in Thread]