Revert to signed span positioning. In the context of FT_Outline_Render, the outline can be placed arbitrarily and the resulting spans should be signed. This partially reverts ef04e4eb2056 and fixes #1410. However, for internal use, when outlines are placed in the first quadrant, we still can interpret positions as unsigned. * include/freetype/ftimage.h (FT_Span): Use signed position again. * src/smooth/ftgrays.c (gray_sweep_direct): Sync with FT_Span. * src/smooth/ftsmooth.c (ft_smooth_lcd_spans, ft_smooth_lcdv_spans, ft_smooth_overlap_spans): Prevent sign extension.
diff --git a/include/freetype/ftimage.h b/include/freetype/ftimage.h index 1fff76b..7c41912 100644 --- a/include/freetype/ftimage.h +++ b/include/freetype/ftimage.h
@@ -875,7 +875,7 @@ */ typedef struct FT_Span_ { - unsigned short x; + short x; unsigned short len; unsigned char coverage;
diff --git a/src/smooth/ftgrays.c b/src/smooth/ftgrays.c index b77687f..53948d2 100644 --- a/src/smooth/ftgrays.c +++ b/src/smooth/ftgrays.c
@@ -1805,7 +1805,7 @@ FT_FILL_RULE( coverage, cover, fill ); span[n].coverage = (unsigned char)coverage; - span[n].x = (unsigned short)x; + span[n].x = (short)x; span[n].len = (unsigned short)( cell->x - x ); if ( ++n == FT_MAX_GRAY_SPANS ) @@ -1824,7 +1824,7 @@ FT_FILL_RULE( coverage, area, fill ); span[n].coverage = (unsigned char)coverage; - span[n].x = (unsigned short)cell->x; + span[n].x = (short)cell->x; span[n].len = 1; if ( ++n == FT_MAX_GRAY_SPANS )
diff --git a/src/smooth/ftsmooth.c b/src/smooth/ftsmooth.c index 25c1e5e..f5a3de6 100644 --- a/src/smooth/ftsmooth.c +++ b/src/smooth/ftsmooth.c
@@ -124,7 +124,8 @@ for ( ; count--; spans++ ) - for ( dst = dst_line + spans->x * 3, w = spans->len; w--; dst += 3 ) + for ( dst = dst_line + (unsigned short)spans->x * 3, + w = spans->len; w--; dst += 3 ) *dst = spans->coverage; } @@ -290,7 +291,8 @@ for ( ; count--; spans++ ) - for ( dst = dst_line + spans->x, w = spans->len; w--; dst++ ) + for ( dst = dst_line + (unsigned short)spans->x, + w = spans->len; w--; dst++ ) { dst[0] += ( spans->coverage * target->wght[0] + 85 ) >> 8; dst[1] += ( spans->coverage * target->wght[1] + 85 ) >> 8; @@ -385,7 +387,8 @@ for ( ; count--; spans++ ) - for ( dst = dst_line + spans->x, w = spans->len; w--; dst++ ) + for ( dst = dst_line + (unsigned short)spans->x, + w = spans->len; w--; dst++ ) { dst[ 0] += ( spans->coverage * target->wght[0] + 85 ) >> 8; dst[ pitch] += ( spans->coverage * target->wght[1] + 85 ) >> 8; @@ -473,7 +476,7 @@ unsigned char* dst = target->origin - ( y / SCALE ) * target->pitch; - unsigned short x; + unsigned int x, i; unsigned int cover, sum; @@ -487,8 +490,9 @@ cover = ( spans->coverage + SCALE * SCALE / 2 ) / ( SCALE * SCALE ); for ( x = 0; x < spans->len; x++ ) { - sum = dst[( spans->x + x ) / SCALE] + cover; - dst[( spans->x + x ) / SCALE] = (unsigned char)( sum - ( sum >> 8 ) ); + i = ( (unsigned short)spans->x + x ) / SCALE; + sum = dst[i] + cover; + dst[i] = (unsigned char)( sum - ( sum >> 8 ) ); } } }