shithub: pain

Download patch

ref: f48eac8988cf8ce8b18f49a97b26695c7b44ee52
parent: 672d39e9b1697da4b955f7a8b692994dfe916be7
author: jmq <jmq@jmq.sh>
date: Fri Aug 22 22:35:39 EDT 2025

fixing pill resize

--- a/main.c
+++ b/main.c
@@ -24,7 +24,7 @@
 int CanvasMoved = 1;
 Rectangle CanvasSize;
 Rectangle ZoomedSize;
-Point CanvasAt = {0};
+Point CanvasAt = {0};						// Position of the canvas relative to wuindow position
 Layer * RootLayer = nil;
 Layer * CurrentLayer = nil;
 Image * Background = nil;
@@ -172,20 +172,45 @@
 
 	if (Background == nil)
 		setbackground(BACKGROUNDCOLOR);
-
+	
+	// vr (Viewable Rectangle) is just a rectangle with the dimensions
+	// of the zoomed canvas that starts at the position of the canvas
+	// relative to the window
 	vr = rectaddpt(ZoomedSize, CanvasAt);
+
+	// Get the intersect rectangle between vr and the window.
+	// Remember, vr's position is relative to the window, meaning
+	// the window's position, as far as vr is concerned, is the origin.
+	// After this, vr is just a rectangle that shows the viewable part
+	// of the zoomed in canvas, relative to the window's position 
 	i = rectclip(&vr,Rect(0, 0, Dx(screen->r), Dy(screen->r)));
+
+	// If we are clipping (i == true) and, either we Should Redraw (sr) or,
+	// the canvas moved since we last drew it and the area of vr is still the same
+	// as the zoomed size we want. The reason we do the last check, is because
+	// there's no need to redraw the Zoomed Image if vr hasn't changed in size,
+	// since it's position doesn't affect it's contents.
 	if (i && ((CanvasMoved && Ar(vr) != Ar(ZoomedSize)) || sr)) {
-		p = CanvasAt;
-		if (p.x < 0) {
-			vr.max.x += -p.x;
-			p.x = 0;
-		}
-		if (p.y < 0) {
-			vr.max.y += -p.y;
-			p.y = 0;
-		}
-		vr = rectsubpt(vr, p);
+		// Now this might look a little confusing, and that's because this is actually a workaround
+		// to a problem with resizeimage (and that function still gives me nightmares)
+		//
+		// The issue is that we want Zoomed Image to have only the visible part of the
+		// zoomed canvas (which is the whole point of vr). Now, this is fine for positive
+		// coordinates, but when the canvas starts on negative coordinates, resize image gets
+		// a little fucky. To fix that, I found that increasing the max coordinates of vr
+		// by the same amount their respecting origin origin is on the negative makes this work
+		// fine for some reson. Don't ask me why.
+ 		p = CanvasAt;
+ 		if (p.x < 0) {
+ 			vr.max.x += -p.x;
+ 			p.x = 0;
+ 		}
+ 		if (p.y < 0) {
+ 			vr.max.y += -p.y;
+ 			p.y = 0;
+ 		}
+ 		vr = rectsubpt(vr, p);
+
 		if (resizeimage(ZoomedImage, vr, Zoom, ViewImage, ZP) < 0)
 			sysfatal("resizeimage: %r");
 	}
--- a/pill/pill.c
+++ b/pill/pill.c
@@ -59,7 +59,7 @@
 		tr.max.y = tr.min.y + Dy(sr);
 	}
 
-	if ((t = allocimage(display, tr, s->chan, 1, DNofill)) == nil) {
+	if ((t = allocimage(display, tr, s->chan, 1, DTransparent)) == nil) {
 		werrstr("allocimage: %r");
 		return -1;
 	}
@@ -71,23 +71,19 @@
 		return -1;
 	}
 
-	if (Dx(tr) > Dx(sr)) {
-		scale = ((float)Dx(tr))/((float)Dx(sr));
-	} else {
-		scale = ((float)Dx(sr))/((float)Dx(tr));
-	}
-	p = dr.min;
+	scale = ((float)Dx(sr))/((float)Dx(tr));
+	p = ZP;
 	r.min = tr.min;
-	r.max.y = tr.max.y;
+	r.max.y = s->r.max.y;
 	
 	i = 0;
-	while (r.min.x < tr.max.x) {
-		draw(c, c->r, s, nil, p);
-		p.x += 1;
+	while (i < Dx(tr)) {
+		drawop(c, c->r, s, nil, p, S);
+		p.x = s->r.min.x + (int)(((float)i)*scale);
 
-		r.min.x = (int)(((float)(i))*scale) + tr.min.x;
-		r.max.x = (int)(((float)(i+1))*scale) + tr.min.x;
-		draw(t, r, c, nil, ZP);
+		r.min.x = i + tr.min.x;
+		r.max.x = r.min.x + 1;
+		draw(screen, r, c, nil, ZP);
 		i+=1;
 	}
 	
@@ -100,30 +96,29 @@
 		return -1;
 	}
 
-	if (Dy(tr) > Dy(sr)) {
-		scale = ((float)Dy(tr))/((float)Dy(sr));
-	} else {
-		scale = ((float)Dy(sr))/((float)Dy(tr));
-	}
+	scale = ((float)Dy(sr))/((float)Dy(tr));
 
 	p = dr.min;
 	r.min = tr.min;
 	r.max.x = tr.max.x;
-	r.max.y = r.min.y + MAX(1.0, scale);
 
-	i = 0;
-	while (r.min.y < dr.max.y) {
-		draw(c, c->r, t, nil, p);
-		p.y += 1;
-		
-		// Move the draw rectangle for the temporary image scale
-		// rectangles to the right
-		r.min.y = (int)(((float)(i))*scale) + dr.min.x;
-		r.max.y = (int)(((float)(i+1))*scale) + dr.min.x;
-		draw(d, r, c, nil, ZP);
-		i+=1;
-	}
+// 	i = 0;
+// 	while (r.min.y < dr.max.y) {
+// 		draw(c, c->r, t, nil, p);
+// 		p.y = (int)(((float)i)*scale);
+// 		
+// 		// Move the draw rectangle for the temporary image scale
+// 		// rectangles to the right
+// 		r.min.y = i + tr.min.x;
+// 		r.max.y =i + tr.min.x + 1;
+// 		Rectangle fr = rectaddpt(r, d->r.min);
+// 		draw(d, fr, c, nil, ZP);
+// 		i+=1;
+// 	}
 
+	draw(d, d->r, t, nil, d->r.min);
+
+
 	freeimage(t);
 	freeimage(c);
 	
@@ -304,10 +299,14 @@
 static void
 drawcanvas(void)
 {
-	print("VirtualWindow: %R\n", VirtualWindow->r);
-	print("screen: %R\n", screen->r);
-	draw(screen, screen->r, Background, nil, ZP);
-	draw(screen, screen->r, VirtualWindow, nil, ZP);
+	Rectangle vwr = VirtualWindow->r;
+	//print("VirtualWindow: %R\n", VirtualWindow->r);
+	//print("screen: %R\n", screen->r);
+	VirtualWindow->r.min = screen->r.min;
+	VirtualWindow->r.max.x = VirtualWindow->r.min.x + Dx(vwr);
+	VirtualWindow->r.max.y = VirtualWindow->r.min.y + Dy(vwr);
+	//draw(screen, screen->r, Background, nil, ZP);
+	//draw(screen, screen->r, VirtualWindow, nil, ZP);
 }
 
 void
@@ -330,11 +329,12 @@
 		freeimage(VirtualWindow);
 	}
 
-	VirtualWindow = allocimage(display, screen->r, RGBA32, 1, DTransparent);
+	VirtualWindow = allocimage(display, screen->r, RGBA32, 0, DTransparent);
 	if (VirtualWindow == nil) {
 		sysfatal("initcanvas: %r");
 	}
 
+	draw(screen, screen->r, Background, nil, ZP);
 	rc = resizeimage(VirtualWindow, HuePicker);
 	if (rc < 0) {
 		sysfatal("resizeimage: %r");
--- a/resize.c
+++ b/resize.c
@@ -11,7 +11,6 @@
 int
 resizeimage(Image * di, Rectangle dr, float scale, Image * si, Point sp)
 {
-	float d, f;
 	Point p;
 	Rectangle r, tr;
 	int i;
@@ -68,7 +67,7 @@
 		// image, for every line on the target image will we will skip over multiple
 		// lines on the source image.
 		
-		// Move the ci one 1/scale space to the righ
+		// Move the ci one 1 space to the righ
 		draw(ci, ci->r, si, nil, p);
 		p.x += 1;
 		
@@ -108,8 +107,6 @@
 	r.max.y = r.min.y + MAX(1.0, scale);
 
 	i = 0;
-	d = p.y;
-	f = r.min.y;
 	while (r.min.y < dr.max.y) {
 		// If we are expanding an image, one scan on the source image will result on
 		// multiple draws on the target image. Conversively, if we are shrinking an
@@ -116,7 +113,7 @@
 		// image, for every line on the target image will we will skip over multiple
 		// lines on the source image.
 		
-		// Move the ci one 1/scale space to the right
+		// Move the ci one 1 space down
 		draw(ci, ci->r, t, nil, p);
 		p.y += 1;
 		
--