From 4522bfae90c64e2ffb7eb2a8b0e6203536bb392a Mon Sep 17 00:00:00 2001 From: Luca Carlon Date: Fri, 19 Sep 2025 19:27:30 +0200 Subject: [PATCH] Improvements to curly underline This commit tried to improves the look of curly underline implemented in 5ab23a96 by replacing arcs with quadratic Bezier curves. The performance of the render is mostly unaltered. Enabling antialiasing provides an even better result, but the performance impact is too relevant. --- src/terminalDisplay/TerminalPainter.cpp | 29 +++++++++++++++---------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/terminalDisplay/TerminalPainter.cpp b/src/terminalDisplay/TerminalPainter.cpp index 0c1ffb89d..9d6e724f1 100644 --- a/src/terminalDisplay/TerminalPainter.cpp +++ b/src/terminalDisplay/TerminalPainter.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -915,24 +916,30 @@ void TerminalPainter::drawAboveText(QPainter &painter, painter.drawLine(QLineF(x1, y, x2, y)); if (underline == RE_UNDERLINE_DOUBLE || underline == RE_UNDERLINE_CURL) { const int fontHeight = m_parentDisplay->terminalFont()->fontHeight(); - const int amplitude = fontHeight / 8; + const qreal amplitude = fontHeight / 8; if (underline == RE_UNDERLINE_DOUBLE) { if (amplitude) painter.drawLine(x1, y - amplitude, x2, y - amplitude); } else { - y = std::max(static_cast(0), y - amplitude); + y = std::max(static_cast(0), y - amplitude / 2); assert(underline == RE_UNDERLINE_CURL); const int len = x2 - x1; if (len > 0) { - const int halfPeriodsPerGlyph = 2; - const int numHalfPeriods = len * halfPeriodsPerGlyph / fontWidth; - for (int j = 0; j < numHalfPeriods; j++) { - const int begin = j * len / numHalfPeriods; - const int end = (j + 1) * len / numHalfPeriods; - const qreal angle1 = 0.0; - const qreal angle2 = 360.0 * 16.0 * ((j % 2 == 0) ? 0.5 : -0.5); - painter.drawArc(x1 + begin, y, end-begin, amplitude, angle1, angle2); - } + const qreal desiredWavelength = fontWidth / 1.2; + const int cycles = std::max(1, static_cast(len / desiredWavelength)); + const qreal wavelength = static_cast(len) / cycles; + const qreal halfWavelength = wavelength / 2.0; + const qreal quarterWavelength = halfWavelength / 2.0; + const qreal threeQuarterWavelength = 3 * quarterWavelength; + QPainterPath segment; + segment.moveTo(0, 0); + segment.quadTo(quarterWavelength, -amplitude, halfWavelength, 0); + segment.quadTo(threeQuarterWavelength, amplitude, wavelength, 0); + QPainterPath path; + path.moveTo(x1, y); + for (int i = 0; i < cycles; ++i) + path.addPath(segment.translated(x1 + i * wavelength, y)); + painter.drawPath(path); } } }