git: drawterm

Download patch

ref: ec862e9c8acd30ec73eb9e11b8e849ed5b711e76
parent: bdaf1a663cf88374589d1aad556614aa3af838fa
author: rodri <rgl@antares-labs.eu>
date: Sat Dec 27 12:38:50 EST 2025

libmem(draw|layer), devdraw: bring affinewarp changes from 9front

--- a/include/memdraw.h
+++ b/include/memdraw.h
@@ -144,7 +144,8 @@
 extern void	memarc(Memimage*, Point, int, int, int, Memimage*, Point, int, int, int);
 extern Rectangle	memlinebbox(Point, Point, int, int, int);
 extern int	memlineendsize(int);
-extern int	memaffinewarp(Memimage*, Rectangle, Memimage*, Point, Warp, int);
+extern void	memaffinewarp(Memimage*, Rectangle, Memimage*, Point, Warp, int);
+extern void	memlaffinewarp(Memimage*, Rectangle, Memimage*, Point, Warp, int);
 extern Memimage*	allocmemimagekernel(double*, int, int, double);
 extern int	memimagecorrelate(Memimage*, Rectangle, Memimage*, Point, Memimage*);
 extern void	_memmkcmap(void);
--- a/kern/devdraw.c
+++ b/kern/devdraw.c
@@ -1388,6 +1388,13 @@
 			q += sprint(q, " [%d %d]", BGLONG(a), BGLONG(a+4));
 			a += 8;
 			break;
+		case 'M':
+			q += sprint(q, " [[%d %d %d][%d %d %d][%d %d %d]]",
+				BGLONG(a),    BGLONG(a+ 4), BGLONG(a+ 8),
+				BGLONG(a+12), BGLONG(a+16), BGLONG(a+20),
+				BGLONG(a+24), BGLONG(a+28), BGLONG(a+32));
+			a += 36;
+			break;
 		case 'b':
 			q += sprint(q, " %d", *a++);
 			break;
@@ -1532,8 +1539,7 @@
 			src = drawimage(client, a+21);
 			drawpoint(&p, a+25);
 			drawwarp(w, a+33);
-			if(memaffinewarp(dst, r, src, p, w, a[33+3*3*4]) < 0)
-				error("memaffinewarp failed");
+			memlaffinewarp(dst, r, src, p, w, a[33+3*3*4]);
 			dstflush(dstid, dst, r);
 			continue;
 
--- a/libmemdraw/warp.c
+++ b/libmemdraw/warp.c
@@ -713,7 +713,7 @@
 	return r<<24|g<<16|b<<8|a;
 }
 
-int
+void
 memaffinewarp(Memimage *d, Rectangle r, Memimage *s, Point sp0, Warp m, int smooth)
 {
 	ulong (*sample)(Sampler*, Point) = sample1;
@@ -726,11 +726,11 @@
 	dr = d->clipr;
 	rectclip(&dr, d->r);
 	if(rectclip(&r, dr) == 0)
-		return 0;
+		return;
 
 	samp.r = s->clipr;
 	if(rectclip(&samp.r, s->r) == 0)
-		return 0;
+		return;
 
 	if(smooth)
 		sample = bilinear;
@@ -744,7 +744,10 @@
 	 * 	Lee, S., Lee, GG., Jang, E.S., Kim, WY,
 	 * 	Intelligent Computing.  ICIC 2006. LNCS, vol 4113.
 	 */
-	p2 = p2₀ = xform((Point){int2fix(r.min.x - dr.min.x) + (1<<6), int2fix(r.min.y - dr.min.y) + (1<<6)}, m);
+	p2 = p2₀ = xform((Point){
+		int2fix(r.min.x - d->r.min.x) + (1<<6),
+		int2fix(r.min.y - d->r.min.y) + (1<<6)
+	}, m);
 	for(dp.y = r.min.y; dp.y < r.max.y; dp.y++){
 	for(dp.x = r.min.x; dp.x < r.max.x; dp.x++){
 		samp.Δx = fixfrac(p2.x);
@@ -762,7 +765,6 @@
 		p2.x = p2₀.x += m[0][1];
 		p2.y = p2₀.y += m[1][1];
 	}
-	return 0;
 }
 
 static double
--- a/libmemlayer/Makefile
+++ b/libmemlayer/Makefile
@@ -4,6 +4,7 @@
 
 OFILES=\
 	draw.$O\
+	warp.$O\
 	lalloc.$O\
 	layerop.$O\
 	ldelete.$O\
--- /dev/null
+++ b/libmemlayer/warp.c
@@ -1,0 +1,159 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <memdraw.h>
+#include <memlayer.h>
+
+struct Draw
+{
+	Memlayer	*dstlayer;
+	Memimage	*src;
+	Point		sp;
+	Warp		warp;
+	int		smooth;
+};
+
+static
+void
+ldrawop(Memimage *dst, Rectangle screenr, Rectangle clipr, void *etc, int insave)
+{
+	struct Draw *d;
+	Rectangle r;
+
+	d = etc;
+	if(insave && d->dstlayer->save == nil)
+		return;
+
+	if(insave){
+		r = rectsubpt(screenr, d->dstlayer->delta);
+		clipr = rectsubpt(clipr, d->dstlayer->delta);
+	}else
+		r = screenr;
+
+	/* now in logical coordinates */
+
+	/* clipr may have narrowed what we should draw on, so clip if necessary */
+	if(!rectinrect(r, clipr) && rectclip(&r, clipr) == 0)
+		return;
+	memlaffinewarp(dst, r, d->src, d->sp, d->warp, d->smooth);
+}
+
+void
+memlaffinewarp(Memimage *dst, Rectangle r, Memimage *src, Point p0, Warp w, int smooth)
+{
+	struct Draw d;
+	Rectangle srcr, tr;
+	Memlayer *dl, *sl;
+
+    Top:
+	if(dst->layer == nil && src->layer == nil){
+		memaffinewarp(dst, r, src, p0, w, smooth);
+		return;
+	}
+
+	/*
+ 	 * Convert to screen coordinates.
+	 */
+	dl = dst->layer;
+	if(dl != nil){
+		r.min.x += dl->delta.x;
+		r.min.y += dl->delta.y;
+		r.max.x += dl->delta.x;
+		r.max.y += dl->delta.y;
+    Clearlayer:
+		if(dl->clear){
+			if(src == dst){
+				p0.x += dl->delta.x;
+				p0.y += dl->delta.y;
+				src = dl->screen->image;
+			}
+			dst = dl->screen->image;
+			goto Top;
+		}
+	}
+
+	sl = src->layer;
+	if(sl != nil){
+		p0.x += sl->delta.x;
+		p0.y += sl->delta.y;
+		srcr.min.x += sl->delta.x;
+		srcr.min.y += sl->delta.y;
+		srcr.max.x += sl->delta.x;
+		srcr.max.y += sl->delta.y;
+	}
+
+	/*
+	 * Now everything is in screen coordinates.
+	 * mask is an image.  dst and src are images or obscured layers.
+	 */
+
+	/*
+	 * if dst and src are the same layer, just draw in save area and expose.
+	 */
+	if(dl != nil && dst == src){
+		if(dl->save == nil)
+			return;	/* refresh function makes this case unworkable */
+		if(rectXrect(r, srcr)){
+			tr = r;
+			if(srcr.min.x < tr.min.x)
+				tr.min.x = srcr.min.x;
+			if(srcr.min.y < tr.min.y)
+				tr.min.y = srcr.min.y;
+			if(srcr.max.x > tr.max.x)
+				tr.max.x = srcr.max.x;
+			if(srcr.max.y > tr.max.y)
+				tr.max.y = srcr.max.y;
+			memlhide(dst, tr);
+		}else{
+			memlhide(dst, r);
+			memlhide(dst, srcr);
+		}
+		memlaffinewarp(dl->save, rectsubpt(r, dl->delta), dl->save,
+			subpt(srcr.min, src->layer->delta), w, smooth);
+		memlexpose(dst, r);
+		return;
+	}
+
+	if(sl != nil){
+		if(sl->clear){
+			src = sl->screen->image;
+			if(dl != nil){
+				r.min.x -= dl->delta.x;
+				r.min.y -= dl->delta.y;
+				r.max.x -= dl->delta.x;
+				r.max.y -= dl->delta.y;
+			}
+			goto Top;
+		}
+		/* relatively rare case; use save area */
+		if(sl->save == nil)
+			return;	/* refresh function makes this case unworkable */
+		memlhide(src, srcr);
+		/* convert back to logical coordinates */
+		p0.x -= sl->delta.x;
+		p0.y -= sl->delta.y;
+		srcr.min.x -= sl->delta.x;
+		srcr.min.y -= sl->delta.y;
+		srcr.max.x -= sl->delta.x;
+		srcr.max.y -= sl->delta.y;
+		src = src->layer->save;
+	}
+
+	/*
+	 * src is now an image.  dst may be an image or a clear layer
+	 */
+	if(dst->layer == nil)
+		goto Top;
+	if(dst->layer->clear)
+		goto Clearlayer;
+
+	/*
+	 * dst is an obscured layer
+	 */
+	d.dstlayer = dl;
+	d.src = src;
+	d.sp = p0;
+	memmove(d.warp, w, sizeof(Warp));
+	d.smooth = smooth;
+	_memlayerop(ldrawop, dst, r, r, &d);
+}
--