* src/smooth/ftgrays.c (gray_sweep): Avoid buffer overwrites when to the end of a bitmap scanline. The fun never ends ;-)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
diff --git a/ChangeLog b/ChangeLog
index ef5e34d..ab3762a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
* src/smooth/ftgrays.c (gray_convert_glyphs): Make it work with
diff --git a/src/smooth/ftgrays.c b/src/smooth/ftgrays.c
index 08b797e..bb590c6 100644
--- a/src/smooth/ftgrays.c
+++ b/src/smooth/ftgrays.c
@@ -381,32 +381,25 @@ typedef struct TCell_
/* */
/* Record the current cell in the table. */
/* */
- static PCell*
+ static PCell
gray_find_cell( RAS_ARG_ TCoord x,
TCoord y )
{
- PCell *pnode, node;
+ PCell *pcell, cell;
- pnode = &ras.ycells[y];
+ pcell = &ras.ycells[y];
for (;;)
{
- node = *pnode;
- if ( node == NULL || node->x >= x )
+ cell = *pcell;
+ if ( cell == NULL || cell->x > x )
break;
- pnode = &node->next;
- }
-
- return pnode;
- }
-
-
- static PCell
- gray_alloc_cell( RAS_ARG_ TCoord x )
- {
- PCell cell;
+ if ( cell->x == x )
+ goto Exit;
+ pcell = &cell->next;
+ }
if ( ras.num_cells >= ras.max_cells )
ft_longjmp( ras.jump_buffer, 1 );
@@ -416,6 +409,10 @@ typedef struct TCell_
cell->area = 0;
cell->cover = 0;
+ cell->next = *pcell;
+ *pcell = cell;
+
+ Exit:
return cell;
}
@@ -423,19 +420,11 @@ typedef struct TCell_
static void
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 y = (TCoord)( ras.ey - ras.min_ey );
- PCell *pparent = 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;
- }
+ TCoord x = (TCoord)( ras.ex - ras.min_ex );
+ TCoord y = (TCoord)( ras.ey - ras.min_ey );
+ PCell cell = gray_find_cell( RAS_VAR_ x, y );
cell->area += ras.area;
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 */
/* actually set to the (min_ex-1) horizontal position. */
- record = 0;
- clean = 1;
+ /* All cells that are on the left of the clipping region go to the */
+ /* 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 );
- if ( !invalid )
+ /* are we moving to a different cell ? */
+ if ( ex != ras.ex || ey != ras.ey )
{
- /* All cells that are on the left of the clipping region go to the */
- /* min_ex - 1 horizontal position. */
- if ( ex < ras.min_ex )
- 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 current one if it is valid */
+ if ( !ras.invalid )
+ gray_record_cell( RAS_VAR );
- /* 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.cover = 0;
}
- ras.invalid = invalid;
+ ras.invalid = ( ey < ras.min_ey || ey >= ras.max_ey || ex >= ras.max_ex );
ras.ex = ex;
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
gray_sweep( RAS_ARG_ const FT_Bitmap* target )
{
@@ -1288,7 +1281,7 @@ typedef struct TCell_
if ( cover != 0 )
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 )