diff --git a/ChangeLog b/ChangeLog index 3b9d7065d..6e7569007 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,33 @@ +2009-03-09 Alexey Kryukov + + 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 * builds/unix/configure.raw (version_info): Set to 9:20:3. diff --git a/src/sfnt/ttsbit0.c b/src/sfnt/ttsbit0.c index ae468f0a3..3ebcbbd74 100644 --- 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,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;