shithub: freetype+ttf2subf

Download patch

ref: ee3cc2e4fc964e93fd43c723992131f651910c49
parent: 1a5edf7a4f837be07ead65e7a2bbf6eb68a409dd
author: Werner Lemberg <[email protected]>
date: Mon Mar 9 09:13:44 EDT 2009

Fix handling of EBDT formats 8 and 9 (part 2).

This patch fixes the following problems in ttsbit0.c:

. Bitmaps for compound glyphs were never allocated.

. `SBitDecoder' refused to load metrics if some other metrics have
  already been loaded.  This condition certainly makes no sense for
  recursive calls, so I've just disabled it.  Another possibility
  would be resetting `decoder->metrics_loaded' to false before
  loading each composite component.  However, we must restore the
  original metrics after finishing the recursion; otherwise we can
  get a misaligned glyph.

. `tt_sbit_decoder_load_bit_aligned' incorrectly handled `x_pos',
  causing some glyph components to be shifted too far to the right
  (especially noticeable for small sizes).

Note that support for grayscale bitmaps (not necessarily compound) is
completely broken in ttsbit0.c.

* src/sfnt/tt_sbit_decoder_load_metrics: Always load metrics.
(tt_sbit_decoder_load_bit_aligned): Handle `x_pos' correctly in case
of `h == height'.
(tt_sbit_decoder_load_compound): Reset metrics after loading
components.
Allocate bitmap.

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,33 @@
+2009-03-09  Alexey Kryukov  <[email protected]>
+
+	Fix handling of EBDT formats 8 and 9 (part 2).
+
+	This patch fixes the following problems in ttsbit0.c:
+
+	. Bitmaps for compound glyphs were never allocated.
+
+	. `SBitDecoder' refused to load metrics if some other metrics have
+	  already been loaded.  This condition certainly makes no sense for
+	  recursive calls, so I've just disabled it.  Another possibility
+	  would be resetting `decoder->metrics_loaded' to false before
+	  loading each composite component.  However, we must restore the
+	  original metrics after finishing the recursion; otherwise we can
+	  get a misaligned glyph.
+
+	. `tt_sbit_decoder_load_bit_aligned' incorrectly handled `x_pos',
+	  causing some glyph components to be shifted too far to the right
+	  (especially noticeable for small sizes).
+
+	Note that support for grayscale bitmaps (not necessarily compound) is
+	completely broken in ttsbit0.c.
+
+	* src/sfnt/tt_sbit_decoder_load_metrics: Always load metrics.
+	(tt_sbit_decoder_load_bit_aligned): Handle `x_pos' correctly in case
+	of `h == height'.
+	(tt_sbit_decoder_load_compound): Reset metrics after loading
+	components.
+	Allocate bitmap.
+
 2009-03-09  Werner Lemberg  <[email protected]>
 
 	* builds/unix/configure.raw (version_info): Set to 9:20:3.
--- a/src/sfnt/ttsbit0.c
+++ b/src/sfnt/ttsbit0.c
@@ -324,14 +324,11 @@
     if ( p + 5 > limit )
       goto Fail;
 
-    if ( !decoder->metrics_loaded )
-    {
-      metrics->height       = p[0];
-      metrics->width        = p[1];
-      metrics->horiBearingX = (FT_Char)p[2];
-      metrics->horiBearingY = (FT_Char)p[3];
-      metrics->horiAdvance  = p[4];
-    }
+    metrics->height       = p[0];
+    metrics->width        = p[1];
+    metrics->horiBearingX = (FT_Char)p[2];
+    metrics->horiBearingY = (FT_Char)p[3];
+    metrics->horiAdvance  = p[4];
 
     p += 5;
     if ( big )
@@ -339,12 +336,9 @@
       if ( p + 3 > limit )
         goto Fail;
 
-      if ( !decoder->metrics_loaded )
-      {
-        metrics->vertBearingX = (FT_Char)p[0];
-        metrics->vertBearingY = (FT_Char)p[1];
-        metrics->vertAdvance  = p[2];
-      }
+      metrics->vertBearingX = (FT_Char)p[0];
+      metrics->vertBearingY = (FT_Char)p[1];
+      metrics->vertAdvance  = p[2];
 
       p += 3;
     }
@@ -537,9 +531,14 @@
       {
         w = ( width < 8 - x_pos ) ? width : 8 - x_pos;
 
-        if ( nbits < w )
+        if ( h == height )
         {
           rval  |= *p++;
+          nbits += x_pos;
+        }
+        else if ( nbits < w )
+        {
+          rval  |= *p++;
           nbits += 8 - w;
         }
         else
@@ -548,7 +547,8 @@
           nbits  -= w;
         }
 
-        *write++ |= ( ( rval >> nbits ) & 0xFF ) & ~( 0xFF << w );
+        *write++ |= ( ( rval >> nbits ) & 0xFF ) &
+                    ( ~( 0xFF << w ) << ( 8 - w - x_pos ) );
         rval    <<= 8;
 
         w = width - w;
@@ -595,7 +595,14 @@
     FT_Error  error = SFNT_Err_Ok;
     FT_UInt   num_components, nn;
 
+    FT_Char  horiBearingX = decoder->metrics->horiBearingX;
+    FT_Char  horiBearingY = decoder->metrics->horiBearingY;
+    FT_Byte  horiAdvance  = decoder->metrics->horiAdvance;
+    FT_Char  vertBearingX = decoder->metrics->vertBearingX;
+    FT_Char  vertBearingY = decoder->metrics->vertBearingY;
+    FT_Byte  vertAdvance  = decoder->metrics->vertAdvance;
 
+
     if ( p + 2 > limit )
       goto Fail;
 
@@ -603,6 +610,13 @@
     if ( p + 4 * num_components > limit )
       goto Fail;
 
+    if ( !decoder->bitmap_allocated )
+    {
+      error = tt_sbit_decoder_alloc_bitmap( decoder );
+      if ( error )
+        goto Exit;
+    }
+
     for ( nn = 0; nn < num_components; nn++ )
     {
       FT_UInt  gindex = FT_NEXT_USHORT( p );
@@ -616,6 +630,15 @@
       if ( error )
         break;
     }
+
+    decoder->metrics->horiBearingX = horiBearingX;
+    decoder->metrics->horiBearingY = horiBearingY;
+    decoder->metrics->horiAdvance  = horiAdvance;
+    decoder->metrics->vertBearingX = vertBearingX;
+    decoder->metrics->vertBearingY = vertBearingY;
+    decoder->metrics->vertAdvance  = vertAdvance;
+    decoder->metrics->width        = (FT_UInt)decoder->bitmap->width;
+    decoder->metrics->height       = (FT_UInt)decoder->bitmap->rows;
 
   Exit:
     return error;