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.
This commit is contained in:
Werner Lemberg 2009-03-09 13:13:44 +00:00
parent 1a5edf7a4f
commit ee3cc2e4fc
2 changed files with 69 additions and 16 deletions

@ -1,3 +1,33 @@
2009-03-09 Alexey Kryukov <anagnost@yandex.ru>
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 <wl@gnu.org>
* builds/unix/configure.raw (version_info): Set to 9:20:3.

@ -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,7 +531,12 @@
{
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;
@ -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,6 +595,13 @@
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 );
@ -617,6 +631,15 @@
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;