From 7d7d7302821682ca4d620b0d8d7e575e1a726c50 Mon Sep 17 00:00:00 2001 From: Malte Langkabel Date: Sun, 19 Jul 2026 21:25:16 +0200 Subject: [PATCH] Mitre pause-border corners to avoid double-darkening Clip each side of the pause vignette to a trapezoid so the four gradient strips meet along the corner diagonals instead of overlapping, which was compositing two 50% blacks into darker, oddly-shaded corners. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Y7N59FsLA5e2kuVdqe4Uhc --- src/ui/GameWorldView.cpp | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/src/ui/GameWorldView.cpp b/src/ui/GameWorldView.cpp index a552723..c7a89f8 100644 --- a/src/ui/GameWorldView.cpp +++ b/src/ui/GameWorldView.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -1709,29 +1710,50 @@ void GameWorldView::drawPauseBorder(QPainter& painter) const QColor edge(0, 0, 0, 128); // 50% black at the viewport edge const QColor inner(0, 0, 0, 0); // fully transparent toward the center + const qreal w = width(); + const qreal h = height(); + painter.save(); // Each side is a linear gradient fading from `edge` at the viewport border to - // `inner` toward the center. Corners overlap and read as a natural vignette. + // `inner` toward the center. The four sides are clipped to trapezoids that meet + // along the corner diagonals (a mitred picture frame), so the strips never + // overlap and don't double-darken the corners. Because the border thickness is + // the same on every side, both adjoining gradients evaluate equally along each + // 45-degree diagonal and join seamlessly. + const std::function drawSide = + [&](const QLinearGradient& gradient, const QPolygonF& trapezoid) { + QPainterPath clip; + clip.addPolygon(trapezoid); + painter.save(); + painter.setClipPath(clip); + painter.fillRect(QRectF(0, 0, w, h), gradient); + painter.restore(); + }; + QLinearGradient left(0, 0, borderPx, 0); left.setColorAt(0.0, edge); left.setColorAt(1.0, inner); - painter.fillRect(QRectF(0, 0, borderPx, height()), left); + drawSide(left, QPolygonF({ QPointF(0, 0), QPointF(borderPx, borderPx), + QPointF(borderPx, h - borderPx), QPointF(0, h) })); - QLinearGradient right(width(), 0, width() - borderPx, 0); + QLinearGradient right(w, 0, w - borderPx, 0); right.setColorAt(0.0, edge); right.setColorAt(1.0, inner); - painter.fillRect(QRectF(width() - borderPx, 0, borderPx, height()), right); + drawSide(right, QPolygonF({ QPointF(w, 0), QPointF(w - borderPx, borderPx), + QPointF(w - borderPx, h - borderPx), QPointF(w, h) })); QLinearGradient top(0, 0, 0, borderPx); top.setColorAt(0.0, edge); top.setColorAt(1.0, inner); - painter.fillRect(QRectF(0, 0, width(), borderPx), top); + drawSide(top, QPolygonF({ QPointF(0, 0), QPointF(w, 0), + QPointF(w - borderPx, borderPx), QPointF(borderPx, borderPx) })); - QLinearGradient bottom(0, height(), 0, height() - borderPx); + QLinearGradient bottom(0, h, 0, h - borderPx); bottom.setColorAt(0.0, edge); bottom.setColorAt(1.0, inner); - painter.fillRect(QRectF(0, height() - borderPx, width(), borderPx), bottom); + drawSide(bottom, QPolygonF({ QPointF(0, h), QPointF(w, h), + QPointF(w - borderPx, h - borderPx), QPointF(borderPx, h - borderPx) })); painter.restore(); }