separate out
diff --git a/src/libmemdraw/arc.c b/src/libmemdraw/arc.c
new file mode 100644
index 0000000..df836a0
--- /dev/null
+++ b/src/libmemdraw/arc.c
@@ -0,0 +1,116 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <memdraw.h>
+
+/*
+ * elarc(dst,c,a,b,t,src,sp,alpha,phi)
+ *   draws the part of an ellipse between rays at angles alpha and alpha+phi
+ *   measured counterclockwise from the positive x axis. other
+ *   arguments are as for ellipse(dst,c,a,b,t,src,sp)
+ */
+
+enum
+{
+	R, T, L, B	/* right, top, left, bottom */
+};
+
+static
+Point corners[] = {
+	{1,1},
+	{-1,1},
+	{-1,-1},
+	{1,-1}
+};
+
+static
+Point p00;
+
+/*
+ * make a "wedge" mask covering the desired angle and contained in
+ * a surrounding square; draw a full ellipse; intersect that with the
+ * wedge to make a mask through which to copy src to dst.
+ */
+void
+memarc(Memimage *dst, Point c, int a, int b, int t, Memimage *src, Point sp, int alpha, int phi, int op)
+{
+	int i, w, beta, tmp, c1, c2, m, m1;
+	Rectangle rect;
+	Point p,	bnd[8];
+	Memimage *wedge, *figure, *mask;
+
+	if(a < 0)
+		a = -a;
+	if(b < 0)
+		b = -b;
+	w = t;
+	if(w < 0)
+		w = 0;
+	alpha = -alpha;		/* compensate for upside-down coords */
+	phi = -phi;
+	beta = alpha + phi;
+	if(phi < 0){
+		tmp = alpha;
+		alpha = beta;
+		beta = tmp;
+		phi = -phi;
+	}
+	if(phi >= 360){
+		memellipse(dst, c, a, b, t, src, sp, op);
+		return;
+	}
+	while(alpha < 0)
+		alpha += 360;
+	while(beta < 0)
+		beta += 360;
+	c1 = alpha/90 & 3;	/* number of nearest corner */
+	c2 = beta/90 & 3;
+		/*
+		 * icossin returns point at radius ICOSSCALE.
+		 * multiplying by m1 moves it outside the ellipse
+		*/
+	rect = Rect(-a-w, -b-w, a+w+1, b+w+1);
+	m = rect.max.x;	/* inradius of bounding square */
+	if(m < rect.max.y)
+		m = rect.max.y;
+	m1 = (m+ICOSSCALE-1) >> 10;
+	m = m1 << 10;		/* assure m1*cossin is inside */
+	i = 0;
+	bnd[i++] = Pt(0,0);
+	icossin(alpha, &p.x, &p.y);
+	bnd[i++] = mulpt(p, m1);
+	for(;;) {
+		bnd[i++] = mulpt(corners[c1], m);
+		if(c1==c2 && phi<180)
+			break;
+		c1 = (c1+1) & 3;
+		phi -= 90;
+	}
+	icossin(beta, &p.x, &p.y);
+	bnd[i++] = mulpt(p, m1);
+
+	figure = nil;
+	mask = nil;
+	wedge = allocmemimage(rect, GREY1);
+	if(wedge == nil)
+		goto Return;
+	memfillcolor(wedge, DTransparent);
+	memfillpoly(wedge, bnd, i, ~0, memopaque, p00, S);
+	figure = allocmemimage(rect, GREY1);
+	if(figure == nil)
+		goto Return;
+	memfillcolor(figure, DTransparent);
+	memellipse(figure, p00, a, b, t, memopaque, p00, S);
+	mask = allocmemimage(rect, GREY1);
+	if(mask == nil)
+		goto Return;
+	memfillcolor(mask, DTransparent);
+	memimagedraw(mask, rect, figure, rect.min, wedge, rect.min, S);
+	c = subpt(c, dst->r.min);
+	memdraw(dst, dst->r, src, subpt(sp, c), mask, subpt(p00, c), op);
+
+    Return:
+	freememimage(wedge);
+	freememimage(figure);
+	freememimage(mask);
+}