opengl: Avoid infinite recursion in bezier_approximate() in case of degraded curve.

This commit is contained in:
Paul Gofman 2024-11-18 19:41:29 -06:00 committed by Alexandre Julliard
parent 245dfb801e
commit eea781a03b
Notes: Alexandre Julliard 2024-11-19 23:21:20 +01:00
Approved-by: Alexandre Julliard (@julliard)
Merge-Request: https://gitlab.winehq.org/wine/wine/merge_requests/6843

View file

@ -1176,7 +1176,7 @@ typedef struct _bezier_vector {
GLdouble y; GLdouble y;
} bezier_vector; } bezier_vector;
static double bezier_deviation_squared(const bezier_vector *p) static BOOL bezier_fits_deviation(const bezier_vector *p, FLOAT max_deviation)
{ {
bezier_vector deviation; bezier_vector deviation;
bezier_vector vertex; bezier_vector vertex;
@ -1184,25 +1184,36 @@ static double bezier_deviation_squared(const bezier_vector *p)
double base_length; double base_length;
double dot; double dot;
max_deviation *= max_deviation;
vertex.x = (p[0].x + p[1].x*2 + p[2].x)/4 - p[0].x; vertex.x = (p[0].x + p[1].x*2 + p[2].x)/4 - p[0].x;
vertex.y = (p[0].y + p[1].y*2 + p[2].y)/4 - p[0].y; vertex.y = (p[0].y + p[1].y*2 + p[2].y)/4 - p[0].y;
base.x = p[2].x - p[0].x; base.x = p[2].x - p[0].x;
base.y = p[2].y - p[0].y; base.y = p[2].y - p[0].y;
base_length = sqrt(base.x*base.x + base.y*base.y); base_length = base.x * base.x + base.y * base.y;
base.x /= base_length; if (base_length <= max_deviation)
base.y /= base_length; {
base.x = 0.0;
base.y = 0.0;
}
else
{
base_length = sqrt(base_length);
base.x /= base_length;
base.y /= base_length;
dot = base.x*vertex.x + base.y*vertex.y; dot = base.x*vertex.x + base.y*vertex.y;
dot = min(max(dot, 0.0), base_length); dot = min(max(dot, 0.0), base_length);
base.x *= dot; base.x *= dot;
base.y *= dot; base.y *= dot;
}
deviation.x = vertex.x-base.x; deviation.x = vertex.x-base.x;
deviation.y = vertex.y-base.y; deviation.y = vertex.y-base.y;
return deviation.x*deviation.x + deviation.y*deviation.y; return deviation.x*deviation.x + deviation.y*deviation.y <= max_deviation;
} }
static int bezier_approximate(const bezier_vector *p, bezier_vector *points, FLOAT deviation) static int bezier_approximate(const bezier_vector *p, bezier_vector *points, FLOAT deviation)
@ -1212,7 +1223,7 @@ static int bezier_approximate(const bezier_vector *p, bezier_vector *points, FLO
bezier_vector vertex; bezier_vector vertex;
int total_vertices; int total_vertices;
if(bezier_deviation_squared(p) <= deviation*deviation) if (bezier_fits_deviation(p, deviation))
{ {
if(points) if(points)
*points = p[2]; *points = p[2];