mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-10 02:40:11 +00:00
path: Recognize circles when parsing
We can look out for the tell-tale M-O-O-O-O-Z and turn it into a circle contour.
This commit is contained in:
parent
0fce24674a
commit
b8a3d7fa00
@ -953,6 +953,78 @@ parse_command (const char **p,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_string (const char **p,
|
||||
const char *s)
|
||||
{
|
||||
int len = strlen (s);
|
||||
if (strncmp (*p, s, len) != 0)
|
||||
return FALSE;
|
||||
(*p) += len;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_circle (const char **p,
|
||||
double *cx,
|
||||
double *cy,
|
||||
double *r)
|
||||
{
|
||||
const char *o = *p;
|
||||
double x0, y0, x1, y1, x2, y2, x3, y3;
|
||||
double x4, y4, x5, y5, x6, y6, x7, y7;
|
||||
double x8, y8, w0, w1, w2, w3;
|
||||
double xx, yy;
|
||||
|
||||
if (parse_coordinate_pair (p, &x0, &y0) &&
|
||||
parse_string (p, "O") &&
|
||||
parse_coordinate_pair (p, &x1, &y1) &&
|
||||
parse_coordinate_pair (p, &x2, &y2) &&
|
||||
parse_nonnegative_number (p, &w0) &&
|
||||
parse_string (p, "O") &&
|
||||
parse_coordinate_pair (p, &x3, &y3) &&
|
||||
parse_coordinate_pair (p, &x4, &y4) &&
|
||||
parse_nonnegative_number (p, &w1) &&
|
||||
parse_string (p, "O") &&
|
||||
parse_coordinate_pair (p, &x5, &y5) &&
|
||||
parse_coordinate_pair (p, &x6, &y6) &&
|
||||
parse_nonnegative_number (p, &w2) &&
|
||||
parse_string (p, "O") &&
|
||||
parse_coordinate_pair (p, &x7, &y7) &&
|
||||
parse_coordinate_pair (p, &x8, &y8) &&
|
||||
parse_nonnegative_number (p, &w3) &&
|
||||
parse_string (p, "Z"))
|
||||
{
|
||||
xx = (x0 + x4) / 2;
|
||||
yy = (y2 + y6) / 2;
|
||||
|
||||
#define NEAR(x, y) (fabs ((x) - (y)) < 0.001)
|
||||
|
||||
if (NEAR (x0, x1) && NEAR (x0, x8) && NEAR (x0, x7) &&
|
||||
NEAR (x2, x6) && NEAR (x3, x4) && NEAR (x4, x5) &&
|
||||
NEAR (y5, y6) && NEAR (y6, y7) && NEAR (y4, y8) &&
|
||||
NEAR (y8, y0) && NEAR (y3, y2) && NEAR (y2, y1) &&
|
||||
NEAR (x2, xx) && NEAR (yy, y4) &&
|
||||
NEAR (w0, M_SQRT1_2) && NEAR (w1, M_SQRT1_2) &&
|
||||
NEAR (w2, M_SQRT1_2) && NEAR (w3, M_SQRT1_2) &&
|
||||
x1 > x2 && x2 > x3 && y3 > y4 && y4 > y5)
|
||||
{
|
||||
*cx = xx;
|
||||
*cy = yy;
|
||||
*r = x0 - xx;
|
||||
|
||||
skip_whitespace (p);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#undef NEAR
|
||||
}
|
||||
|
||||
*p = o;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_path_parse:
|
||||
* @string: a string
|
||||
@ -1037,9 +1109,20 @@ gsk_path_parse (const char *string)
|
||||
case 'M':
|
||||
case 'm':
|
||||
{
|
||||
double x1, y1;
|
||||
double x1, y1, r;
|
||||
|
||||
if (parse_coordinate_pair (&p, &x1, &y1))
|
||||
if (parse_circle (&p, &x1, &y1, &r))
|
||||
{
|
||||
gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (x1, y1), r);
|
||||
if (_strchr ("zZX", prev_cmd))
|
||||
{
|
||||
path_x = x1 + r;
|
||||
path_y = y1;
|
||||
}
|
||||
x = x1 + r;
|
||||
y = y1;
|
||||
}
|
||||
else if (parse_coordinate_pair (&p, &x1, &y1))
|
||||
{
|
||||
if (cmd == 'm')
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user