shithub: view

Download patch

ref: 0617f98c17987d70020991f9536d6794b0c12093
parent: 032d83f1b0e022c09886d0a57815615332fce7c2
author: phil9 <telephil9@gmail.com>
date: Fri Nov 26 00:23:49 EST 2021

initial zoom support

	this is not fully functional as we are applying transformations
	to the zoomed image instead of the original one for the time being

--- a/view.c
+++ b/view.c
@@ -21,11 +21,28 @@
 Mousectl *mctl;
 Keyboardctl *kctl;
 Image *bg;
+Image *orig;
 Image *img;
 Point pos;
+int zoomlevel;
 
+const char* zoomlevels[] = {
+	"25%", "33%", "50%", "75%",
+	"100%",
+	"150%", "200%", "300%", "400%",
+};
+
 enum
 {
+	Defaultzoomlevel = 4,
+	Nzoomlevels = nelem(zoomlevels),
+};
+
+enum
+{
+	Mzoomin,
+	Mzoomout,
+	Morigsize,
 	Mhflip,
 	Mvflip,
 	Mrotleft,
@@ -34,6 +51,9 @@
 };
 char *menu2str[] =
 {
+	"zoom in",
+	"zoom out",
+	"orig. size",
 	"flip horiz.",
 	"flip vert.",
 	"rotate left",
@@ -133,6 +153,8 @@
 	i = load(filename);
 	if(i == nil)
 		return -1;
+	freeimage(orig);
+	orig = nil;
 	freeimage(img);
 	img = i;
 	pos = subpt(ZP, img->r.min);
@@ -241,20 +263,72 @@
 Image*
 rotate(int op)
 {
-	static char *opcmd[] = {
-		[Mhflip]	= "rotate -l",
-		[Mvflip]	= "rotate -u",
-		[Mrotleft]	= "rotate -r 270",
-		[Mrotright]	= "rotate -r 90",
-	};
-	if(op < 0 || op > 3){
+	const char *cmd;
+
+	switch(op){
+	case Mhflip:
+		cmd = "rotate -l";
+		break;
+	case Mvflip:
+		cmd = "rotate -u";
+		break;
+	case Mrotleft:
+		cmd = "rotate -r 270";
+		break;
+	case Mrotright:
+		cmd = "rotate -r 90";
+		break;
+	default:
 		werrstr("invalid rotate op");
 		return nil;
 	}
-	return ipipeto(img, opcmd[op]);
+	return ipipeto(img, cmd);
 }
 
 void
+zoom(int zop)
+{
+	Image *i;
+	char cmd[255];
+
+	switch(zop){
+	case Mzoomin:
+		if(zoomlevel + 1 >= Nzoomlevels)
+			return;
+		++zoomlevel;
+		break;
+	case Mzoomout:
+		if(zoomlevel == 0)
+			return;
+		--zoomlevel;
+		break;
+	case Morigsize:
+		if(zoomlevel == Defaultzoomlevel)
+			return;
+		zoomlevel = Defaultzoomlevel;
+		img = orig;
+		goto Redraw;
+	}
+	if(snprint(cmd, sizeof cmd, "resize -x %s", zoomlevels[zoomlevel]) <= 0){
+		fprint(2, "error creating zoom command: %r\n"); /* XXX */
+		return;
+	}
+	i = ipipeto(orig == nil ? img : orig, cmd);
+	if(i == nil){
+		fprint(2, "unable to zoom image: %r\n"); /* XXX */
+		return;
+	}
+	if(orig == nil)
+		orig = img;
+	else
+		freeimage(img);
+	img = i;
+Redraw:
+	pos = subpt(ZP, img->r.min);
+	redraw();
+}
+
+void
 menu2hit(void)
 {
 	Image *i;
@@ -264,6 +338,11 @@
 	i = nil;
 	n = menuhit(2, mctl, &menu2, nil);
 	switch(n){
+	case Mzoomin:
+	case Mzoomout:
+	case Morigsize:
+		zoom(n);
+		return;
 	case Mhflip:
 	case Mvflip:
 	case Mrotleft:
@@ -275,12 +354,12 @@
 		}
 		break;
 	case Mpipeto:
-		if(enter("command:", buf, sizeof buf, mctl, kctl, nil) > 0){
-			i = ipipeto(img, buf);
-			if(i == nil){
-				fprint(2, "unable to pipe image: %r\n");
-				return;
-			}
+		if(enter("command:", buf, sizeof buf, mctl, kctl, nil) <= 0)
+			return;
+		i = ipipeto(img, buf);
+		if(i == nil){
+			fprint(2, "unable to pipe image: %r\n");
+			return;
 		}
 		break;
 	}
@@ -365,6 +444,7 @@
 	}; 
 
 	img = nil;
+	zoomlevel = Defaultzoomlevel;
 	ARGBEGIN{
 	default:
 		usage();