efl: simplify the enum to only use Cubic Bezier curve.

So SVG support all kind of primitive, but really they are just sugar
on top of the simpler cubic bezier curve. Let's simplify our backend
by just supporting them and the simple line. We still provide all
the sugar, but via helper function that do convert to the right
number of Bezier curve.
This commit is contained in:
Cedric BAIL 2015-04-03 16:23:07 +02:00
parent 4248bc2870
commit 5bb35d5598
4 changed files with 244 additions and 305 deletions

View File

@ -45,165 +45,6 @@ struct _Ector_Renderer_Cairo_Shape_Data
cairo_path_t *path;
};
// This function come from librsvg rsvg-path.c
static void
_ector_arc_segment(Eo *obj, cairo_t* ctx,
double xc, double yc,
double th0, double th1, double rx, double ry,
double x_axis_rotation)
{
double x1, y1, x2, y2, x3, y3;
double t;
double th_half;
double f, sinf, cosf;
f = x_axis_rotation * M_PI / 180.0;
sinf = sin(f);
cosf = cos(f);
th_half = 0.5 * (th1 - th0);
t = (8.0 / 3.0) * sin(th_half * 0.5) * sin(th_half * 0.5) / sin(th_half);
x1 = rx * (cos(th0) - t * sin(th0));
y1 = ry * (sin(th0) + t * cos(th0));
x3 = rx* cos(th1);
y3 = ry* sin(th1);
x2 = x3 + rx * (t * sin(th1));
y2 = y3 + ry * (-t * cos(th1));
USE(obj, cairo_curve_to, );
cairo_curve_to(ctx,
xc + cosf * x1 - sinf * y1,
yc + sinf * x1 + cosf * y1,
xc + cosf * x2 - sinf * y2,
yc + sinf * x2 + cosf * y2,
xc + cosf * x3 - sinf * y3,
yc + sinf * x3 + cosf * y3);
}
// This function come from librsvg rsvg-path.c
static void
_ector_arc_to(Eo *obj, cairo_t* ctx,
double *current_x, double *current_y,
double rx, double ry, double x_axis_rotation,
Eina_Bool large_arc_flag, Eina_Bool sweep_flag,
double x, double y)
{
/* See Appendix F.6 Elliptical arc implementation notes
http://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes */
double f, sinf, cosf;
double x1, y1, x2, y2;
double x1_, y1_;
double cx_, cy_, cx, cy;
double gamma;
double theta1, delta_theta;
double k1, k2, k3, k4, k5;
int i, n_segs;
/* Start and end of path segment */
x1 = *current_x;
y1 = *current_y;
x2 = x;
y2 = y;
if (x1 == x2 && y1 == y2)
return;
/* X-axis */
f = x_axis_rotation * M_PI / 180.0;
sinf = sin(f);
cosf = cos(f);
/* Check the radius against floading point underflow.
See http://bugs.debian.org/508443 */
if ((fabs(rx) < DBL_EPSILON) || (fabs(ry) < DBL_EPSILON)) {
USE(obj, cairo_line_to, );
cairo_line_to(ctx, x, y);
*current_x = x;
*current_y = y;
return;
}
if (rx < 0) rx = -rx;
if (ry < 0) ry = -ry;
k1 = (x1 - x2) / 2;
k2 = (y1 - y2) / 2;
x1_ = cosf * k1 + sinf * k2;
y1_ = -sinf * k1 + cosf * k2;
gamma = (x1_ * x1_) / (rx * rx) + (y1_ * y1_) / (ry * ry);
if (gamma > 1) {
rx *= sqrt(gamma);
ry *= sqrt(gamma);
}
/* Compute the center */
k1 = rx * rx * y1_ * y1_ + ry * ry * x1_ * x1_;
if (k1 == 0)
return;
k1 = sqrt(fabs((rx * rx * ry * ry) / k1 - 1));
if (sweep_flag == large_arc_flag)
k1 = -k1;
cx_ = k1 * rx * y1_ / ry;
cy_ = -k1 * ry * x1_ / rx;
cx = cosf * cx_ - sinf * cy_ + (x1 + x2) / 2;
cy = sinf * cx_ + cosf * cy_ + (y1 + y2) / 2;
/* Compute start angle */
k1 = (x1_ - cx_) / rx;
k2 = (y1_ - cy_) / ry;
k3 = (-x1_ - cx_) / rx;
k4 = (-y1_ - cy_) / ry;
k5 = sqrt(fabs(k1 * k1 + k2 * k2));
if (k5 == 0) return;
k5 = k1 / k5;
if (k5 < -1) k5 = -1;
else if(k5 > 1) k5 = 1;
theta1 = acos(k5);
if(k2 < 0) theta1 = -theta1;
/* Compute delta_theta */
k5 = sqrt(fabs((k1 * k1 + k2 * k2) * (k3 * k3 + k4 * k4)));
if (k5 == 0) return;
k5 = (k1 * k3 + k2 * k4) / k5;
if (k5 < -1) k5 = -1;
else if (k5 > 1) k5 = 1;
delta_theta = acos(k5);
if(k1 * k4 - k3 * k2 < 0) delta_theta = -delta_theta;
if (sweep_flag && delta_theta < 0)
delta_theta += M_PI*2;
else if (!sweep_flag && delta_theta > 0)
delta_theta -= M_PI*2;
/* Now draw the arc */
n_segs = ceil (fabs (delta_theta / (M_PI * 0.5 + 0.001)));
for (i = 0; i < n_segs; i++)
_ector_arc_segment(obj, ctx,
cx, cy,
theta1 + i * delta_theta / n_segs,
theta1 + (i + 1) * delta_theta / n_segs,
rx, ry, x_axis_rotation);
*current_x = x;
*current_y = y;
}
static Eina_Bool
_ector_renderer_cairo_shape_ector_renderer_generic_base_prepare(Eo *obj, Ector_Renderer_Cairo_Shape_Data *pd)
{
@ -230,8 +71,6 @@ _ector_renderer_cairo_shape_ector_renderer_generic_base_prepare(Eo *obj, Ector_R
if (!pd->path && pd->shape->path.cmd)
{
double *pts;
double current_x = 0, current_y = 0;
double current_ctrl_x = 0, current_ctrl_y = 0;
unsigned int i;
USE(obj, cairo_new_path, EINA_FALSE);
@ -248,9 +87,6 @@ _ector_renderer_cairo_shape_ector_renderer_generic_base_prepare(Eo *obj, Ector_R
cairo_move_to(pd->parent->cairo, pts[0], pts[1]);
current_ctrl_x = current_x = pts[0];
current_ctrl_y = current_y = pts[1];
pts += 2;
break;
case EFL_GRAPHICS_PATH_COMMAND_TYPE_LINE_TO:
@ -258,9 +94,6 @@ _ector_renderer_cairo_shape_ector_renderer_generic_base_prepare(Eo *obj, Ector_R
cairo_line_to(pd->parent->cairo, pts[0], pts[1]);
current_ctrl_x = current_x = pts[0];
current_ctrl_y = current_y = pts[1];
pts += 2;
break;
case EFL_GRAPHICS_PATH_COMMAND_TYPE_CUBIC_TO:
@ -273,109 +106,13 @@ _ector_renderer_cairo_shape_ector_renderer_generic_base_prepare(Eo *obj, Ector_R
pts[2], pts[3], pts[4], pts[5], // control points
pts[0], pts[1]); // destination point
current_ctrl_x = pts[4];
current_ctrl_y = pts[5];
current_x = pts[0];
current_y = pts[1];
pts += 6;
break;
case EFL_GRAPHICS_PATH_COMMAND_TYPE_ARC_TO:
_ector_arc_to(obj, pd->parent->cairo,
&current_x, &current_y,
pts[2], pts[3], pts[4],
0, 0, // FIXME: need to get the large arc and sweep flag
pts[0], pts[1]);
pts += 5;
break;
case EFL_GRAPHICS_PATH_COMMAND_TYPE_CLOSE:
USE(obj, cairo_close_path, EINA_FALSE);
cairo_close_path(pd->parent->cairo);
break;
case EFL_GRAPHICS_PATH_COMMAND_TYPE_QUADRATIC_TO:
{
double x1, y1, x2, y2, x3, y3;
// This code come from librsvg rsvg-path.c
// Be careful, we do have a different order than
// cairo, first is destination point, followed by
// the control point. The opposite of cairo.
/* raise quadratic bezier to cubic */
x1 = (current_x + 2 * pts[2]) * (1.0 / 3.0);
y1 = (current_y + 2 * pts[3]) * (1.0 / 3.0);
x3 = pts[0];
y3 = pts[1];
x2 = (x3 + 2 * pts[2]) * (1.0 / 3.0);
y2 = (y3 + 2 * pts[3]) * (1.0 / 3.0);
cairo_curve_to(pd->parent->cairo,
x1, y1, x2, y2, // control points
x3, y3); // destination point
current_ctrl_x = pts[2];
current_ctrl_y = pts[3];
current_x = x3;
current_y = y3;
break;
}
case EFL_GRAPHICS_PATH_COMMAND_TYPE_SQUADRATIC_TO:
{
// This code come from librsvg rsvg-path.c
// Smooth quadratic basically reusing the last control
// point in a meaningful way.
double xc, yc; /* quadratic control point */
double x1, y1, x2, y2, x3, y3;
xc = 2 * current_x - current_ctrl_x;
yc = 2 * current_y - current_ctrl_y;
/* generate a quadratic bezier with control point = xc, yc */
x1 = (current_x + 2 * xc) * (1.0 / 3.0);
y1 = (current_y + 2 * yc) * (1.0 / 3.0);
x3 = pts[0];
y3 = pts[1];
x2 = (x3 + 2 * xc) * (1.0 / 3.0);
y2 = (y3 + 2 * yc) * (1.0 / 3.0);
USE(obj, cairo_curve_to, EINA_FALSE);
cairo_curve_to(pd->parent->cairo,
x1, y1, x2, y2, x3, y3);
current_ctrl_x = xc;
current_ctrl_y = yc;
current_x = x3;
current_y = y3;
break;
}
case EFL_GRAPHICS_PATH_COMMAND_TYPE_SCUBIC_TO:
{
// This code come from librsvg rsvg-path.c
// Smooth cubic basically reusing the last control point
// in a meaningful way.
double x1, y1, x2, y2, x3, y3;
x1 = 2 * current_x - current_ctrl_x;
y1 = 2 * current_y - current_ctrl_y;
x2 = pts[2];
y2 = pts[3];
x3 = pts[0];
y3 = pts[1];
USE(obj, cairo_curve_to, EINA_FALSE);
cairo_curve_to(pd->parent->cairo,
x1, y1, x2, y2, x3, y3);
current_ctrl_x = x2;
current_ctrl_y = y2;
current_x = x3;
current_y = y3;
break;
}
case EFL_GRAPHICS_PATH_COMMAND_TYPE_LAST:
case EFL_GRAPHICS_PATH_COMMAND_TYPE_END:
break;

View File

@ -45,11 +45,7 @@ typedef enum _Efl_Graphics_Path_Command
EFL_GRAPHICS_PATH_COMMAND_TYPE_END = 0, /**< End of the stream of command */
EFL_GRAPHICS_PATH_COMMAND_TYPE_MOVE_TO, /**< A move command type */
EFL_GRAPHICS_PATH_COMMAND_TYPE_LINE_TO, /**< A line command type */
EFL_GRAPHICS_PATH_COMMAND_TYPE_QUADRATIC_TO, /**< A quadratic command type */
EFL_GRAPHICS_PATH_COMMAND_TYPE_SQUADRATIC_TO, /**< A smooth quadratic command type */
EFL_GRAPHICS_PATH_COMMAND_TYPE_CUBIC_TO, /**< A cubic command type */
EFL_GRAPHICS_PATH_COMMAND_TYPE_SCUBIC_TO, /**< A smooth cubic command type */
EFL_GRAPHICS_PATH_COMMAND_TYPE_ARC_TO, /**< An arc command type */
EFL_GRAPHICS_PATH_COMMAND_TYPE_CLOSE, /**< A close command type */
EFL_GRAPHICS_PATH_COMMAND_TYPE_LAST, /**< Not a valid command, but last one according to this version header */
} Efl_Graphics_Path_Command;

View File

@ -4,6 +4,10 @@
#include <Efl.h>
#include <math.h>
#include <float.h>
#include <ctype.h>
static inline unsigned int
efl_graphics_path_command_length(Efl_Graphics_Path_Command command)
{
@ -12,11 +16,7 @@ efl_graphics_path_command_length(Efl_Graphics_Path_Command command)
case EFL_GRAPHICS_PATH_COMMAND_TYPE_END: return 0;
case EFL_GRAPHICS_PATH_COMMAND_TYPE_MOVE_TO: return 2;
case EFL_GRAPHICS_PATH_COMMAND_TYPE_LINE_TO: return 2;
case EFL_GRAPHICS_PATH_COMMAND_TYPE_QUADRATIC_TO: return 4;
case EFL_GRAPHICS_PATH_COMMAND_TYPE_SQUADRATIC_TO: return 2;
case EFL_GRAPHICS_PATH_COMMAND_TYPE_CUBIC_TO: return 6;
case EFL_GRAPHICS_PATH_COMMAND_TYPE_SCUBIC_TO: return 4;
case EFL_GRAPHICS_PATH_COMMAND_TYPE_ARC_TO: return 5;
case EFL_GRAPHICS_PATH_COMMAND_TYPE_CLOSE: return 0;
case EFL_GRAPHICS_PATH_COMMAND_TYPE_LAST: return 0;
}
@ -125,6 +125,52 @@ efl_graphics_path_interpolate(const Efl_Graphics_Path_Command *cmd,
*r = (*from) * pos_map + ((*to) * (1.0 - pos_map));
}
EAPI Eina_Bool
efl_graphics_path_current_get(const Efl_Graphics_Path_Command *cmd,
const double *points,
double *current_x, double *current_y,
double *current_ctrl_x, double *current_ctrl_y)
{
unsigned int i;
if (current_x) *current_x = 0;
if (current_y) *current_y = 0;
if (current_ctrl_x) *current_ctrl_x = 0;
if (current_ctrl_y) *current_ctrl_y = 0;
if (!cmd || !points) return EINA_FALSE;
for (i = 0; cmd[i] != EFL_GRAPHICS_PATH_COMMAND_TYPE_END; i++)
{
switch (cmd[i])
{
case EFL_GRAPHICS_PATH_COMMAND_TYPE_END:
break;
case EFL_GRAPHICS_PATH_COMMAND_TYPE_MOVE_TO:
case EFL_GRAPHICS_PATH_COMMAND_TYPE_LINE_TO:
if (current_x) *current_x = points[0];
if (current_y) *current_y = points[1];
points += 2;
break;
case EFL_GRAPHICS_PATH_COMMAND_TYPE_CUBIC_TO:
if (current_x) *current_x = points[0];
if (current_y) *current_y = points[1];
if (current_ctrl_x) *current_ctrl_x = points[4];
if (current_ctrl_y) *current_ctrl_y = points[5];
points += 6;
break;
case EFL_GRAPHICS_PATH_COMMAND_TYPE_CLOSE:
break;
case EFL_GRAPHICS_PATH_COMMAND_TYPE_LAST:
default:
return EINA_FALSE;
}
}
return EINA_TRUE;
}
EAPI void
efl_graphics_path_append_move_to(Efl_Graphics_Path_Command **commands, double **points,
double x, double y)
@ -157,30 +203,49 @@ EAPI void
efl_graphics_path_append_quadratic_to(Efl_Graphics_Path_Command **commands, double **points,
double x, double y, double ctrl_x, double ctrl_y)
{
double *offset_point;
double current_x = 0, current_y = 0;
double ctrl_x0, ctrl_y0, ctrl_x1, ctrl_y1;
if (!efl_graphics_path_grow(EFL_GRAPHICS_PATH_COMMAND_TYPE_QUADRATIC_TO,
commands, points, &offset_point))
if (!efl_graphics_path_current_get(*commands, *points,
&current_x, &current_y,
NULL, NULL))
return ;
offset_point[0] = x;
offset_point[1] = y;
offset_point[2] = ctrl_x;
offset_point[3] = ctrl_y;
// Convert quadratic bezier to cubic
ctrl_x0 = (current_x + 2 * ctrl_x) * (1.0 / 3.0);
ctrl_y0 = (current_y + 2 * ctrl_y) * (1.0 / 3.0);
ctrl_x1 = (x + 2 * ctrl_x) * (1.0 / 3.0);
ctrl_y1 = (y + 2 * ctrl_y) * (1.0 / 3.0);
efl_graphics_path_append_cubic_to(commands, points, x, y,
ctrl_x0, ctrl_y0, ctrl_x1, ctrl_y1);
}
EAPI void
efl_graphics_path_append_squadratic_to(Efl_Graphics_Path_Command **commands, double **points,
double x, double y)
{
double *offset_point;
double xc, yc; /* quadratic control point */
double ctrl_x0, ctrl_y0, ctrl_x1, ctrl_y1;
double current_x = 0, current_y = 0;
double current_ctrl_x = 0, current_ctrl_y = 0;
if (!efl_graphics_path_grow(EFL_GRAPHICS_PATH_COMMAND_TYPE_SQUADRATIC_TO,
commands, points, &offset_point))
if (!efl_graphics_path_current_get(*commands, *points,
&current_x, &current_y,
&current_ctrl_x, &current_ctrl_y))
return ;
offset_point[0] = x;
offset_point[1] = y;
xc = 2 * current_x - current_ctrl_x;
yc = 2 * current_y - current_ctrl_y;
/* generate a quadratic bezier with control point = xc, yc */
ctrl_x0 = (current_x + 2 * xc) * (1.0 / 3.0);
ctrl_y0 = (current_y + 2 * yc) * (1.0 / 3.0);
ctrl_x1 = (x + 2 * xc) * (1.0 / 3.0);
ctrl_y1 = (y + 2 * yc) * (1.0 / 3.0);
efl_graphics_path_append_cubic_to(commands, points, x, y,
ctrl_x0, ctrl_y0,
ctrl_x1, ctrl_y1);
}
EAPI void
@ -208,35 +273,169 @@ efl_graphics_path_append_scubic_to(Efl_Graphics_Path_Command **commands, double
double x, double y,
double ctrl_x, double ctrl_y)
{
double *offset_point;
double ctrl_x0, ctrl_y0;
double current_x = 0, current_y = 0;
double current_ctrl_x = 0, current_ctrl_y = 0;
if (!efl_graphics_path_grow(EFL_GRAPHICS_PATH_COMMAND_TYPE_SCUBIC_TO,
commands, points, &offset_point))
if (!efl_graphics_path_current_get(*commands, *points,
&current_x, &current_y,
&current_ctrl_x, &current_ctrl_y))
return ;
offset_point[0] = x;
offset_point[1] = y;
offset_point[2] = ctrl_x;
offset_point[3] = ctrl_y;
ctrl_x0 = 2 * current_x - current_ctrl_x;
ctrl_y0 = 2 * current_y - current_ctrl_y;
efl_graphics_path_append_cubic_to(commands, points, x, y,
ctrl_x0, ctrl_y0, ctrl_x, ctrl_y);
}
// This function come from librsvg rsvg-path.c
static void
_efl_graphics_path_append_arc_segment(Efl_Graphics_Path_Command **commands, double **points,
double xc, double yc,
double th0, double th1, double rx, double ry,
double angle)
{
double x1, y1, x2, y2, x3, y3;
double t;
double th_half;
double f, sinf, cosf;
f = angle * M_PI / 180.0;
sinf = sin(f);
cosf = cos(f);
th_half = 0.5 * (th1 - th0);
t = (8.0 / 3.0) * sin(th_half * 0.5) * sin(th_half * 0.5) / sin(th_half);
x1 = rx * (cos(th0) - t * sin(th0));
y1 = ry * (sin(th0) + t * cos(th0));
x3 = rx* cos(th1);
y3 = ry* sin(th1);
x2 = x3 + rx * (t * sin(th1));
y2 = y3 + ry * (-t * cos(th1));
efl_graphics_path_append_cubic_to(commands, points,
xc + cosf * x3 - sinf * y3,
yc + sinf * x3 + cosf * y3,
xc + cosf * x1 - sinf * y1,
yc + sinf * x1 + cosf * y1,
xc + cosf * x2 - sinf * y2,
yc + sinf * x2 + cosf * y2);
}
// This function come from librsvg rsvg-path.c
EAPI void
efl_graphics_path_append_arc_to(Efl_Graphics_Path_Command **commands, double **points,
double x, double y,
double rx, double ry,
double angle)
double rx, double ry, double angle,
Eina_Bool large_arc, Eina_Bool sweep)
{
double *offset_point;
/* See Appendix F.6 Elliptical arc implementation notes
http://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes */
double f, sinf, cosf;
double x1, y1, x2, y2;
double x1_, y1_;
double cx_, cy_, cx, cy;
double gamma;
double theta1, delta_theta;
double k1, k2, k3, k4, k5;
int i, n_segs;
if (!efl_graphics_path_grow(EFL_GRAPHICS_PATH_COMMAND_TYPE_ARC_TO,
commands, points, &offset_point))
if (!efl_graphics_path_current_get(*commands, *points,
&x1, &y1,
NULL, NULL))
return ;
offset_point[0] = x;
offset_point[1] = y;
offset_point[2] = rx;
offset_point[3] = ry;
offset_point[4] = angle;
/* Start and end of path segment */
x2 = x;
y2 = y;
if (x1 == x2 && y1 == y2)
return;
/* X-axis */
f = angle * M_PI / 180.0;
sinf = sin(f);
cosf = cos(f);
/* Check the radius against floading point underflow.
See http://bugs.debian.org/508443 */
if ((fabs(rx) < DBL_EPSILON) || (fabs(ry) < DBL_EPSILON))
{
efl_graphics_path_append_line_to(commands, points, x, y);
return;
}
if (rx < 0) rx = -rx;
if (ry < 0) ry = -ry;
k1 = (x1 - x2) / 2;
k2 = (y1 - y2) / 2;
x1_ = cosf * k1 + sinf * k2;
y1_ = -sinf * k1 + cosf * k2;
gamma = (x1_ * x1_) / (rx * rx) + (y1_ * y1_) / (ry * ry);
if (gamma > 1)
{
rx *= sqrt(gamma);
ry *= sqrt(gamma);
}
/* Compute the center */
k1 = rx * rx * y1_ * y1_ + ry * ry * x1_ * x1_;
if (k1 == 0) return;
k1 = sqrt(fabs((rx * rx * ry * ry) / k1 - 1));
if (sweep == large_arc)
k1 = -k1;
cx_ = k1 * rx * y1_ / ry;
cy_ = -k1 * ry * x1_ / rx;
cx = cosf * cx_ - sinf * cy_ + (x1 + x2) / 2;
cy = sinf * cx_ + cosf * cy_ + (y1 + y2) / 2;
/* Compute start angle */
k1 = (x1_ - cx_) / rx;
k2 = (y1_ - cy_) / ry;
k3 = (-x1_ - cx_) / rx;
k4 = (-y1_ - cy_) / ry;
k5 = sqrt(fabs(k1 * k1 + k2 * k2));
if (k5 == 0) return;
k5 = k1 / k5;
if (k5 < -1) k5 = -1;
else if(k5 > 1) k5 = 1;
theta1 = acos(k5);
if(k2 < 0) theta1 = -theta1;
/* Compute delta_theta */
k5 = sqrt(fabs((k1 * k1 + k2 * k2) * (k3 * k3 + k4 * k4)));
if (k5 == 0) return;
k5 = (k1 * k3 + k2 * k4) / k5;
if (k5 < -1) k5 = -1;
else if (k5 > 1) k5 = 1;
delta_theta = acos(k5);
if(k1 * k4 - k3 * k2 < 0) delta_theta = -delta_theta;
if (sweep && delta_theta < 0)
delta_theta += M_PI*2;
else if (!sweep && delta_theta > 0)
delta_theta -= M_PI*2;
/* Now draw the arc */
n_segs = ceil(fabs(delta_theta / (M_PI * 0.5 + 0.001)));
for (i = 0; i < n_segs; i++)
_efl_graphics_path_append_arc_segment(commands, points,
cx, cy,
theta1 + i * delta_theta / n_segs,
theta1 + (i + 1) * delta_theta / n_segs,
rx, ry, angle);
}
EAPI void
@ -253,8 +452,8 @@ efl_graphics_path_append_circle(Efl_Graphics_Path_Command **commands, double **p
double x, double y, double radius)
{
efl_graphics_path_append_move_to(commands, points, x, y - radius);
efl_graphics_path_append_arc_to(commands, points, x + radius, y, radius, radius, 0);
efl_graphics_path_append_arc_to(commands, points, x, y + radius, radius, radius, 0);
efl_graphics_path_append_arc_to(commands, points, x - radius, y, radius, radius, 0);
efl_graphics_path_append_arc_to(commands, points, x, y - radius, radius, radius, 0);
efl_graphics_path_append_arc_to(commands, points, x + radius, y, radius, radius, 0, EINA_FALSE, EINA_FALSE);
efl_graphics_path_append_arc_to(commands, points, x, y + radius, radius, radius, 0, EINA_FALSE, EINA_FALSE);
efl_graphics_path_append_arc_to(commands, points, x - radius, y, radius, radius, 0, EINA_FALSE, EINA_FALSE);
efl_graphics_path_append_arc_to(commands, points, x, y - radius, radius, radius, 0, EINA_FALSE, EINA_FALSE);
}

View File

@ -36,7 +36,8 @@ EAPI void
efl_graphics_path_append_arc_to(Efl_Graphics_Path_Command **commands, double **points,
double x, double y,
double rx, double ry,
double angle);
double angle,
Eina_Bool large_arc, Eina_Bool sweep);
EAPI void
efl_graphics_path_append_close(Efl_Graphics_Path_Command **commands, double **points);
@ -55,4 +56,10 @@ EAPI Eina_Bool
efl_graphics_path_equal_commands(const Efl_Graphics_Path_Command *a,
const Efl_Graphics_Path_Command *b);
EAPI Eina_Bool
efl_graphics_path_current_get(const Efl_Graphics_Path_Command *cmd,
const double *points,
double *current_x, double *current_y,
double *current_ctrl_x, double *current_ctrl_y);
#endif