From 37c6765044c75864f963ba6d6d0585f7ff2e8cd4 Mon Sep 17 00:00:00 2001 From: Subhransu Sekhar Mohanty Date: Thu, 5 Feb 2015 12:01:24 +0900 Subject: [PATCH] evas/example : updated evas-vg-simple application Change-Id: Id38a5aca1f5fb7e98021ee325c0b99a63f0df0cf --- src/examples/evas/evas-vg-simple.c | 361 ++----------------------------------- 1 file changed, 12 insertions(+), 349 deletions(-) diff --git a/src/examples/evas/evas-vg-simple.c b/src/examples/evas/evas-vg-simple.c index cfaddd5..ea7409f 100644 --- a/src/examples/evas/evas-vg-simple.c +++ b/src/examples/evas/evas-vg-simple.c @@ -32,352 +32,13 @@ #include #include - -#include -#include - -#define PATH_KAPPA 0.5522847498 -#define PI 3.1415926535 - -typedef struct _Bezier -{ -float x1, y1, x2, y2, x3, y3, x4, y4; -}Bezier; - -typedef struct _Point -{ - int x; - int y; -}Point; - -static -Bezier bezierFromPoints(Point p1, Point p2, - Point p3, Point p4) -{ - Bezier b; - b.x1 = p1.x; - b.y1 = p1.y; - b.x2 = p2.x; - b.y2 = p2.y; - b.x3 = p3.x; - b.y3 = p3.y; - b.x4 = p4.x; - b.y4 = p4.y; - return b; -} - -inline void -parameterSplitLeft(Bezier *b, float t, Bezier *left) -{ - left->x1 = b->x1; - left->y1 = b->y1; - - left->x2 = b->x1 + t * ( b->x2 - b->x1 ); - left->y2 = b->y1 + t * ( b->y2 - b->y1 ); - - left->x3 = b->x2 + t * ( b->x3 - b->x2 ); // temporary holding spot - left->y3 = b->y2 + t * ( b->y3 - b->y2 ); // temporary holding spot - - b->x3 = b->x3 + t * ( b->x4 - b->x3 ); - b->y3 = b->y3 + t * ( b->y4 - b->y3 ); - - b->x2 = left->x3 + t * ( b->x3 - left->x3); - b->y2 = left->y3 + t * ( b->y3 - left->y3); - - left->x3 = left->x2 + t * ( left->x3 - left->x2 ); - left->y3 = left->y2 + t * ( left->y3 - left->y2 ); - - left->x4 = b->x1 = left->x3 + t * (b->x2 - left->x3); - left->y4 = b->y1 = left->y3 + t * (b->y2 - left->y3); -} -static -Bezier bezierOnInterval(Bezier *b, float t0, float t1) -{ - if (t0 == 0 && t1 == 1) - return *b; - - Bezier result; - parameterSplitLeft(b, t0, &result); - float trueT = (t1-t0)/(1-t0); - parameterSplitLeft(b, trueT, &result); - - return result; -} - -inline void -_bezier_coefficients(float t, float *ap, float *bp, float *cp, float *dp) -{ - float a,b,c,d; - float m_t = 1. - t; - b = m_t * m_t; - c = t * t; - d = c * t; - a = b * m_t; - b *= 3. * t; - c *= 3. * m_t; - *ap = a; - *bp = b; - *cp = c; - *dp = d; -} - -static -float _t_for_arc_angle(float angle) -{ - if (angle < 0.00001) - return 0; - - if (angle == 90.0) - return 1; - - float radians = PI * angle / 180; - float cosAngle = cos(radians); - float sinAngle = sin(radians); - - // initial guess - float tc = angle / 90; - // do some iterations of newton's method to approximate cosAngle - // finds the zero of the function b.pointAt(tc).x() - cosAngle - tc -= ((((2-3*PATH_KAPPA) * tc + 3*(PATH_KAPPA-1)) * tc) * tc + 1 - cosAngle) // value - / (((6-9*PATH_KAPPA) * tc + 6*(PATH_KAPPA-1)) * tc); // derivative - tc -= ((((2-3*PATH_KAPPA) * tc + 3*(PATH_KAPPA-1)) * tc) * tc + 1 - cosAngle) // value - / (((6-9*PATH_KAPPA) * tc + 6*(PATH_KAPPA-1)) * tc); // derivative - - // initial guess - float ts = tc; - // do some iterations of newton's method to approximate sinAngle - // finds the zero of the function b.pointAt(tc).y() - sinAngle - ts -= ((((3*PATH_KAPPA-2) * ts - 6*PATH_KAPPA + 3) * ts + 3*PATH_KAPPA) * ts - sinAngle) - / (((9*PATH_KAPPA-6) * ts + 12*PATH_KAPPA - 6) * ts + 3*PATH_KAPPA); - ts -= ((((3*PATH_KAPPA-2) * ts - 6*PATH_KAPPA + 3) * ts + 3*PATH_KAPPA) * ts - sinAngle) - / (((9*PATH_KAPPA-6) * ts + 12*PATH_KAPPA - 6) * ts + 3*PATH_KAPPA); - - // use the average of the t that best approximates cosAngle - // and the t that best approximates sinAngle - float t = 0.5 * (tc + ts); - return t; -} - -static void -_find_ellipse_coords(int x, int y, int w, int h, float angle, float length, - Point* startPoint, Point *endPoint) -{ - if (!w || !h ) { - if (startPoint) - startPoint->x = 0 , startPoint->y = 0; - if (endPoint) - endPoint->x = 0 , endPoint->y = 0; - return; - } - - int w2 = w / 2; - int h2 = h / 2; - - float angles[2] = { angle, angle + length }; - Point *points[2] = { startPoint, endPoint }; - int i =0; - for (i = 0; i < 2; ++i) { - if (!points[i]) - continue; - - float theta = angles[i] - 360 * floor(angles[i] / 360); - float t = theta / 90; - // truncate - int quadrant = (int)t; - t -= quadrant; - - t = _t_for_arc_angle(90 * t); - - // swap x and y? - if (quadrant & 1) - t = 1 - t; - - float a, b, c, d; - _bezier_coefficients(t, &a, &b, &c, &d); - float px = a + b + c*PATH_KAPPA; - float py = d + c + b*PATH_KAPPA; - - // left quadrants - if (quadrant == 1 || quadrant == 2) - px = -px; - - // top quadrants - if (quadrant == 0 || quadrant == 1) - py = -py; - int cx = x+w/2; - int cy = y+h/2; - points[i]->x = cx + w2 * px; - points[i]->y = cy + h2 * py; - } -} - - -//// The return value is the starting point of the arc -static -Point _curves_for_arc(int x, int y, int w, int h, - float startAngle, float sweepLength, - Point *curves, int *point_count) -{ - *point_count = 0; - int w2 = w / 2; - int w2k = w2 * PATH_KAPPA; - - int h2 = h / 2; - int h2k = h2 * PATH_KAPPA; - - Point points[16] = - { - // start point - x + w, y + h2, - - // 0 -> 270 degrees - x + w, y + h2 + h2k, - x + w2 + w2k, y + h, - x + w2, y + h, - - // 270 -> 180 degrees - x + w2 - w2k, y + h, - x, y + h2 + h2k, - x, y + h2, - - // 180 -> 90 degrees - x, y + h2 - h2k, - x + w2 - w2k, y, - x + w2, y, - - // 90 -> 0 degrees - x + w2 + w2k, y, - x + w, y + h2 - h2k, - x + w, y + h2 - }; - - if (sweepLength > 360) sweepLength = 360; - else if (sweepLength < -360) sweepLength = -360; - - // Special case fast paths - if (startAngle == 0) { - if (sweepLength == 360) { - int i; - for (i = 11; i >= 0; --i) - curves[(*point_count)++] = points[i]; - return points[12]; - } else if (sweepLength == -360) { - int i ; - for (i = 1; i <= 12; ++i) - curves[(*point_count)++] = points[i]; - return points[0]; - } - } - - int startSegment = (int)(floor(startAngle / 90)); - int endSegment = (int)(floor((startAngle + sweepLength) / 90)); - - float startT = (startAngle - startSegment * 90) / 90; - float endT = (startAngle + sweepLength - endSegment * 90) / 90; - - int delta = sweepLength > 0 ? 1 : -1; - if (delta < 0) { - startT = 1 - startT; - endT = 1 - endT; - } - - // avoid empty start segment - if (startT == 1.0) { - startT = 0; - startSegment += delta; - } - - // avoid empty end segment - if (endT == 0) { - endT = 1; - endSegment -= delta; - } - - startT = _t_for_arc_angle(startT * 90); - endT = _t_for_arc_angle(endT * 90); - - Eina_Bool splitAtStart = !(fabs(startT) <= 0.00001f); - Eina_Bool splitAtEnd = !(fabs(endT - 1.0) <= 0.00001f); - - const int end = endSegment + delta; - - // empty arc? - if (startSegment == end) { - const int quadrant = 3 - ((startSegment % 4) + 4) % 4; - const int j = 3 * quadrant; - return delta > 0 ? points[j + 3] : points[j]; - } - - - Point startPoint, endPoint; - _find_ellipse_coords(x, y, w, h, startAngle, sweepLength, &startPoint, &endPoint); - int i; - for (i = startSegment; i != end; i += delta) { - const int quadrant = 3 - ((i % 4) + 4) % 4; - const int j = 3 * quadrant; - - Bezier b; - if (delta > 0) - b = bezierFromPoints(points[j + 3], points[j + 2], points[j + 1], points[j]); - else - b = bezierFromPoints(points[j], points[j + 1], points[j + 2], points[j + 3]); - - // empty arc? - if (startSegment == endSegment && (startT == endT)) - return startPoint; - - if (i == startSegment) { - if (i == endSegment && splitAtEnd) - b = bezierOnInterval(&b, startT, endT); - else if (splitAtStart) - b = bezierOnInterval(&b, startT, 1); - } else if (i == endSegment && splitAtEnd) { - b = bezierOnInterval(&b, 0, endT); - } - - // push control points - curves[(*point_count)].x = b.x2; - curves[(*point_count)++].y = b.y2; - curves[(*point_count)].x = b.x3; - curves[(*point_count)++].y = b.y3; - curves[(*point_count)].x = b.x4; - curves[(*point_count)++].y = b.y4; - } - - curves[*(point_count)-1] = endPoint; - - return startPoint; -} - -void _arcto(Efl_Gfx_Path_Command **path_cmd, double **points,int x, int y, int width, int height, int startAngle, int sweepLength) -{ - int point_count; - - Point pts[15]; - Point curve_start = _curves_for_arc(x,y,width,height, startAngle, sweepLength, pts, &point_count); - int cx = x + (width)/2; - int cy = y + (height)/2; - - efl_gfx_path_append_move_to(path_cmd, points, cx, cy); - - efl_gfx_path_append_line_to(path_cmd, points, curve_start.x, curve_start.y); - int i; - for (i=0; i