mirror of
https://gitlab.winehq.org/wine/wine.git
synced 2024-11-19 17:06:04 -07:00
opengl: Avoid infinite recursion in bezier_approximate() in case of degraded curve.
This commit is contained in:
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
1 changed files with 21 additions and 10 deletions
|
@ -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];
|
||||||
|
|
Loading…
Reference in a new issue