--- /dev/null
+#include <math.h>
+#include "cgmath/cgmath.h"
+#include "logo.h"
+#include "logodata.h"
+
+struct cpnode {
+ cgm_vec2 p;
+ struct cpnode *next;
+};
+
+#define CPLERP(res, a, b, t) \
+ do { \
+ (res).x = (a).x + ((b).x - (a).x) * (t); \
+ (res).y = (a).y + ((b).y - (a).y) * (t); \
+ } while(0)
+
+static cgm_vec2 *cp;
+static int numcp;
+
+int init_logo(const char *fname)
+{
+ cp = logocp;
+ numcp = LOGO_NUM_CP;
+ return 0;
+}
+
+static void eval_seg(float *res, int a, int b, float t)
+{
+ int prev, next;
+
+ if(numcp == 2) {
+ res[0] = cp[a].x + (cp[b].x - cp[a].x) * t;
+ res[1] = cp[a].y + (cp[b].y - cp[a].y) * t;
+ return;
+ }
+
+ prev = a <= 0 ? a : a - 1;
+ next = b >= numcp - 1 ? b : b + 1;
+
+ res[0] = cgm_bspline(cp[prev].x, cp[a].x, cp[b].x, cp[next].x, t);
+ res[1] = cgm_bspline(cp[prev].y, cp[a].y, cp[b].y, cp[next].y, t);
+}
+
+void eval_logo(float *res, float t)
+{
+ int idx0, idx1;
+ float t0, t1, dt;
+
+ if(!cp || numcp <= 0) {
+ res[0] = res[1] = 0;
+ return;
+ }
+ if(numcp == 1) {
+ res[0] = cp[0].x;
+ res[1] = cp[0].y;
+ return;
+ }
+
+ if(t < 0.0f) t = 0.0f;
+ if(t > 1.0f) t = 1.0f;
+
+ idx0 = (int)(t * (numcp - 1));
+ if(idx0 > numcp - 2) idx0 = numcp - 2;
+ idx1 = idx0 + 1;
+
+ dt = 1.0f / (float)(numcp - 1);
+ t0 = (float)idx0 * dt;
+ t1 = (float)idx1 * dt;
+ t = (t - t0) / (t1 - t0);
+
+ eval_seg(res, idx0, idx1, t);
+}