* src/smooth/ftgrays.c (gray_sweep): Avoid buffer overwrites

when to the end of a bitmap scanline. The fun never ends ;-)
This commit is contained in:
David Turner 2006-09-05 09:45:15 +00:00
parent d1fc7d427b
commit 772e55d38e
2 changed files with 51 additions and 53 deletions

View File

@ -1,3 +1,8 @@
2006-09-05 David Turner <david@freetype.org>
* src/smooth/ftgrays.c (gray_sweep): Avoid buffer overwrites
when to the end of a bitmap scanline. The fun never ends ;-)
2006-09-04 David Turner <david@freetype.org> 2006-09-04 David Turner <david@freetype.org>
* src/smooth/ftgrays.c (gray_convert_glyphs): Make it work with * src/smooth/ftgrays.c (gray_convert_glyphs): Make it work with

View File

@ -381,33 +381,26 @@ typedef struct TCell_
/* */ /* */
/* Record the current cell in the table. */ /* Record the current cell in the table. */
/* */ /* */
static PCell* static PCell
gray_find_cell( RAS_ARG_ TCoord x, gray_find_cell( RAS_ARG_ TCoord x,
TCoord y ) TCoord y )
{ {
PCell *pnode, node; PCell *pcell, cell;
pnode = &ras.ycells[y]; pcell = &ras.ycells[y];
for (;;) for (;;)
{ {
node = *pnode; cell = *pcell;
if ( node == NULL || node->x >= x ) if ( cell == NULL || cell->x > x )
break; break;
pnode = &node->next; if ( cell->x == x )
goto Exit;
pcell = &cell->next;
} }
return pnode;
}
static PCell
gray_alloc_cell( RAS_ARG_ TCoord x )
{
PCell cell;
if ( ras.num_cells >= ras.max_cells ) if ( ras.num_cells >= ras.max_cells )
ft_longjmp( ras.jump_buffer, 1 ); ft_longjmp( ras.jump_buffer, 1 );
@ -416,6 +409,10 @@ typedef struct TCell_
cell->area = 0; cell->area = 0;
cell->cover = 0; cell->cover = 0;
cell->next = *pcell;
*pcell = cell;
Exit:
return cell; return cell;
} }
@ -423,19 +420,11 @@ typedef struct TCell_
static void static void
gray_record_cell( RAS_ARG ) gray_record_cell( RAS_ARG )
{ {
if ( !ras.invalid && ( ras.area | ras.cover ) ) if ( !ras.invalid && (ras.area | ras.cover) )
{ {
TCoord x = (TCoord)( ras.ex - ras.min_ex ); TCoord x = (TCoord)( ras.ex - ras.min_ex );
TCoord y = (TCoord)( ras.ey - ras.min_ey ); TCoord y = (TCoord)( ras.ey - ras.min_ey );
PCell *pparent = gray_find_cell( RAS_VAR_ x, y ); PCell cell = gray_find_cell( RAS_VAR_ x, y );
PCell cell = *pparent;
if ( cell == NULL || cell->x != x )
{
cell = gray_alloc_cell( RAS_VAR_ x );
cell->next = *pparent;
*pparent = cell;
}
cell->area += ras.area; cell->area += ras.area;
cell->cover += ras.cover; cell->cover += ras.cover;
@ -464,37 +453,23 @@ typedef struct TCell_
/* Note that if a cell is to the left of the clipping region, it is */ /* Note that if a cell is to the left of the clipping region, it is */
/* actually set to the (min_ex-1) horizontal position. */ /* actually set to the (min_ex-1) horizontal position. */
record = 0; /* All cells that are on the left of the clipping region go to the */
clean = 1; /* min_ex - 1 horizontal position. */
if ( ex < ras.min_ex )
ex = (TCoord)(ras.min_ex - 1);
invalid = ( ey < ras.min_ey || ey >= ras.max_ey || ex >= ras.max_ex ); /* are we moving to a different cell ? */
if ( !invalid ) if ( ex != ras.ex || ey != ras.ey )
{ {
/* All cells that are on the left of the clipping region go to the */ /* record the current one if it is valid */
/* min_ex - 1 horizontal position. */ if ( !ras.invalid )
if ( ex < ras.min_ex ) gray_record_cell( RAS_VAR );
ex = (TCoord)(ras.min_ex - 1);
/* if our position is new, then record the previous cell */
if ( ex != ras.ex || ey != ras.ey )
record = 1;
else
clean = ras.invalid; /* do not clean if we didn't move from */
/* a valid cell */
}
/* record the previous cell if needed (i.e., if we changed the cell */
/* position, or changed the `invalid' flag) */
if ( ras.invalid != invalid || record )
gray_record_cell( RAS_VAR );
if ( clean )
{
ras.area = 0; ras.area = 0;
ras.cover = 0; ras.cover = 0;
} }
ras.invalid = invalid; ras.invalid = ( ey < ras.min_ey || ey >= ras.max_ey || ex >= ras.max_ex );
ras.ex = ex; ras.ex = ex;
ras.ey = ey; ras.ey = ey;
} }
@ -1248,6 +1223,24 @@ typedef struct TCell_
} }
#if 1
gray_dump_cells( RAS_ARG )
{
int yindex;
for ( yindex = 0; yindex < ras.ycount; yindex++ )
{
PCell cell;
printf( "%3d:", yindex );
for ( cell = ras.ycells[yindex]; cell != NULL; cell = cell->next )
printf( " (%3d, c:%4d, a:%6d)", cell->x, cell->cover, cell->area );
printf( "\n" );
}
}
#endif
static void static void
gray_sweep( RAS_ARG_ const FT_Bitmap* target ) gray_sweep( RAS_ARG_ const FT_Bitmap* target )
{ {
@ -1288,7 +1281,7 @@ typedef struct TCell_
if ( cover != 0 ) if ( cover != 0 )
gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ), gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ),
ras.max_ex - x ); (ras.max_ex - ras.min_ex) - x );
} }
if ( ras.render_span && ras.num_gray_spans > 0 ) if ( ras.render_span && ras.num_gray_spans > 0 )