From 6d9f30c343f0c25af25621e478a1dbbb7443f87d Mon Sep 17 00:00:00 2001 From: Rubidium Date: Fri, 3 Jan 2025 14:07:13 +0100 Subject: [PATCH] Codefix: prevent matrix overflows on high resolution monitors --- src/graph_gui.cpp | 2 +- src/widget.cpp | 13 ++++++------- src/widget_type.h | 17 ++++------------- 3 files changed, 11 insertions(+), 21 deletions(-) diff --git a/src/graph_gui.cpp b/src/graph_gui.cpp index 683d5bb3c8..2debcc9337 100644 --- a/src/graph_gui.cpp +++ b/src/graph_gui.cpp @@ -555,7 +555,7 @@ public: resize.width = 0; resize.height = 0; - this->GetWidget(WID_GRAPH_RANGE_MATRIX)->SetMatrixDimension(1, ClampTo(std::size(this->ranges))); + this->GetWidget(WID_GRAPH_RANGE_MATRIX)->SetMatrixDimension(1, ClampTo(std::size(this->ranges))); break; case WID_GRAPH_GRAPH: { diff --git a/src/widget.cpp b/src/widget.cpp index a57523faf0..efc25f5f47 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -398,15 +398,15 @@ static inline void DrawInset(const Rect &r, Colours colour, TextColour text_colo * @param r Rectangle of the matrix background. * @param colour Colour of the background. * @param clicked Matrix is rendered lowered. - * @param data Data of the widget, number of rows and columns of the widget. + * @param num_columns The number of columns in the matrix. + * @param num_rows The number of rows in the matrix. * @param resize_x Matrix resize unit size. * @param resize_y Matrix resize unit size. */ -static inline void DrawMatrix(const Rect &r, Colours colour, bool clicked, uint16_t data, uint resize_x, uint resize_y) +static inline void DrawMatrix(const Rect &r, Colours colour, bool clicked, uint32_t num_columns, uint32_t num_rows, uint resize_x, uint resize_y) { DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, (clicked) ? FR_LOWERED : FR_NONE); - int num_columns = GB(data, MAT_COL_START, MAT_COL_BITS); // Lower 8 bits of the widget data: Number of columns in the matrix. int column_width; // Width of a single column in the matrix. if (num_columns == 0) { column_width = resize_x; @@ -415,7 +415,6 @@ static inline void DrawMatrix(const Rect &r, Colours colour, bool clicked, uint1 column_width = r.Width() / num_columns; } - int num_rows = GB(data, MAT_ROW_START, MAT_ROW_BITS); // Upper 8 bits of the widget data: Number of rows in the matrix. int row_height; // Height of a single row in the matrix. if (num_rows == 0) { row_height = resize_y; @@ -1168,9 +1167,9 @@ void NWidgetCore::SetSpriteTip(SpriteID sprite, StringID tool_tip) * @param columns The number of columns in the matrix (0 for autoscaling). * @param rows The number of rows in the matrix (0 for autoscaling). */ -void NWidgetCore::SetMatrixDimension(uint8_t columns, uint8_t rows) +void NWidgetCore::SetMatrixDimension(uint32_t columns, uint32_t rows) { - this->widget_data.matrix = static_cast((rows << MAT_ROW_START) | (columns << MAT_COL_START)); + this->widget_data.matrix = { columns, rows }; } /** @@ -3028,7 +3027,7 @@ void NWidgetLeaf::Draw(const Window *w) break; case WWT_MATRIX: - DrawMatrix(r, this->colour, clicked, this->widget_data.matrix, this->resize_x, this->resize_y); + DrawMatrix(r, this->colour, clicked, this->widget_data.matrix.width, this->widget_data.matrix.height, this->resize_x, this->resize_y); break; case WWT_EDITBOX: { diff --git a/src/widget_type.h b/src/widget_type.h index 4075684c50..5f820a5a69 100644 --- a/src/widget_type.h +++ b/src/widget_type.h @@ -17,15 +17,6 @@ #include "gfx_type.h" #include "window_type.h" -/** Bits of the #WWT_MATRIX widget data. */ -/* Number of column bits of the WWT_MATRIX widget data. */ -static constexpr uint8_t MAT_COL_START = 0; ///< Lowest bit of the number of columns. -static constexpr uint8_t MAT_COL_BITS = 8; ///< Number of bits for the number of columns in the matrix. - -/* Number of row bits of the WWT_MATRIX widget data. */ -static constexpr uint8_t MAT_ROW_START = 8; ///< Lowest bit of the number of rows. -static constexpr uint8_t MAT_ROW_BITS = 8; ///< Number of bits for the number of rows in the matrix. - /** Values for an arrow widget */ enum ArrowWidgetValues : uint8_t { AWV_DECREASE, ///< Arrow to the left or in case of RTL to the right @@ -370,7 +361,7 @@ struct WidgetData { SpriteID sprite{}; ArrowWidgetValues arrow_widget_type{}; ResizeWidgetValues resize_widget_type{}; - uint32_t matrix{}; + Dimension matrix{}; }; /** @@ -385,7 +376,7 @@ public: void SetStringTip(StringID string, StringID tool_tip); void SetSprite(SpriteID sprite); void SetSpriteTip(SpriteID sprite, StringID tool_tip); - void SetMatrixDimension(uint8_t columns, uint8_t rows); + void SetMatrixDimension(uint32_t columns, uint32_t rows); void SetResizeWidgetType(ResizeWidgetValues type); void SetToolTip(StringID tool_tip); StringID GetToolTip() const; @@ -1261,9 +1252,9 @@ constexpr NWidgetPart SetResizeWidgetTypeTip(ResizeWidgetValues widget_type, Str * @param tip Tooltip of the widget. * @ingroup NestedWidgetParts */ -constexpr NWidgetPart SetMatrixDataTip(uint8_t cols, uint8_t rows, StringID tip = {}) +constexpr NWidgetPart SetMatrixDataTip(uint32_t cols, uint32_t rows, StringID tip = {}) { - return NWidgetPart{WPT_DATATIP, NWidgetPartDataTip{{.matrix = static_cast((rows << MAT_ROW_START) | (cols << MAT_COL_START))}, tip}}; + return NWidgetPart{WPT_DATATIP, NWidgetPartDataTip{{.matrix{ cols, rows }}, tip}}; } /**