shithub: etoys

Download patch

ref: e40277aa9e1d188a779ca42058e7932fb445f420
parent: a946b00aa91ed059a1e9aad367bb6e872dcd1c1a
author: rodri <rgl@antares-labs.eu>
date: Mon May 11 13:42:56 EDT 2020

new toy: béziers

--- /dev/null
+++ b/beziers.c
@@ -1,0 +1,128 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <event.h>
+#include <keyboard.h>
+
+typedef struct Point2 Point2;
+typedef struct Bézier Bézier;
+
+struct Point2
+{
+	double x, y, w;
+};
+
+struct Bézier
+{
+	Point2 p0, p1, p2, p3;
+};
+
+enum {
+	Cbg,
+	Cctl,
+	Cbez,
+	NCOLOR
+};
+
+Image *pal[NCOLOR];
+Bézier *bezs;
+Point2 pts[4];
+ulong nbez, npt;
+
+Point2
+Pt2(double x, double y, double w)
+{
+	return (Point2){x,y,w};
+}
+
+Point
+toscreen(Point2 p)
+{
+	return addpt(screen->r.min, Pt(p.x,p.y));
+}
+
+Point2
+fromscreen(Point p)
+{
+	p = subpt(p, screen->r.min);
+	return Pt2(p.x,p.y,1);
+}
+
+void
+initpalette(void)
+{
+	pal[Cbg] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x000000ff);
+	pal[Cctl] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x00ff00ff);
+	pal[Cbez] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0xff0000ff);
+}
+
+void
+redraw(void)
+{
+	int i;
+
+	draw(screen, screen->r, pal[Cbg], nil, ZP);
+	for(i = 0; i < nbez; i++)
+		bezier(screen, toscreen(bezs[i].p0), toscreen(bezs[i].p1), toscreen(bezs[i].p2), toscreen(bezs[i].p3), Endsquare, Endsquare, 0, pal[Cbez], ZP);
+	for(i = 0; i < npt; i++)
+		fillellipse(screen, toscreen(pts[i]), 2, 2, pal[Cctl], ZP);
+	flushimage(display, 1);
+}
+
+void
+usage(void)
+{
+	fprint(2, "usage: %s\n", argv0);
+	exits("usage");
+}
+
+void
+main(int argc, char *argv[])
+{
+	Event e;
+	Bézier b;
+
+	ARGBEGIN{
+	default: usage();
+	}ARGEND;
+	if(argc > 0)
+		usage();
+	if(initdraw(nil, nil, nil) < 0)
+		sysfatal("initdraw: %r");
+	initpalette();
+	einit(Emouse|Ekeyboard);
+	redraw();
+	for(;;)
+		switch(event(&e)){
+		case Emouse:
+			if((e.mouse.buttons&1) != 0){
+				pts[npt++] = fromscreen(e.mouse.xy);
+				if(npt >= nelem(pts)){
+					b.p0 = pts[0];
+					b.p1 = pts[1];
+					b.p2 = pts[2];
+					b.p3 = pts[3];
+					bezs = realloc(bezs, ++nbez*sizeof(Bézier));
+					bezs[nbez-1] = b;
+					npt = 0;
+				}
+				redraw();
+			}
+			break;
+		case Ekeyboard:
+			switch(e.kbdc){
+			case 'q':
+			case Kdel:
+				exits(0);
+			}
+			break;
+		}
+}
+
+void
+eresized(int)
+{
+	if(getwindow(display, Refnone) < 0)
+		sysfatal("resize failed");
+	redraw();
+}
--- a/mkfile
+++ b/mkfile
@@ -3,5 +3,6 @@
 BIN=/$objtype/bin/etoys
 TARG=\
 	triangles\
+	beziers\
 
 </sys/src/cmd/mkmany