From 77d6b1f91fbb2b4c9bd7cfe8113235f10fb20089 Mon Sep 17 00:00:00 2001 From: Matan Ziv-Av Date: Sun, 7 Aug 2022 11:25:43 +0300 Subject: [PATCH] Some fixes - Do not ignore imageSize, even though it seems to be unnecessary. - Check for end of text before trying to read it. - Fix text decoder underline test --- .../TerminalCharacterDecoderTest.cpp | 6 +++--- src/characters/Character.h | 1 + src/terminalDisplay/TerminalPainter.cpp | 21 +++++++++++++------ 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/autotests/TerminalCharacterDecoderTest.cpp b/src/autotests/TerminalCharacterDecoderTest.cpp index 81250bfc..2c75ed6a 100644 --- a/src/autotests/TerminalCharacterDecoderTest.cpp +++ b/src/autotests/TerminalCharacterDecoderTest.cpp @@ -45,10 +45,10 @@ void TerminalCharacterDecoderTest::testPlainTextDecoder_data() */ QTest::newRow("simple text with default rendition") << "hello" << QVector(6).fill(DEFAULT_RENDITION) << "hello"; QTest::newRow("simple text with bold rendition") << "hello" << QVector(6).fill(RE_BOLD) << "hello"; - QTest::newRow("simple text with underline and italic rendition") << "hello" << QVector(6).fill(RE_UNDERLINE | RE_ITALIC) << "hello"; + QTest::newRow("simple text with underline and italic rendition") << "hello" << QVector(6).fill(RE_UNDERLINE_BIT | RE_ITALIC) << "hello"; QTest::newRow("simple text with default rendition (shorten)") << "hello" << QVector(4).fill(DEFAULT_RENDITION) << "hello"; - QTest::newRow("simple text with underline rendition (shorten)") << "hello" << QVector(4).fill(RE_UNDERLINE) << "hello"; + QTest::newRow("simple text with underline rendition (shorten)") << "hello" << QVector(4).fill(RE_UNDERLINE_BIT) << "hello"; } void TerminalCharacterDecoderTest::testPlainTextDecoder() @@ -87,7 +87,7 @@ void TerminalCharacterDecoderTest::testHTMLDecoder_data() << R"(hello
)"; // The below is wrong; only the first rendition is used (eg ignores the |) QTest::newRow("simple text with underline and italic rendition") - << "hello" << QVector(6).fill(RE_UNDERLINE | RE_ITALIC) + << "hello" << QVector(6).fill(RE_UNDERLINE_BIT | RE_ITALIC) << R"(hello
)"; QTest::newRow("text with &") diff --git a/src/characters/Character.h b/src/characters/Character.h index 7b0c90eb..c8f0ca43 100644 --- a/src/characters/Character.h +++ b/src/characters/Character.h @@ -78,6 +78,7 @@ const RenditionFlags RE_UNDERLINE_DOUBLE= 2; const RenditionFlags RE_UNDERLINE_CURL = 3; const RenditionFlags RE_UNDERLINE_DOT = 4; const RenditionFlags RE_UNDERLINE_DASH = 5; +const RenditionFlags RE_UNDERLINE_BIT = (1 << 12); // Masks of flags that matter for drawing what is below/above the text const RenditionFlags RE_MASK_UNDER = RE_TRANSPARENT | RE_REVERSE | RE_CURSOR | RE_SELECTED; const RenditionFlags RE_MASK_ABOVE = RE_TRANSPARENT | RE_REVERSE | RE_CURSOR | RE_SELECTED | RE_STRIKEOUT | RE_CONCEAL | RE_OVERLINE | RE_UNDERLINE_MASK; diff --git a/src/terminalDisplay/TerminalPainter.cpp b/src/terminalDisplay/TerminalPainter.cpp index 669e1a0f..4f3e45a3 100644 --- a/src/terminalDisplay/TerminalPainter.cpp +++ b/src/terminalDisplay/TerminalPainter.cpp @@ -111,6 +111,15 @@ void TerminalPainter::drawContents(Character *image, paint.setLayoutDirection(Qt::LeftToRight); for (int y = rect.y(); y <= rect.bottom(); y++) { + int pos = m_parentDisplay->loc(0, y); + if (pos > imageSize) { + break; + } + int right = rect.right(); + if (pos + right > imageSize) { + right = imageSize - pos; + } + const int textY = topPadding + fontHeight * y; bool doubleHeightLinePair = false; int x = rect.x(); @@ -146,7 +155,6 @@ void TerminalPainter::drawContents(Character *image, const int textX = leftPadding + fontWidth * rect.x() * (doubleWidthLine ? 2 : 1); const int textWidth = fontWidth * rect.width(); const int textHeight = doubleHeight && !doubleHeightLinePair ? fontHeight / 2 : fontHeight; - int pos = m_parentDisplay->loc(0, y); // move the calculated area to take account of scaling applied to the painter. // the position of the area from the origin (0,0) is scaled @@ -178,7 +186,7 @@ void TerminalPainter::drawContents(Character *image, RenditionFlags oldRendition = -1; QColor oldColor = QColor(); - for (; x <= rect.right(); x++) { + for (; x <= right; x++) { if (x > lastNonSpace) { // What about the cursor? // break; @@ -623,8 +631,8 @@ void TerminalPainter::drawBelowText(QPainter &painter, x = i + startX; } - if (first || style[x].rendition.all != style[lastX].rendition.all || style[x].foregroundColor != style[lastX].foregroundColor - || style[x].backgroundColor != style[lastX].backgroundColor || i == width) { + if (first || i == width || style[x].rendition.all != style[lastX].rendition.all || style[x].foregroundColor != style[lastX].foregroundColor + || style[x].backgroundColor != style[lastX].backgroundColor) { if (first) { first = false; } else { @@ -697,8 +705,9 @@ void TerminalPainter::drawAboveText(QPainter &painter, x = i + startX; } - if (first || ((style[x].rendition.all ^ style[lastX].rendition.all) & RE_MASK_ABOVE) || ((style[x].flags ^ style[lastX].flags) & EF_UNDERLINE_COLOR) - || style[x].foregroundColor != style[lastX].foregroundColor || style[x].backgroundColor != style[lastX].backgroundColor || i == width) { + if (first || i == width || ((style[x].rendition.all ^ style[lastX].rendition.all) & RE_MASK_ABOVE) + || ((style[x].flags ^ style[lastX].flags) & EF_UNDERLINE_COLOR) || style[x].foregroundColor != style[lastX].foregroundColor + || style[x].backgroundColor != style[lastX].backgroundColor) { if (first) { first = false; } else {