Use unsigned point and contour indexing in FT_Outline
.
This doubles the number or allowed points, see https://github.com/harfbuzz/harfbuzz/issues/4752 Although it is hardly practical to use more than 32767 points, other font engines seem to support it. * docs/CHANGES: Announce it. * include/freetype/ftimage.h (FT_Outline): Do it and update limits. * src/*: Update `FT_Outline` users.
This commit is contained in:
parent
2b9fdec5fa
commit
2a7bb4596f
12
docs/CHANGES
12
docs/CHANGES
@ -1,13 +1,21 @@
|
||||
CHANGES BETWEEN 2.13.2 and 2.13.3 (2024-Mmm-DD)
|
||||
|
||||
I. IMPORTANT BUG FIXES
|
||||
I. IMPORTANT CHANGES
|
||||
|
||||
- Some fields in the `FT_Outline` structure have been changed
|
||||
from signed to unsigned type, which better reflects the actual
|
||||
usage. It is also an additional means to protect against
|
||||
malformed input.
|
||||
|
||||
|
||||
II. IMPORTANT BUG FIXES
|
||||
|
||||
- Rare double-free crashes in the cache subsystem have been fixed.
|
||||
|
||||
- Excessive stack allocation in the autohinter has been fixed.
|
||||
|
||||
|
||||
II. MISCELLANEOUS
|
||||
III. MISCELLANEOUS
|
||||
|
||||
- The B/W rasterizer has received a major upkeep that resulted in
|
||||
large performance improvement. The rendering speed has increased
|
||||
|
@ -345,14 +345,14 @@ FT_BEGIN_HEADER
|
||||
*/
|
||||
typedef struct FT_Outline_
|
||||
{
|
||||
short n_contours; /* number of contours in glyph */
|
||||
short n_points; /* number of points in the glyph */
|
||||
unsigned short n_contours; /* number of contours in glyph */
|
||||
unsigned short n_points; /* number of points in the glyph */
|
||||
|
||||
FT_Vector* points; /* the outline's points */
|
||||
char* tags; /* the points flags */
|
||||
short* contours; /* the contour end points */
|
||||
FT_Vector* points; /* the outline's points */
|
||||
char* tags; /* the points flags */
|
||||
unsigned short* contours; /* the contour end points */
|
||||
|
||||
int flags; /* outline masks */
|
||||
int flags; /* outline masks */
|
||||
|
||||
} FT_Outline;
|
||||
|
||||
@ -360,8 +360,8 @@ FT_BEGIN_HEADER
|
||||
|
||||
/* Following limits must be consistent with */
|
||||
/* FT_Outline.{n_contours,n_points} */
|
||||
#define FT_OUTLINE_CONTOURS_MAX SHRT_MAX
|
||||
#define FT_OUTLINE_POINTS_MAX SHRT_MAX
|
||||
#define FT_OUTLINE_CONTOURS_MAX USHRT_MAX
|
||||
#define FT_OUTLINE_POINTS_MAX USHRT_MAX
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
|
@ -1655,9 +1655,9 @@ FT_BEGIN_HEADER
|
||||
{
|
||||
FT_Memory memory;
|
||||
FT_UShort max_points;
|
||||
FT_Short max_contours;
|
||||
FT_UShort max_contours;
|
||||
FT_UShort n_points; /* number of points in zone */
|
||||
FT_Short n_contours; /* number of contours */
|
||||
FT_UShort n_contours; /* number of contours */
|
||||
|
||||
FT_Vector* org; /* original point coordinates */
|
||||
FT_Vector* cur; /* current point coordinates */
|
||||
|
@ -980,7 +980,7 @@
|
||||
{
|
||||
FT_Vector* vec = outline->points;
|
||||
char* tag = outline->tags;
|
||||
FT_Short endpoint = outline->contours[0];
|
||||
FT_UShort endpoint = outline->contours[0];
|
||||
AF_Point end = points + endpoint;
|
||||
AF_Point prev = end;
|
||||
FT_Int contour_index = 0;
|
||||
@ -1046,10 +1046,10 @@
|
||||
|
||||
/* set up the contours array */
|
||||
{
|
||||
AF_Point* contour = hints->contours;
|
||||
AF_Point* contour_limit = contour + hints->num_contours;
|
||||
short* end = outline->contours;
|
||||
FT_Int idx = 0;
|
||||
AF_Point* contour = hints->contours;
|
||||
AF_Point* contour_limit = contour + hints->num_contours;
|
||||
FT_UShort* end = outline->contours;
|
||||
FT_Int idx = 0;
|
||||
|
||||
|
||||
for ( ; contour < contour_limit; contour++, end++ )
|
||||
|
@ -489,7 +489,7 @@
|
||||
return FT_THROW( Invalid_Outline );
|
||||
|
||||
/* if outline is empty, return (0,0,0,0) */
|
||||
if ( outline->n_points == 0 || outline->n_contours <= 0 )
|
||||
if ( outline->n_points == 0 || outline->n_contours == 0 )
|
||||
{
|
||||
abbox->xMin = abbox->xMax = 0;
|
||||
abbox->yMin = abbox->yMax = 0;
|
||||
|
@ -332,8 +332,8 @@
|
||||
FT_NEW_ARRAY( anoutline->contours, numContours ) )
|
||||
goto Fail;
|
||||
|
||||
anoutline->n_points = (FT_Short)numPoints;
|
||||
anoutline->n_contours = (FT_Short)numContours;
|
||||
anoutline->n_points = (FT_UShort)numPoints;
|
||||
anoutline->n_contours = (FT_UShort)numContours;
|
||||
anoutline->flags |= FT_OUTLINE_OWNER;
|
||||
|
||||
return FT_Err_Ok;
|
||||
@ -359,12 +359,14 @@
|
||||
FT_Int n;
|
||||
|
||||
|
||||
FT_TRACE5(( "FT_Outline_Check: contours = %d, points = %d\n",
|
||||
n_contours, n_points ));
|
||||
/* empty glyph? */
|
||||
if ( n_points == 0 && n_contours == 0 )
|
||||
return FT_Err_Ok;
|
||||
|
||||
/* check point and contour counts */
|
||||
if ( n_points <= 0 || n_contours <= 0 )
|
||||
if ( n_points == 0 || n_contours == 0 )
|
||||
goto Bad;
|
||||
|
||||
end0 = -1;
|
||||
|
@ -727,10 +727,10 @@
|
||||
|
||||
/* copy contours */
|
||||
{
|
||||
FT_UInt count = border->num_points;
|
||||
FT_Byte* tags = border->tags;
|
||||
FT_Short* write = outline->contours + outline->n_contours;
|
||||
FT_Short idx = (FT_Short)outline->n_points;
|
||||
FT_UInt count = border->num_points;
|
||||
FT_Byte* tags = border->tags;
|
||||
FT_UShort* write = outline->contours + outline->n_contours;
|
||||
FT_UShort idx = outline->n_points;
|
||||
|
||||
|
||||
for ( ; count > 0; count--, tags++, idx++ )
|
||||
@ -743,7 +743,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
outline->n_points += (short)border->num_points;
|
||||
outline->n_points += (FT_UShort)border->num_points;
|
||||
|
||||
FT_ASSERT( FT_Outline_Check( outline ) == 0 );
|
||||
}
|
||||
|
@ -108,7 +108,7 @@
|
||||
|
||||
/* don't add empty contours */
|
||||
if ( last >= first )
|
||||
outline->contours[outline->n_contours++] = (short)last;
|
||||
outline->contours[outline->n_contours++] = (FT_UShort)last;
|
||||
|
||||
glyph->path_begun = 0;
|
||||
}
|
||||
|
@ -1171,8 +1171,8 @@
|
||||
FT_QNEW_ARRAY( glyph->contours, outline->n_contours ) )
|
||||
goto Exit;
|
||||
|
||||
glyph->num_points = (FT_UInt)outline->n_points;
|
||||
glyph->num_contours = (FT_UInt)outline->n_contours;
|
||||
glyph->num_points = outline->n_points;
|
||||
glyph->num_contours = outline->n_contours;
|
||||
|
||||
{
|
||||
FT_UInt first = 0, next, n;
|
||||
@ -1186,7 +1186,7 @@
|
||||
PSH_Point point;
|
||||
|
||||
|
||||
next = (FT_UInt)outline->contours[n] + 1;
|
||||
next = outline->contours[n] + 1;
|
||||
count = next - first;
|
||||
|
||||
contour->start = points + first;
|
||||
|
@ -2683,7 +2683,7 @@
|
||||
return FT_THROW( Invalid_Outline );
|
||||
|
||||
/* return immediately if the outline is empty */
|
||||
if ( outline->n_points == 0 || outline->n_contours <= 0 )
|
||||
if ( outline->n_points == 0 || outline->n_contours == 0 )
|
||||
return Raster_Err_Ok;
|
||||
|
||||
if ( !outline->contours || !outline->points )
|
||||
|
@ -3837,7 +3837,7 @@
|
||||
}
|
||||
|
||||
/* if the outline is empty, return */
|
||||
if ( outline->n_points <= 0 || outline->n_contours <= 0 )
|
||||
if ( outline->n_points == 0 || outline->n_contours == 0 )
|
||||
goto Exit;
|
||||
|
||||
/* check whether the outline has valid fields */
|
||||
|
@ -1981,7 +1981,7 @@ typedef ptrdiff_t FT_PtrDist;
|
||||
return FT_THROW( Invalid_Outline );
|
||||
|
||||
/* return immediately if the outline is empty */
|
||||
if ( outline->n_points == 0 || outline->n_contours <= 0 )
|
||||
if ( outline->n_points == 0 || outline->n_contours == 0 )
|
||||
return Smooth_Err_Ok;
|
||||
|
||||
if ( !outline->contours || !outline->points )
|
||||
|
@ -353,7 +353,8 @@
|
||||
FT_Byte c, count;
|
||||
FT_Vector *vec, *vec_limit;
|
||||
FT_Pos x, y;
|
||||
FT_Short *cont, *cont_limit, last;
|
||||
FT_UShort *cont, *cont_limit;
|
||||
FT_Int last;
|
||||
|
||||
|
||||
/* check that we can add the contours to the glyph */
|
||||
@ -372,7 +373,7 @@
|
||||
last = -1;
|
||||
for ( ; cont < cont_limit; cont++ )
|
||||
{
|
||||
*cont = FT_NEXT_SHORT( p );
|
||||
*cont = FT_NEXT_USHORT( p );
|
||||
|
||||
if ( *cont <= last )
|
||||
goto Invalid_Outline;
|
||||
@ -530,8 +531,8 @@
|
||||
*flag = (FT_Byte)( f & ON_CURVE_POINT );
|
||||
}
|
||||
|
||||
outline->n_points = (FT_Short)n_points;
|
||||
outline->n_contours = (FT_Short)n_contours;
|
||||
outline->n_points = (FT_UShort)n_points;
|
||||
outline->n_contours = (FT_UShort)n_contours;
|
||||
|
||||
load->cursor = p;
|
||||
|
||||
@ -752,10 +753,8 @@
|
||||
FT_UInt start_point,
|
||||
FT_UInt start_contour )
|
||||
{
|
||||
zone->n_points = (FT_UShort)load->outline.n_points + 4 -
|
||||
(FT_UShort)start_point;
|
||||
zone->n_contours = load->outline.n_contours -
|
||||
(FT_Short)start_contour;
|
||||
zone->n_points = load->outline.n_points + 4 - (FT_UShort)start_point;
|
||||
zone->n_contours = load->outline.n_contours - (FT_UShort)start_contour;
|
||||
zone->org = load->extra_points + start_point;
|
||||
zone->cur = load->outline.points + start_point;
|
||||
zone->orus = load->extra_points2 + start_point;
|
||||
@ -1044,7 +1043,7 @@
|
||||
current.points = gloader->base.outline.points +
|
||||
num_base_points;
|
||||
current.n_points = gloader->base.outline.n_points -
|
||||
(short)num_base_points;
|
||||
(FT_UShort)num_base_points;
|
||||
|
||||
have_scale = FT_BOOL( subglyph->flags & ( WE_HAVE_A_SCALE |
|
||||
WE_HAVE_AN_XY_SCALE |
|
||||
@ -1057,7 +1056,7 @@
|
||||
/* get offset */
|
||||
if ( !( subglyph->flags & ARGS_ARE_XY_VALUES ) )
|
||||
{
|
||||
FT_UInt num_points = (FT_UInt)gloader->base.outline.n_points;
|
||||
FT_UInt num_points = gloader->base.outline.n_points;
|
||||
FT_UInt k = (FT_UInt)subglyph->arg1;
|
||||
FT_UInt l = (FT_UInt)subglyph->arg2;
|
||||
FT_Vector* p1;
|
||||
@ -1719,8 +1718,8 @@
|
||||
FT_List_Add( &loader->composites, node );
|
||||
}
|
||||
|
||||
start_point = (FT_UInt)gloader->base.outline.n_points;
|
||||
start_contour = (FT_UInt)gloader->base.outline.n_contours;
|
||||
start_point = gloader->base.outline.n_points;
|
||||
start_contour = gloader->base.outline.n_contours;
|
||||
|
||||
/* for each subglyph, read composite header */
|
||||
error = face->read_composite_glyph( loader );
|
||||
@ -1872,7 +1871,7 @@
|
||||
linear_hadvance = loader->linear;
|
||||
linear_vadvance = loader->vadvance;
|
||||
|
||||
num_base_points = (FT_UInt)gloader->base.outline.n_points;
|
||||
num_base_points = gloader->base.outline.n_points;
|
||||
|
||||
error = load_truetype_glyph( loader,
|
||||
(FT_UInt)subglyph->index,
|
||||
@ -1896,7 +1895,7 @@
|
||||
loader->vadvance = linear_vadvance;
|
||||
}
|
||||
|
||||
num_points = (FT_UInt)gloader->base.outline.n_points;
|
||||
num_points = gloader->base.outline.n_points;
|
||||
|
||||
if ( num_points == num_base_points )
|
||||
continue;
|
||||
@ -2717,7 +2716,7 @@
|
||||
size->metrics->y_ppem < 24 )
|
||||
glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
|
||||
|
||||
FT_TRACE1(( " subglyphs = %u, contours = %hd, points = %hd,"
|
||||
FT_TRACE1(( " subglyphs = %u, contours = %hu, points = %hu,"
|
||||
" flags = 0x%.3x\n",
|
||||
loader.gloader->base.num_subglyphs,
|
||||
glyph->outline.n_contours,
|
||||
|
@ -5270,11 +5270,11 @@
|
||||
FT_UShort refp;
|
||||
FT_F26Dot6 dx, dy;
|
||||
|
||||
FT_Short contour, bounds;
|
||||
FT_UShort contour, bounds;
|
||||
FT_UShort start, limit, i;
|
||||
|
||||
|
||||
contour = (FT_Short)args[0];
|
||||
contour = (FT_UShort)args[0];
|
||||
bounds = ( exc->GS.gep2 == 0 ) ? 1 : exc->zp2.n_contours;
|
||||
|
||||
if ( BOUNDS( contour, bounds ) )
|
||||
@ -5290,15 +5290,13 @@
|
||||
if ( contour == 0 )
|
||||
start = 0;
|
||||
else
|
||||
start = (FT_UShort)( exc->zp2.contours[contour - 1] + 1 -
|
||||
exc->zp2.first_point );
|
||||
start = exc->zp2.contours[contour - 1] + 1 - exc->zp2.first_point;
|
||||
|
||||
/* we use the number of points if in the twilight zone */
|
||||
if ( exc->GS.gep2 == 0 )
|
||||
limit = exc->zp2.n_points;
|
||||
else
|
||||
limit = (FT_UShort)( exc->zp2.contours[contour] -
|
||||
exc->zp2.first_point + 1 );
|
||||
limit = exc->zp2.contours[contour] + 1 - exc->zp2.first_point;
|
||||
|
||||
for ( i = start; i < limit; i++ )
|
||||
{
|
||||
@ -5341,9 +5339,9 @@
|
||||
/* Normal zone's `n_points' includes phantoms, so must */
|
||||
/* use end of last contour. */
|
||||
if ( exc->GS.gep2 == 0 )
|
||||
limit = (FT_UShort)exc->zp2.n_points;
|
||||
limit = exc->zp2.n_points;
|
||||
else if ( exc->GS.gep2 == 1 && exc->zp2.n_contours > 0 )
|
||||
limit = (FT_UShort)( exc->zp2.contours[exc->zp2.n_contours - 1] + 1 );
|
||||
limit = exc->zp2.contours[exc->zp2.n_contours - 1] + 1;
|
||||
else
|
||||
limit = 0;
|
||||
|
||||
|
@ -115,7 +115,7 @@
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
tt_glyphzone_new( FT_Memory memory,
|
||||
FT_UShort maxPoints,
|
||||
FT_Short maxContours,
|
||||
FT_UShort maxContours,
|
||||
TT_GlyphZone zone )
|
||||
{
|
||||
FT_Error error;
|
||||
|
@ -105,7 +105,7 @@ FT_BEGIN_HEADER
|
||||
FT_LOCAL( FT_Error )
|
||||
tt_glyphzone_new( FT_Memory memory,
|
||||
FT_UShort maxPoints,
|
||||
FT_Short maxContours,
|
||||
FT_UShort maxContours,
|
||||
TT_GlyphZone zone );
|
||||
|
||||
#endif /* TT_USE_BYTECODE_INTERPRETER */
|
||||
|
Loading…
Reference in New Issue
Block a user