Bug 579356: Limit recursion in CalcBezLength for SVG path length-calculation. r=dholbert a=blocking

This commit is contained in:
Robert Longson 2010-08-05 07:53:43 -07:00
Родитель 0ebb139424
Коммит b36609721b
1 изменённых файлов: 18 добавлений и 5 удалений

Просмотреть файл

@ -51,6 +51,10 @@ struct PathPoint {
// Error threshold to use when calculating the length of Bezier curves // Error threshold to use when calculating the length of Bezier curves
static const float PATH_SEG_LENGTH_TOLERANCE = 0.0000001f; static const float PATH_SEG_LENGTH_TOLERANCE = 0.0000001f;
//----------------------------------------------------------------------
// Maximum recursion limit for length calculation
static const PRUint32 MAX_STEPS = 10;
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// implementation helper macros // implementation helper macros
@ -122,8 +126,9 @@ static void SplitCubicBezier(PathPoint *curve,
left[3].y = right[0].y = (left[2].y + right[1].y) / 2; left[3].y = right[0].y = (left[2].y + right[1].y) / 2;
} }
static float CalcBezLength(PathPoint *curve,PRUint32 numPts, static float CalcBezLengthHelper(PathPoint *curve, PRUint32 numPts,
void (*split)(PathPoint*, PathPoint*, PathPoint*)) PRUint32 steps,
void (*split)(PathPoint*, PathPoint*, PathPoint*))
{ {
PathPoint left[4]; PathPoint left[4];
PathPoint right[4]; PathPoint right[4];
@ -134,14 +139,22 @@ static float CalcBezLength(PathPoint *curve,PRUint32 numPts,
} }
dist = GetDistance(curve[0].x, curve[numPts - 1].x, dist = GetDistance(curve[0].x, curve[numPts - 1].x,
curve[0].y, curve[numPts - 1].y); curve[0].y, curve[numPts - 1].y);
if (length - dist > PATH_SEG_LENGTH_TOLERANCE) { if (length - dist > PATH_SEG_LENGTH_TOLERANCE && steps < MAX_STEPS) {
split(curve, left, right); split(curve, left, right);
return CalcBezLength(left, numPts, split) + ++steps;
CalcBezLength(right, numPts, split); return CalcBezLengthHelper(left, numPts, steps, split) +
CalcBezLengthHelper(right, numPts, steps, split);
} }
return length; return length;
} }
static inline float CalcBezLength(PathPoint *curve, PRUint32 numPts,
void (*split)(PathPoint*, PathPoint*, PathPoint*))
{
return CalcBezLengthHelper(curve, numPts, 0, split);
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// nsSVGPathSeg // nsSVGPathSeg