[LyX/2.3.x] Set a maximum value to zoom level

Jean-Marc Lasgouttes lasgouttes at lyx.org
Wed Nov 23 16:57:44 UTC 2022


commit c203a842fce88f7313ceb6da99f6a4a10f50f365
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date:   Tue Feb 8 19:42:17 2022 +0100

    Set a maximum value to zoom level
    
    The minimal vamue is set to 10%, let's set the max to 1000%. This
    avoids crashes when characters are too large.
    
    The code is refactored to be more compact and the tests are more precise.
    
    Fixes bug #12452.
    
    (cherry picked from commit 5259b6ba62fd4e31c260d73cbdfdb66847afcb98)
---
 src/frontends/qt4/GuiView.cpp |   76 +++++++++++++++++++---------------------
 src/frontends/qt4/GuiView.h   |    2 +
 status.23x                    |    1 +
 3 files changed, 39 insertions(+), 40 deletions(-)

diff --git a/src/frontends/qt4/GuiView.cpp b/src/frontends/qt4/GuiView.cpp
index b28d926..f53df68 100644
--- a/src/frontends/qt4/GuiView.cpp
+++ b/src/frontends/qt4/GuiView.cpp
@@ -780,9 +780,8 @@ bool GuiView::restoreLayout()
 	QSettings settings;
 	zoom_ratio_ = settings.value("zoom_ratio", 1.0).toDouble();
 	// Actual zoom value: default zoom + fractional offset
-	int zoom = lyxrc.defaultZoom * zoom_ratio_;
-	if (zoom < static_cast<int>(zoom_min_))
-		zoom = zoom_min_;
+	int zoom = (int)(lyxrc.defaultZoom * zoom_ratio_);
+	zoom = min(max(zoom, zoom_min_), zoom_max_);
 	lyxrc.currentZoom = zoom;
 	devel_mode_ = settings.value("devel_mode", devel_mode_).toBool();
 	settings.beginGroup("views");
@@ -1818,6 +1817,30 @@ void GuiView::resetAutosaveTimers()
 }
 
 
+namespace {
+
+double zoomRatio(FuncRequest const & cmd, double const zr)
+{
+	if (cmd.argument().empty()) {
+		if (cmd.action() == LFUN_BUFFER_ZOOM)
+			return 1.0;
+		else if (cmd.action() == LFUN_BUFFER_ZOOM_IN)
+			return zr + 0.1;
+		else // cmd.action() == LFUN_BUFFER_ZOOM_OUT
+			return zr - 0.1;
+	} else {
+		if (cmd.action() == LFUN_BUFFER_ZOOM)
+			return convert<int>(cmd.argument()) / double(lyxrc.defaultZoom);
+		else if (cmd.action() == LFUN_BUFFER_ZOOM_IN)
+			return zr + convert<int>(cmd.argument()) / 100.0;
+		else // cmd.action() == LFUN_BUFFER_ZOOM_OUT
+			return zr - convert<int>(cmd.argument()) / 100.0;
+	}
+}
+
+}
+
+
 bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
 {
 	bool enable = true;
@@ -2122,32 +2145,20 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
 		break;
 
 	case LFUN_BUFFER_ZOOM_OUT:
-	case LFUN_BUFFER_ZOOM_IN: {
-		// only diff between these two is that the default for ZOOM_OUT
-		// is a neg. number
-		bool const neg_zoom =
-			convert<int>(cmd.argument()) < 0 ||
-			(cmd.action() == LFUN_BUFFER_ZOOM_OUT && cmd.argument().empty());
-		if (lyxrc.currentZoom <= zoom_min_ && neg_zoom) {
+	case LFUN_BUFFER_ZOOM_IN:
+	case LFUN_BUFFER_ZOOM: {
+		int const zoom = (int)(lyxrc.defaultZoom * zoomRatio(cmd, zoom_ratio_));
+		if (zoom < zoom_min_) {
 			docstring const msg =
 				bformat(_("Zoom level cannot be less than %1$d%."), zoom_min_);
 			flag.message(msg);
 			enable = false;
-		} else
-			enable = doc_buffer;
-		break;
-	}
-
-	case LFUN_BUFFER_ZOOM: {
-		bool const less_than_min_zoom =
-			!cmd.argument().empty() && convert<int>(cmd.argument()) < zoom_min_;
-		if (lyxrc.currentZoom <= zoom_min_ && less_than_min_zoom) {
+		} else if (zoom > zoom_max_) {
 			docstring const msg =
-				bformat(_("Zoom level cannot be less than %1$d%."), zoom_min_);
+				bformat(_("Zoom level cannot be more than %1$d%."), zoom_max_);
 			flag.message(msg);
 			enable = false;
-		}
-		else
+		} else
 			enable = doc_buffer;
 		break;
 	}
@@ -4223,26 +4234,11 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
 		case LFUN_BUFFER_ZOOM_IN:
 		case LFUN_BUFFER_ZOOM_OUT:
 		case LFUN_BUFFER_ZOOM: {
-			if (cmd.argument().empty()) {
-				if (cmd.action() == LFUN_BUFFER_ZOOM)
-					zoom_ratio_ = 1.0;
-				else if (cmd.action() == LFUN_BUFFER_ZOOM_IN)
-					zoom_ratio_ += 0.1;
-				else
-					zoom_ratio_ -= 0.1;
-			} else {
-				if (cmd.action() == LFUN_BUFFER_ZOOM)
-					zoom_ratio_ = convert<int>(cmd.argument()) / double(lyxrc.defaultZoom);
-				else if (cmd.action() == LFUN_BUFFER_ZOOM_IN)
-					zoom_ratio_ += convert<int>(cmd.argument()) / 100.0;
-				else
-					zoom_ratio_ -= convert<int>(cmd.argument()) / 100.0;
-			}
+			zoom_ratio_ = zoomRatio(cmd, zoom_ratio_);
 
 			// Actual zoom value: default zoom + fractional extra value
-			int zoom = lyxrc.defaultZoom * zoom_ratio_;
-			if (zoom < static_cast<int>(zoom_min_))
-				zoom = zoom_min_;
+			int zoom = (int)(lyxrc.defaultZoom * zoom_ratio_);
+			zoom = min(max(zoom, zoom_min_), zoom_max_);
 
 			lyxrc.currentZoom = zoom;
 
diff --git a/src/frontends/qt4/GuiView.h b/src/frontends/qt4/GuiView.h
index e78df4b..0b2b1f3 100644
--- a/src/frontends/qt4/GuiView.h
+++ b/src/frontends/qt4/GuiView.h
@@ -478,6 +478,8 @@ private:
 	double zoom_ratio_ = 1.0;
 	/// Minimum zoom percentage
 	static int const zoom_min_ = 10;
+	/// Maximum zoom percentage
+	static int const zoom_max_ = 1000;
 
 	// movability flag of all toolbars
 	bool toolbarsMovable_;
diff --git a/status.23x b/status.23x
index c3d63f9..b6c8761 100644
--- a/status.23x
+++ b/status.23x
@@ -149,6 +149,7 @@ What's new
 
 - Fix broken modifier handling for Qt-5.12 on Mac (bug 12247).
 
+- Limit zoom value to 1000% to avoid crashes (bug 12452).
 
 
 * INTERNALS


More information about the lyx-cvs mailing list