bugThe FreeType Project - Bugs: bug #19327, FT_Bitmap_Embolden crops...

 
 

bug #19327: FT_Bitmap_Embolden crops monochrome bitmaps

Submitted by:  Simon Botond <tequiia>
Submitted on:  Fri 16 Mar 2007 07:32:24 PM UTC  
 
Severity: 3 - NormalItem Group: Incorrect behaviour
Status: FixedPrivacy: Public
Assigned to: David Turner <freetype>Open/Closed: Closed
Planned Release: 2.3.4

Add a New Comment(Rich Markup)
   

You are not logged in

Please log in, so followups can be emailed to you.

 

Thu 12 Apr 2007 02:01:18 PM UTC, comment #1:

Hi,

The 2.3.4 release solved the issues with the cropped bitmaps. Thanks!

What I want to note: for monochrome bitmaps only the last bytes are cleared now, the unused bits from the last used byte are left untouched. My fix cleared those bits, too. It was a bit of overkill probably, because it wrote into memory too many times because of that.

Thanks for your help!

Boti

Simon Botond <tequiia>
Fri 16 Mar 2007 07:32:24 PM UTC, original submission:

To reproduce the issue call FT_Embolden_Bitmap(library, bitmap, 7*64, 0) on a monochrome bitmap. It's most visible on round letters, ex. 'o' or 'e'. In the resulting bitmap the right edge of the letters appear cropped.

For example lets consider that we loaded and rendered the letter 'l' and it's bitmap looks the following way:

... ... ...
0xff 0xfe 0x00
0xff 0xfe 0x00
0xff 0xfe 0x00
0xff 0xfe 0x00
0xff 0xfe 0x00
0xff 0xfe 0x00
... ... ...

width = 15 pitch = 3 ppb = 8

Now we call FT_Embolden_Bitmap(library, bitmap, 7*64, 0) to embolden it. We'll end up in ft_bitmap_assure_bitmap_buffer() at the following code (lines 136 -> 165):

/* if no need to allocate memory */
if ( ypixels == 0 && pitch * ppb >= bitmap->width + xpixels )
{
/* zero the padding */
for ( i = 0; i < bitmap->rows; i++ )
{
unsigned char* last_byte;
int bits = xpixels * ( 8 / ppb );
int mask = 0;

last_byte = bitmap->buffer + i * pitch + ( bitmap->width - 1 ) / ppb;

if ( bits >= 8 )
{
FT_MEM_ZERO( last_byte + 1, bits / 8 );
bits %= 8;
}

if ( bits > 0 )
{
while ( bits-- > 0 )
mask |= 1 << bits;

*last_byte &= ~mask;
}
}

return FT_Err_Ok;
}

What happens now:
last_byte = bitmap->buffer + i * pitch + 1;
The while loop will clear the last 7 bits from last_byte !! That will erase the last 6 valid pixels from our bitmap. That will be done on every single row. And before the embolding begins our bitmap will look as:

... ... ...
0xff 0x80 0x00
0xff 0x80 0x00
0xff 0x80 0x00
0xff 0x80 0x00
0xff 0x80 0x00
... ... ...

To address this I modified the above code to this:

/* if no need to allocate memory */
if ( ypixels == 0 && pitch * ppb >= bitmap->width + xpixels )
{
/* zero the padding */
for ( i = 0; i < bitmap->rows; i++ )
{
if ( ppb == 1 )
{
unsigned char* last_byte;

last_byte = bitmap->buffer + i * pitch + bitmap->width - 1;
FT_MEM_ZERO( last_byte + 1, xpixels );
}
else
{

unsigned char* first_byte = bitmap->buffer + i * pitch;
int bits = xpixels * ( 8 / ppb );

for (j = 0; j < bits; j++)
{
unsigned char* crt_byte;
int crt_bit;
int mask;

crt_byte = first_byte + (bitmap->width + j) / 8;
crt_bit = (bitmap->width + j) % 8;
mask = 1 << (7 - crt_bit);
*crt_byte &= ~mask;
}
}
}

return FT_Err_Ok;
}

This seems to solve the problem with the cropping. The code for the monochrome bitmaps probably could be optimized to minimize the number of memory writes.

Simon Botond <tequiia>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach File(s):
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -unavailable- added by wl (Updated the item)
  • -unavailable- added by tequiia (Submitted the item)
  •  

    Do you think this task is very important?
    If so, you can click here to add your encouragement to it.
    This task has 0 encouragements so far.

    Only logged-in users can vote.

     

    Please enter the title of George Orwell's famous dystopian book (it's a date):

     

     

    Follow 4 latest changes.

    Date Changed By Updated Field Previous Value => Replaced By
    Fri 06 Apr 2007 09:29:18 AM UTCwlStatusNone=>Fixed
      Open/ClosedOpen=>Closed
      Planned ReleaseNone=>2.3.4
    Fri 16 Mar 2007 11:53:08 PM UTCwlAssigned toNone=>freetype

    Back to the top


    Powered by Savane 3.1-cleanup1