freetype-commit
[Top][All Lists]
Advanced

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

[freetype2] master 37e193e 1/5: Introduce a way of quickly retrieving (e


From: Werner LEMBERG
Subject: [freetype2] master 37e193e 1/5: Introduce a way of quickly retrieving (embedded) bitmap metrics.
Date: Sun, 6 Nov 2016 11:47:13 +0000 (UTC)

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

    Introduce a way of quickly retrieving (embedded) bitmap metrics.
    
    `FT_Load_Glyph' doesn't generate a bitmap for a non-bitmap glyph
    until the user calls `FT_Render_Glyph'.  However, it always
    allocates memory for bitmaps and copies or decodes the contents of a
    bitmap glyph, which can be quite slow for PNG data.
    
    * include/freetype/freetype.h (FT_LOAD_BITMAP_METRICS_ONLY): New
    macro.
    
    * src/base/ftobjs.c (FT_Load_Glyph): Unset FT_LOAD_RENDER if
    FT_LOAD_BITMAP_METRICS_ONLY is used.
    
    * src/sfnt/ttsbit.c (tt_sbit_decoder_alloc_bitmap,
    tt_sbit_decoder_load_bitmap): Add argument to control allocation of
    the glyph slot.
    (tt_sbit_decoder_load_image, tt_sbit_decoder_load_compound,
    tt_face_load_sbit_image): Updated.
    
    * src/pcf/pcfdrivr.c (PCF_Glyph_Load): Quickly exit if
    `FT_LOAD_BITMAP_METRICS_ONLY' is set.
    
    * src/pfr/pfrsbit.c, src/pfr/pfrsbit.h (pfr_slot_load_bitmap): Add
    argument to control allocation of the glyph slot.
    * src/pfr/pfrobjs (pfr_slot_load): Updated.
    
    * src/winfonts/winfnt.c (FNT_Load_Glyph): Ditto.
    
    * docs/CHANGES: Updated.
---
 ChangeLog                   |   35 +++++++++++++++++++++++++++++++-
 docs/CHANGES                |    3 +++
 include/freetype/freetype.h |    9 +++++++++
 src/base/ftobjs.c           |    3 +++
 src/pcf/pcfdrivr.c          |   35 ++++++++++++++++----------------
 src/pfr/pfrobjs.c           |    6 +++++-
 src/pfr/pfrsbit.c           |    6 +++++-
 src/pfr/pfrsbit.h           |    3 ++-
 src/sfnt/ttsbit.c           |   47 +++++++++++++++++++++++++++++--------------
 src/winfonts/winfnt.c       |   44 +++++++++++++++++++++-------------------
 10 files changed, 134 insertions(+), 57 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 881d23e..cbe5a20 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,37 @@
-2016-10-29  Werner Lemberg  <address@hidden>
+2016-11-06  Seigo Nonaka  <address@hidden>
+           Werner Lemberg  <address@hidden>
+
+       Introduce a way of quickly retrieving (embedded) bitmap metrics.
+
+       `FT_Load_Glyph' doesn't generate a bitmap for a non-bitmap glyph
+       until the user calls `FT_Render_Glyph'.  However, it always
+       allocates memory for bitmaps and copies or decodes the contents of a
+       bitmap glyph, which can be quite slow for PNG data.
+
+       * include/freetype/freetype.h (FT_LOAD_BITMAP_METRICS_ONLY): New
+       macro.
+
+       * src/base/ftobjs.c (FT_Load_Glyph): Unset FT_LOAD_RENDER if
+       FT_LOAD_BITMAP_METRICS_ONLY is used.
+
+       * src/sfnt/ttsbit.c (tt_sbit_decoder_alloc_bitmap,
+       tt_sbit_decoder_load_bitmap): Add argument to control allocation of
+       the glyph slot.
+       (tt_sbit_decoder_load_image, tt_sbit_decoder_load_compound,
+       tt_face_load_sbit_image): Updated.
+
+       * src/pcf/pcfdrivr.c (PCF_Glyph_Load): Quickly exit if
+       `FT_LOAD_BITMAP_METRICS_ONLY' is set.
+
+       * src/pfr/pfrsbit.c, src/pfr/pfrsbit.h (pfr_slot_load_bitmap): Add
+       argument to control allocation of the glyph slot.
+       * src/pfr/pfrobjs (pfr_slot_load): Updated.
+
+       * src/winfonts/winfnt.c (FNT_Load_Glyph): Ditto.
+
+       * docs/CHANGES: Updated.
+
+2016-11-06  Werner Lemberg  <address@hidden>
 
        Synchronize with gnulib (#49448).
 
diff --git a/docs/CHANGES b/docs/CHANGES
index 25e2740..5b50fa2 100644
--- a/docs/CHANGES
+++ b/docs/CHANGES
@@ -37,6 +37,9 @@ CHANGES BETWEEN 2.7 and 2.7.1
       blend  coordinates of the currently  selected variation instance
       has been added to the Multiple Masters interface.
 
+    - A new load flag `FT_LOAD_BITMAP_METRICS_ONLY' to retrieve bitmap
+      information without loading the (embedded) bitmap itself.
+
 
 ======================================================================
 
diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h
index a81eb72..49aa6f1 100644
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -2802,6 +2802,14 @@ FT_BEGIN_HEADER
    *
    *     Currently, this flag is only implemented for TrueType fonts.
    *
+   *   FT_LOAD_BITMAP_METRICS_ONLY ::
+   *     This flag is used to request loading of the metrics and bitmap
+   *     image information of a (possibly embedded) bitmap glyph without
+   *     allocating or copying the bitmap image data itself.  No effect if
+   *     the target glyph is not a bitmap image.
+   *
+   *     This flag unsets @FT_LOAD_RENDER.
+   *
    *   FT_LOAD_CROP_BITMAP ::
    *     Ignored.  Deprecated.
    *
@@ -2848,6 +2856,7 @@ FT_BEGIN_HEADER
   /* Bits 16..19 are used by `FT_LOAD_TARGET_' */
 #define FT_LOAD_COLOR                        ( 1L << 20 )
 #define FT_LOAD_COMPUTE_METRICS              ( 1L << 21 )
+#define FT_LOAD_BITMAP_METRICS_ONLY          ( 1L << 22 )
 
   /* */
 
diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c
index 9006b59..060d78e 100644
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -641,6 +641,9 @@
       load_flags &= ~FT_LOAD_RENDER;
     }
 
+    if ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY )
+      load_flags &= ~FT_LOAD_RENDER;
+
     /*
      * Determine whether we need to auto-hint or not.
      * The general rules are:
diff --git a/src/pcf/pcfdrivr.c b/src/pcf/pcfdrivr.c
index a0db807..476882f 100644
--- a/src/pcf/pcfdrivr.c
+++ b/src/pcf/pcfdrivr.c
@@ -492,8 +492,6 @@ THE SOFTWARE.
     PCF_Metric  metric;
     FT_ULong    bytes;
 
-    FT_UNUSED( load_flags );
-
 
     FT_TRACE1(( "PCF_Glyph_Load: glyph index %d\n", glyph_index ));
 
@@ -550,6 +548,24 @@ THE SOFTWARE.
       return FT_THROW( Invalid_File_Format );
     }
 
+    slot->format      = FT_GLYPH_FORMAT_BITMAP;
+    slot->bitmap_left = metric->leftSideBearing;
+    slot->bitmap_top  = metric->ascent;
+
+    slot->metrics.horiAdvance  = (FT_Pos)( metric->characterWidth * 64 );
+    slot->metrics.horiBearingX = (FT_Pos)( metric->leftSideBearing * 64 );
+    slot->metrics.horiBearingY = (FT_Pos)( metric->ascent * 64 );
+    slot->metrics.width        = (FT_Pos)( ( metric->rightSideBearing -
+                                             metric->leftSideBearing ) * 64 );
+    slot->metrics.height       = (FT_Pos)( bitmap->rows * 64 );
+
+    ft_synthesize_vertical_metrics( &slot->metrics,
+                                    ( face->accel.fontAscent +
+                                      face->accel.fontDescent ) * 64 );
+
+    if ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY )
+      goto Exit;
+
     /* XXX: to do: are there cases that need repadding the bitmap? */
     bytes = (FT_ULong)bitmap->pitch * bitmap->rows;
 
@@ -582,21 +598,6 @@ THE SOFTWARE.
       }
     }
 
-    slot->format      = FT_GLYPH_FORMAT_BITMAP;
-    slot->bitmap_left = metric->leftSideBearing;
-    slot->bitmap_top  = metric->ascent;
-
-    slot->metrics.horiAdvance  = (FT_Pos)( metric->characterWidth * 64 );
-    slot->metrics.horiBearingX = (FT_Pos)( metric->leftSideBearing * 64 );
-    slot->metrics.horiBearingY = (FT_Pos)( metric->ascent * 64 );
-    slot->metrics.width        = (FT_Pos)( ( metric->rightSideBearing -
-                                             metric->leftSideBearing ) * 64 );
-    slot->metrics.height       = (FT_Pos)( bitmap->rows * 64 );
-
-    ft_synthesize_vertical_metrics( &slot->metrics,
-                                    ( face->accel.fontAscent +
-                                      face->accel.fontDescent ) * 64 );
-
   Exit:
     return error;
   }
diff --git a/src/pfr/pfrobjs.c b/src/pfr/pfrobjs.c
index 769a3b6..06996d6 100644
--- a/src/pfr/pfrobjs.c
+++ b/src/pfr/pfrobjs.c
@@ -342,7 +342,11 @@
     /* try to load an embedded bitmap */
     if ( ( load_flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP ) ) == 0 )
     {
-      error = pfr_slot_load_bitmap( slot, size, gindex );
+      error = pfr_slot_load_bitmap(
+                slot,
+                size,
+                gindex,
+                ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY ) != 0 );
       if ( error == 0 )
         goto Exit;
     }
diff --git a/src/pfr/pfrsbit.c b/src/pfr/pfrsbit.c
index 144f50c..f9dbf73 100644
--- a/src/pfr/pfrsbit.c
+++ b/src/pfr/pfrsbit.c
@@ -578,7 +578,8 @@
   FT_LOCAL( FT_Error )
   pfr_slot_load_bitmap( PFR_Slot  glyph,
                         PFR_Size  size,
-                        FT_UInt   glyph_index )
+                        FT_UInt   glyph_index,
+                        FT_Bool   metrics_only )
   {
     FT_Error     error;
     PFR_Face     face   = (PFR_Face) glyph->root.face;
@@ -775,6 +776,9 @@
         glyph->root.bitmap_left = (FT_Int)xpos;
         glyph->root.bitmap_top  = (FT_Int)( ypos + (FT_Long)ysize );
 
+        if ( metrics_only )
+          goto Exit1;
+
         /* Allocate and read bitmap data */
         {
           FT_ULong  len = (FT_ULong)glyph->root.bitmap.pitch * ysize;
diff --git a/src/pfr/pfrsbit.h b/src/pfr/pfrsbit.h
index 94ead28..676ad55 100644
--- a/src/pfr/pfrsbit.h
+++ b/src/pfr/pfrsbit.h
@@ -26,7 +26,8 @@ FT_BEGIN_HEADER
   FT_LOCAL( FT_Error )
   pfr_slot_load_bitmap( PFR_Slot  glyph,
                         PFR_Size  size,
-                        FT_UInt   glyph_index );
+                        FT_UInt   glyph_index,
+                        FT_Bool   metrics_only );
 
 FT_END_HEADER
 
diff --git a/src/sfnt/ttsbit.c b/src/sfnt/ttsbit.c
index b5986aa..8d8b9e7 100644
--- a/src/sfnt/ttsbit.c
+++ b/src/sfnt/ttsbit.c
@@ -536,7 +536,8 @@
 
 
   static FT_Error
-  tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder  decoder )
+  tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder  decoder,
+                                FT_Bool         metrics_only )
   {
     FT_Error    error = FT_Err_Ok;
     FT_UInt     width, height;
@@ -599,6 +600,9 @@
     if ( size == 0 )
       goto Exit;     /* exit successfully! */
 
+    if ( metrics_only )
+      goto Exit;     /* only metrics are requested */
+
     error = ft_glyphslot_alloc_bitmap( decoder->face->root.glyph, size );
     if ( error )
       goto Exit;
@@ -665,7 +669,8 @@
                               FT_UInt         glyph_index,
                               FT_Int          x_pos,
                               FT_Int          y_pos,
-                              FT_UInt         recurse_count );
+                              FT_UInt         recurse_count,
+                              FT_Bool         metrics_only );
 
   typedef FT_Error  (*TT_SBitDecoder_LoadFunc)(
                       TT_SBitDecoder  decoder,
@@ -995,7 +1000,9 @@
                                           gindex,
                                           x_pos + dx,
                                           y_pos + dy,
-                                          recurse_count + 1 );
+                                          recurse_count + 1,
+                                          /* request full bitmap image */
+                                          FALSE );
       if ( error )
         break;
     }
@@ -1077,7 +1084,8 @@
                                FT_ULong        glyph_size,
                                FT_Int          x_pos,
                                FT_Int          y_pos,
-                               FT_UInt         recurse_count )
+                               FT_UInt         recurse_count,
+                               FT_Bool         metrics_only )
   {
     FT_Error   error;
     FT_Stream  stream = decoder->stream;
@@ -1199,11 +1207,15 @@
 
       if ( !decoder->bitmap_allocated )
       {
-        error = tt_sbit_decoder_alloc_bitmap( decoder );
+        error = tt_sbit_decoder_alloc_bitmap( decoder, metrics_only );
+
         if ( error )
           goto Fail;
       }
 
+      if ( metrics_only )
+        goto Fail; /* this is not an error */
+
       error = loader( decoder, p, p_limit, x_pos, y_pos, recurse_count );
     }
 
@@ -1220,7 +1232,8 @@
                               FT_UInt         glyph_index,
                               FT_Int          x_pos,
                               FT_Int          y_pos,
-                              FT_UInt         recurse_count )
+                              FT_UInt         recurse_count,
+                              FT_Bool         metrics_only )
   {
     FT_Byte*  p          = decoder->eblc_base + decoder->strike_index_array;
     FT_Byte*  p_limit    = decoder->eblc_limit;
@@ -1405,7 +1418,8 @@
                                         image_end,
                                         x_pos,
                                         y_pos,
-                                        recurse_count );
+                                        recurse_count,
+                                        metrics_only );
 
   Failure:
     return FT_THROW( Invalid_Table );
@@ -1567,11 +1581,13 @@
         error = tt_sbit_decoder_init( decoder, face, strike_index, metrics );
         if ( !error )
         {
-          error = tt_sbit_decoder_load_image( decoder,
-                                              glyph_index,
-                                              0,
-                                              0,
-                                              0 );
+          error = tt_sbit_decoder_load_image(
+                    decoder,
+                    glyph_index,
+                    0,
+                    0,
+                    0,
+                    ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY ) != 0 );
           tt_sbit_decoder_done( decoder );
         }
       }
@@ -1592,9 +1608,10 @@
     }
 
     /* Flatten color bitmaps if color was not requested. */
-    if ( !error                                &&
-         !( load_flags & FT_LOAD_COLOR )       &&
-         map->pixel_mode == FT_PIXEL_MODE_BGRA )
+    if ( !error                                        &&
+         !( load_flags & FT_LOAD_COLOR )               &&
+         !( load_flags & FT_LOAD_BITMAP_METRICS_ONLY ) &&
+         map->pixel_mode == FT_PIXEL_MODE_BGRA         )
     {
       FT_Bitmap   new_map;
       FT_Library  library = face->root.glyph->library;
diff --git a/src/winfonts/winfnt.c b/src/winfonts/winfnt.c
index b412f10..99cc966 100644
--- a/src/winfonts/winfnt.c
+++ b/src/winfonts/winfnt.c
@@ -1000,8 +1000,6 @@
     FT_ULong    offset;
     FT_Bool     new_format;
 
-    FT_UNUSED( load_flags );
-
 
     if ( !face )
     {
@@ -1055,6 +1053,26 @@
       goto Exit;
     }
 
+    bitmap->rows       = font->header.pixel_height;
+    bitmap->pixel_mode = FT_PIXEL_MODE_MONO;
+
+    slot->bitmap_left     = 0;
+    slot->bitmap_top      = font->header.ascent;
+    slot->format          = FT_GLYPH_FORMAT_BITMAP;
+
+    /* now set up metrics */
+    slot->metrics.width        = (FT_Pos)( bitmap->width << 6 );
+    slot->metrics.height       = (FT_Pos)( bitmap->rows << 6 );
+    slot->metrics.horiAdvance  = (FT_Pos)( bitmap->width << 6 );
+    slot->metrics.horiBearingX = 0;
+    slot->metrics.horiBearingY = slot->bitmap_top << 6;
+
+    ft_synthesize_vertical_metrics( &slot->metrics,
+                                    (FT_Pos)( bitmap->rows << 6 ) );
+
+    if ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY )
+      goto Exit;
+
     /* jump to glyph data */
     p = font->fnt_frame + /* font->header.bits_offset */ + offset;
 
@@ -1066,10 +1084,7 @@
       FT_Byte*   write;
 
 
-      bitmap->pitch      = (int)pitch;
-      bitmap->rows       = font->header.pixel_height;
-      bitmap->pixel_mode = FT_PIXEL_MODE_MONO;
-
+      bitmap->pitch = (int)pitch;
       if ( !pitch                                                 ||
            offset + pitch * bitmap->rows > font->header.file_size )
       {
@@ -1093,22 +1108,9 @@
         for ( write = column; p < limit; p++, write += bitmap->pitch )
           *write = *p;
       }
-    }
 
-    slot->internal->flags = FT_GLYPH_OWN_BITMAP;
-    slot->bitmap_left     = 0;
-    slot->bitmap_top      = font->header.ascent;
-    slot->format          = FT_GLYPH_FORMAT_BITMAP;
-
-    /* now set up metrics */
-    slot->metrics.width        = (FT_Pos)( bitmap->width << 6 );
-    slot->metrics.height       = (FT_Pos)( bitmap->rows << 6 );
-    slot->metrics.horiAdvance  = (FT_Pos)( bitmap->width << 6 );
-    slot->metrics.horiBearingX = 0;
-    slot->metrics.horiBearingY = slot->bitmap_top << 6;
-
-    ft_synthesize_vertical_metrics( &slot->metrics,
-                                    (FT_Pos)( bitmap->rows << 6 ) );
+      slot->internal->flags = FT_GLYPH_OWN_BITMAP;
+    }
 
   Exit:
     return error;



reply via email to

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