[patch] keep aspect ratio on scaling



Hi, folks.

Attached is a patch which keeps the aspect ratio when using scaling.
I've tested it a bit with vinagre and it seems to work well, although
it's kind slower than before, I guess... (at least it's slower than
vncviewer :) ), cairo's fault?

Comments?
-- 
Jonh Wendell
http://www.bani.com.br
diff --git a/src/vncdisplay.c b/src/vncdisplay.c
index f779a63..1f4a948 100644
--- a/src/vncdisplay.c
+++ b/src/vncdisplay.c
@@ -347,14 +347,23 @@ static gboolean expose_event(GtkWidget *widget, GdkEventExpose *expose)
 	/* Draw the VNC display */
 	if (priv->pixmap) {
 		if (priv->allow_scaling) {
-			double sx, sy;
+			double sx, sy, scale;
 			/* Scale to fill window */
 			sx = (double)ww / (double)priv->fb.width;
 			sy = (double)wh / (double)priv->fb.height;
-			cairo_scale(cr, sx, sy);
+			scale = MIN(sx, sy);
+			mx = MAX (0, (ww - priv->fb.width*scale)) / 2;
+			my = MAX (0, (wh - priv->fb.height*scale)) / 2;
+
+			cairo_rectangle(cr, 0, 0, ww, wh);
+			cairo_rectangle(cr, mx + priv->fb.width*scale, my,
+					-1 * priv->fb.width*scale, priv->fb.height*scale);
+			cairo_fill(cr);
+
+			cairo_scale(cr, scale, scale);
 			gdk_cairo_set_source_pixmap(cr,
 						    priv->pixmap,
-						    0, 0);
+						    mx/scale, my/scale);
 		} else {
 			gdk_cairo_set_source_pixmap(cr,
 						    priv->pixmap,
@@ -362,7 +371,6 @@ static gboolean expose_event(GtkWidget *widget, GdkEventExpose *expose)
 		}
 		cairo_paint(cr);
 	}
-
 	cairo_destroy(cr);
 #else
 	x = MIN(expose->area.x - mx, priv->fb.width);
@@ -607,14 +615,18 @@ static gboolean motion_event(GtkWidget *widget, GdkEventMotion *motion)
 
 	/* First apply adjustments to the coords in the motion event */
 	if (priv->allow_scaling) {
-		double sx, sy;
-		sx = (double)priv->fb.width / (double)ww;
-		sy = (double)priv->fb.height / (double)wh;
+		double sx, sy, scale, mx, my;
+		sx = (double)ww / (double)priv->fb.width;
+		sy = (double)wh / (double)priv->fb.height;
+
+		scale = MIN(sx, sy);
+		mx = MAX (0, (ww - priv->fb.width*scale)) / 2;
+		my = MAX (0, (wh - priv->fb.height*scale)) / 2;
 
 		/* Scaling the desktop, so scale the mouse coords
 		 * by same ratio */
-		motion->x *= sx;
-		motion->y *= sy;
+		motion->x = (motion->x - mx) / scale;
+		motion->y = (motion->y - my) / scale;
 	} else {
 		int mw = 0, mh = 0;
 
@@ -840,16 +852,21 @@ static gboolean on_update(void *opaque, int x, int y, int w, int h)
 	gdk_drawable_get_size(widget->window, &ww, &wh);
 
 	if (priv->allow_scaling) {
-		double sx, sy;
+		double sx, sy, scale, mx, my;
 
 		/* Scale the VNC region to produce expose region */
 
 		sx = (double)ww / (double)priv->fb.width;
 		sy = (double)wh / (double)priv->fb.height;
-		x *= sx;
-		y *= sy;
-		w *= sx;
-		h *= sy;
+
+		scale = MIN(sx, sy);
+		mx = MAX (0, (ww - priv->fb.width*scale)) / 2;
+		my = MAX (0, (wh - priv->fb.height*scale)) / 2;
+
+		x = x * scale + mx;
+		y = y * scale + my;
+		w = w * scale;
+		h = h * scale;
 	} else {
 		int mw = 0, mh = 0;
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]