From 7ff0d2bab7ebc5ddfb3684b625caef55ab1bbf50 Mon Sep 17 00:00:00 2001 From: Matan Ziv-Av Date: Mon, 3 Oct 2022 12:40:55 +0200 Subject: [PATCH] Change LineProperty from int to a class. It includes more than just flags, and will include even more information. --- src/Screen.cpp | 67 ++++++++++--------- src/Screen.h | 2 +- src/ScreenWindow.cpp | 4 +- src/Vt102Emulation.cpp | 12 ++-- src/autotests/HistoryTest.cpp | 6 +- .../TerminalCharacterDecoderTest.cpp | 4 +- src/characters/Character.h | 37 ++++++++-- .../TerminalImageFilterChain.cpp | 4 +- src/history/HistoryScroll.h | 2 +- src/history/HistoryScrollFile.cpp | 14 ++-- src/history/HistoryScrollFile.h | 2 +- src/history/HistoryScrollNone.cpp | 2 +- src/history/HistoryScrollNone.h | 2 +- src/history/compact/CompactHistoryScroll.cpp | 14 ++-- src/history/compact/CompactHistoryScroll.h | 2 +- src/terminalDisplay/TerminalDisplay.cpp | 14 ++-- src/terminalDisplay/TerminalPainter.cpp | 20 +++--- 17 files changed, 118 insertions(+), 90 deletions(-) diff --git a/src/Screen.cpp b/src/Screen.cpp index 3346af623..9cfb8db1d 100644 --- a/src/Screen.cpp +++ b/src/Screen.cpp @@ -92,7 +92,7 @@ Screen::Screen(int lines, int columns) , _lastDrawnChar(0) , _escapeSequenceUrlExtractor(nullptr) { - std::fill(_lineProperties.begin(), _lineProperties.end(), LINE_DEFAULT); + std::fill(_lineProperties.begin(), _lineProperties.end(), LineProperty()); _graphicsPlacements = std::vector>(); _hasGraphics = false; @@ -340,7 +340,7 @@ void Screen::reverseIndex() void Screen::nextLine() //=NEL { - _lineProperties[_cuY] = SetLineLength(_lineProperties[_cuY], _cuX); + _lineProperties[_cuY].length = _cuX; toStartOfLine(); index(); } @@ -632,14 +632,14 @@ void Screen::resizeImage(int new_lines, int new_columns) auto sessionController = _currentTerminalDisplay->sessionController(); auto terminal = sessionController->session()->foregroundProcessName(); if (terminal == QLatin1String("zsh")) { - while (cursorLine + cursorLineCorrection > 0 && (_lineProperties.at(cursorLine + cursorLineCorrection) & LINE_PROMPT_START) == 0) { + while (cursorLine + cursorLineCorrection > 0 && (_lineProperties.at(cursorLine + cursorLineCorrection).flags.f.prompt_start) == 0) { --cursorLineCorrection; } - if (cursorLine + cursorLineCorrection > 0 && (_lineProperties.at(cursorLine + cursorLineCorrection) & LINE_PROMPT_START) != 0) { - _lineProperties[cursorLine + cursorLineCorrection - 1] &= ~LINE_WRAPPED; + if (cursorLine + cursorLineCorrection > 0 && (_lineProperties.at(cursorLine + cursorLineCorrection).flags.f.prompt_start) != 0) { + _lineProperties[cursorLine + cursorLineCorrection - 1].flags.f.wrapped = 0; } else { cursorLineCorrection = 0; - while (cursorLine + cursorLineCorrection > 0 && (_lineProperties.at(cursorLine + cursorLineCorrection - 1) & LINE_WRAPPED) != 0) { + while (cursorLine + cursorLineCorrection > 0 && (_lineProperties.at(cursorLine + cursorLineCorrection - 1).flags.f.wrapped) != 0) { --cursorLineCorrection; } } @@ -650,7 +650,7 @@ void Screen::resizeImage(int new_lines, int new_columns) int currentPos = 0; while (currentPos < (cursorLine + cursorLineCorrection) && currentPos < (int)_screenLines.size() - 1) { // Join wrapped line in current position - if ((_lineProperties.at(currentPos) & LINE_WRAPPED) != 0) { + if ((_lineProperties.at(currentPos).flags.f.wrapped) != 0) { _screenLines[currentPos].append(_screenLines.at(currentPos + 1)); _screenLines.erase(_screenLines.begin() + currentPos + 1); _lineProperties.erase(_lineProperties.begin() + currentPos); @@ -666,12 +666,13 @@ void Screen::resizeImage(int new_lines, int new_columns) } // If need to move to line below, copy from the current line, to the next one. - if (lineSize > new_columns && !(_lineProperties.at(currentPos) & (LINE_DOUBLEHEIGHT_BOTTOM | LINE_DOUBLEHEIGHT_TOP))) { + if (lineSize > new_columns + && !(_lineProperties.at(currentPos).flags.f.doubleheight_bottom | _lineProperties.at(currentPos).flags.f.doubleheight_top)) { auto values = _screenLines.at(currentPos).mid(new_columns); _screenLines[currentPos].resize(new_columns); _lineProperties.insert(_lineProperties.begin() + currentPos + 1, _lineProperties.at(currentPos)); _screenLines.insert(_screenLines.begin() + currentPos + 1, std::move(values)); - _lineProperties[currentPos] |= LINE_WRAPPED; + _lineProperties[currentPos].flags.f.wrapped = 1; ++cursorLine; scrollPlacements(-1, currentPos); } @@ -705,7 +706,7 @@ void Screen::resizeImage(int new_lines, int new_columns) _lineProperties.resize(new_lines + 1); if (_lineProperties.size() > _screenLines.size()) { - std::fill(_lineProperties.begin() + _screenLines.size(), _lineProperties.end(), LINE_DEFAULT); + std::fill(_lineProperties.begin() + _screenLines.size(), _lineProperties.end(), LineProperty()); } _screenLines.resize(new_lines + 1); @@ -789,7 +790,7 @@ void Screen::copyFromHistory(Character *dest, int startLine, int count) const for (int line = startLine; line < startLine + count; ++line) { const int length = qMin(columns, _history->getLineLen(line)); const int destLineOffset = (line - startLine) * columns; - const int lastColumn = (_history->getLineProperty(line) & LINE_DOUBLEWIDTH) ? columns / 2 : columns; + const int lastColumn = (_history->getLineProperty(line).flags.f.doublewidth) ? columns / 2 : columns; _history->getCells(line, 0, length, dest + destLineOffset); @@ -820,7 +821,7 @@ void Screen::copyFromScreen(Character *dest, int startLine, int count) const for (int line = startLine; line < endLine; ++line) { const int destLineOffset = (line - startLine) * columns; - const int lastColumn = (line < (int)_lineProperties.size() && _lineProperties[line] & LINE_DOUBLEWIDTH) ? columns / 2 : columns; + const int lastColumn = (line < (int)_lineProperties.size() && _lineProperties[line].flags.f.doublewidth) ? columns / 2 : columns; const ImageLine srcLine = _screenLines.at(line); const int length = qMin(columns, srcLine.size()); @@ -915,7 +916,7 @@ QVector Screen::getLineProperties(int startLine, int endLine) cons int Screen::getScreenLineColumns(const int line) const { - if (line < (int)_lineProperties.size() && _lineProperties.at(line) & LINE_DOUBLEWIDTH) { + if (line < (int)_lineProperties.size() && _lineProperties.at(line).flags.f.doublewidth) { return _columns / 2; } @@ -1041,7 +1042,7 @@ void Screen::initTabStops() void Screen::newLine() { if (getMode(MODE_NewLine)) { - _lineProperties[_cuY] = SetLineLength(_lineProperties[_cuY], _cuX); + _lineProperties[_cuY].length = _cuX; toStartOfLine(); } @@ -1085,7 +1086,7 @@ void Screen::displayCharacter(uint c) do { if (charToCombineWithX > 0) { --charToCombineWithX; - } else if (charToCombineWithY > 0 && _lineProperties.at(charToCombineWithY - 1) & LINE_WRAPPED) { // Try previous line + } else if (charToCombineWithY > 0 && _lineProperties.at(charToCombineWithY - 1).flags.f.wrapped) { // Try previous line --charToCombineWithY; charToCombineWithX = _screenLines.at(charToCombineWithY).length() - 1; } else { @@ -1213,7 +1214,7 @@ void Screen::displayCharacter(uint c) notcombine: if (_cuX + w > getScreenLineColumns(_cuY)) { if (getMode(MODE_Wrap)) { - _lineProperties[_cuY] = static_cast(_lineProperties.at(_cuY) | LINE_WRAPPED); + _lineProperties[_cuY].flags.f.wrapped = 1; nextLine(); } else { _cuX = qMax(getScreenLineColumns(_cuY) - w, 0); @@ -1269,8 +1270,8 @@ notcombine: if (_replMode != REPL_None && std::make_pair(_cuY, _cuX) >= _replModeEnd) { _replModeEnd = std::make_pair(_cuY, _cuX); } - if (LineLength(_lineProperties[_cuY]) < _cuX) { - _lineProperties[_cuY] = SetLineLength(_lineProperties[_cuY], _cuX); + if (_lineProperties[_cuY].length < _cuX) { + _lineProperties[_cuY].length = _cuX; } if (_escapeSequenceUrlExtractor) { @@ -1444,16 +1445,16 @@ void Screen::clearImage(int loca, int loce, char c, bool resetLineRendition) const int startCol = (y == topLine) ? loca % _columns : 0; if (endCol < _columns - 1 || startCol > 0) { - _lineProperties[y] &= ~LINE_WRAPPED; - if (LineLength(_lineProperties[y]) < endCol && LineLength(_lineProperties[y]) > startCol) { - _lineProperties[y] = SetLineLength(_lineProperties[y], startCol); + _lineProperties[y].flags.f.wrapped = 0; + if (_lineProperties[y].length < endCol && _lineProperties[y].length > startCol) { + _lineProperties[y].length = startCol; } } else { if (resetLineRendition) { - _lineProperties[y] = LINE_DEFAULT; + _lineProperties[y] = LineProperty(); } { - _lineProperties[y] &= ~(LINE_WRAPPED | LINE_PROMPT_START | LINE_INPUT_START | LINE_OUTPUT_START); + _lineProperties[y].flags.all &= ~(LINE_WRAPPED | LINE_PROMPT_START | LINE_INPUT_START | LINE_OUTPUT_START); } } @@ -1777,7 +1778,7 @@ void Screen::setSelectionEnd(const int x, const int y, const bool trimTrailingWh } } else { size_t line = bottomRow - _history->getLines(); - const int lastColumn = (line < _lineProperties.size() && _lineProperties[line] & LINE_DOUBLEWIDTH) ? _columns / 2 : _columns; + const int lastColumn = (line < _lineProperties.size() && _lineProperties[line].flags.f.doublewidth) ? _columns / 2 : _columns; const auto *data = _screenLines[line].data(); // This should never happen, but it's happening. this is just to gather some information @@ -2004,7 +2005,7 @@ void Screen::writeToStream(TerminalCharacterDecoder *decoder, int startIndex, in // the text on a line. if (y == bottom && copied < count && !options.testFlag(TrimTrailingWhitespace)) { Character newLineChar('\n'); - decoder->decodeLine(&newLineChar, 1, 0); + decoder->decodeLine(&newLineChar, 1, LineProperty()); } } } @@ -2049,7 +2050,7 @@ int Screen::copyLineToStream(int line, // ensure that this method, can append space or 'eol' character to // the selection Character *characterBuffer = getCharacterBuffer((count > -1 ? count : lineLength - start) + 1); - LineProperty currentLineProperties = 0; + LineProperty currentLineProperties = LineProperty(); // determine if the line is in the history buffer or the screen image if (line < _history->getLines()) { @@ -2077,7 +2078,7 @@ int Screen::copyLineToStream(int line, } if (_history->isWrappedLine(line)) { - currentLineProperties |= LINE_WRAPPED; + currentLineProperties.flags.f.wrapped = 1; } else { if (options.testFlag(TrimTrailingWhitespace)) { // ignore trailing white space at the end of the line @@ -2113,7 +2114,7 @@ int Screen::copyLineToStream(int line, } // Don't remove end spaces in lines that wrap - if (options.testFlag(TrimTrailingWhitespace) && ((_lineProperties.at(screenLine) & LINE_WRAPPED) == 0)) { + if (options.testFlag(TrimTrailingWhitespace) && ((_lineProperties.at(screenLine).flags.f.wrapped) == 0)) { // ignore trailing white space at the end of the line while (length > 0 && QChar(data[length - 1].character).isSpace()) { length--; @@ -2130,14 +2131,14 @@ int Screen::copyLineToStream(int line, count = qBound(0, count, length - start); Q_ASSERT((size_t)screenLine < _lineProperties.size()); - currentLineProperties |= _lineProperties[screenLine]; + currentLineProperties = _lineProperties[screenLine]; } if (appendNewLine) { // When users ask not to preserve the linebreaks, they usually mean: // `treat LINEBREAK as SPACE, thus joining multiple _lines into // single line in the same way as 'J' does in VIM.` - const bool isLineWrapped = (currentLineProperties & LINE_WRAPPED) != 0; + const bool isLineWrapped = (currentLineProperties.flags.f.wrapped) != 0; if (isBlockSelectionMode || !isLineWrapped) { characterBuffer[count] = options.testFlag(PreserveLineBreaks) ? Character('\n') : Character(' '); ++count; @@ -2315,12 +2316,12 @@ const HistoryType &Screen::getScroll() const return _history->getType(); } -void Screen::setLineProperty(LineProperty property, bool enable) +void Screen::setLineProperty(quint16 property, bool enable) { if (enable) { - _lineProperties[_cuY] = static_cast(_lineProperties.at(_cuY) | property); + _lineProperties[_cuY].flags.all |= property; } else { - _lineProperties[_cuY] = static_cast(_lineProperties.at(_cuY) & ~property); + _lineProperties[_cuY].flags.all &= ~property; } } diff --git a/src/Screen.h b/src/Screen.h index b5d0c3197..234ae894b 100644 --- a/src/Screen.h +++ b/src/Screen.h @@ -566,7 +566,7 @@ public: * * @param enable true to apply the attribute to the current line or false to remove it */ - void setLineProperty(LineProperty property, bool enable); + void setLineProperty(quint16 property, bool enable); /** * Set REPL mode (shell integration) diff --git a/src/ScreenWindow.cpp b/src/ScreenWindow.cpp index df3f0cb9f..20f9b9369 100644 --- a/src/ScreenWindow.cpp +++ b/src/ScreenWindow.cpp @@ -243,7 +243,7 @@ void ScreenWindow::scrollBy(RelativeScrollMode mode, int amount, bool fullPage) QVector properties = _screen->getLineProperties(0, currentLine()); while (i > 0 && amount < 0) { i--; - if ((properties[i] & LINE_PROMPT_START) != 0) { + if ((properties[i].flags.f.prompt_start) != 0) { if (++amount == 0) { break; } @@ -253,7 +253,7 @@ void ScreenWindow::scrollBy(RelativeScrollMode mode, int amount, bool fullPage) QVector properties = _screen->getLineProperties(currentLine(), _screen->getHistLines()); while (i < _screen->getHistLines() && amount > 0) { i++; - if ((properties[i - currentLine()] & LINE_PROMPT_START) != 0) { + if ((properties[i - currentLine()].flags.f.prompt_start) != 0) { if (--amount == 0) { break; } diff --git a/src/Vt102Emulation.cpp b/src/Vt102Emulation.cpp index 7c10c2d48..46eb3afca 100644 --- a/src/Vt102Emulation.cpp +++ b/src/Vt102Emulation.cpp @@ -2074,7 +2074,7 @@ void Vt102Emulation::sendMouseEvent(int cb, int cx, int cy, int eventType) KeyboardTranslator::Entry LRKeys[2] = {_keyTranslator->findEntry(Qt::Key_Left, Qt::NoModifier, states), _keyTranslator->findEntry(Qt::Key_Right, Qt::NoModifier, states)}; QVector lineProperties = _currentScreen->getLineProperties(cy + _currentScreen->getHistLines(), cy + _currentScreen->getHistLines()); - cx = qMin(cx, LineLength(lineProperties[0])); + cx = qMin(cx, (int)lineProperties[0].length); int cuX = _currentScreen->getCursorX(); int cuY = _currentScreen->getCursorY(); QByteArray textToSend; @@ -2159,13 +2159,13 @@ void Vt102Emulation::emulateUpDown(bool up, KeyboardTranslator::Entry entry, QBy qMin(_currentScreen->getLines() - 1, cuY + 1) + _currentScreen->getHistLines()); int num = _currentScreen->getColumns(); if (up) { - if ((lineProperties[0] & LINE_WRAPPED) == 0) { - num = cuX + qMax(0, LineLength(lineProperties[0]) - cuX) + 1; + if ((lineProperties[0].flags.f.wrapped) == 0) { + num = cuX + qMax(0, lineProperties[0].length - cuX) + 1; } } else { - if ((lineProperties[1] & LINE_WRAPPED) == 0 || (lineProperties[2] & LINE_WRAPPED) == 0) { - realX = qMin(cuX, LineLength(lineProperties[2]) + 1); - num = LineLength(lineProperties[1]) - cuX + realX; + if ((lineProperties[1].flags.f.wrapped) == 0 || (lineProperties[2].flags.f.wrapped) == 0) { + realX = qMin(cuX, lineProperties[2].length + 1); + num = lineProperties[1].length - cuX + realX; } } if (toCol > -1) { diff --git a/src/autotests/HistoryTest.cpp b/src/autotests/HistoryTest.cpp index 9a01c11f6..998dfaca6 100644 --- a/src/autotests/HistoryTest.cpp +++ b/src/autotests/HistoryTest.cpp @@ -136,7 +136,7 @@ void HistoryTest::testHistoryReflow() QCOMPARE(compactHistoryScroll->getMaxLines(), 10); compactHistoryScroll->addCells(testImage, testStringSize); - compactHistoryScroll->addLine(false); + compactHistoryScroll->addLine(); QCOMPARE(compactHistoryScroll->getLines(), 1); QCOMPARE(compactHistoryScroll->reflowLines(10), 0); QCOMPARE(compactHistoryScroll->getLines(), 4); @@ -155,7 +155,7 @@ void HistoryTest::testHistoryReflow() QCOMPARE(historyScrollFile->getMaxLines(), 0); historyScrollFile->addCells(testImage, testStringSize); - historyScrollFile->addLine(false); + historyScrollFile->addLine(); QCOMPARE(historyScrollFile->getLines(), 1); QCOMPARE(historyScrollFile->getMaxLines(), 1); QCOMPARE(historyScrollFile->reflowLines(10), 0); @@ -193,7 +193,7 @@ void HistoryTest::testHistoryTypeChange() historyTypeFile->scroll(historyScroll); historyScroll->addCells(testImage.get(), testStringSize); - historyScroll->addLine(false); + historyScroll->addLine(); QCOMPARE(historyScroll->reflowLines(1), 0); QCOMPARE(historyScroll->getLines(), testStringSize); historyScroll->getCells(0, 0, 1, &testChar); diff --git a/src/autotests/TerminalCharacterDecoderTest.cpp b/src/autotests/TerminalCharacterDecoderTest.cpp index 2c75ed6a7..bd23df1ac 100644 --- a/src/autotests/TerminalCharacterDecoderTest.cpp +++ b/src/autotests/TerminalCharacterDecoderTest.cpp @@ -63,7 +63,7 @@ void TerminalCharacterDecoderTest::testPlainTextDecoder() QString outputString; QTextStream outputStream(&outputString); decoder->begin(&outputStream); - decoder->decodeLine(testCharacters, text.size(), /* ignored */ LINE_DEFAULT); + decoder->decodeLine(testCharacters, text.size(), /* ignored */ LineProperty()); decoder->end(); delete[] testCharacters; delete decoder; @@ -107,7 +107,7 @@ void TerminalCharacterDecoderTest::testHTMLDecoder() QString outputString; QTextStream outputStream(&outputString); decoder->begin(&outputStream); - decoder->decodeLine(testCharacters, text.size(), /* ignored */ LINE_DEFAULT); + decoder->decodeLine(testCharacters, text.size(), /* ignored */ LineProperty()); decoder->end(); delete[] testCharacters; delete decoder; diff --git a/src/characters/Character.h b/src/characters/Character.h index c8f0ca434..6935907c6 100644 --- a/src/characters/Character.h +++ b/src/characters/Character.h @@ -20,9 +20,37 @@ namespace Konsole { -typedef quint32 LineProperty; - #pragma pack(1) +class LineProperty +{ +public: + explicit constexpr LineProperty(quint16 f = 0, uint l = 0, uint c = 0) + : flags({f}) + , length(l) + , counter(c) + { + } + union { + quint16 all; + struct { + uint wrapped : 1; + uint doublewidth : 1; + uint doubleheight_top : 1; + uint doubleheight_bottom : 1; + uint prompt_start : 1; + uint output_start : 1; + uint input_start : 1; + uint output : 1; + } f; + } flags; + qint16 length; + quint16 counter; + bool operator!=(const LineProperty &rhs) const + { + return (flags.all != rhs.flags.all); + } +}; + typedef union { quint16 all; struct { @@ -47,7 +75,6 @@ typedef quint16 RenditionFlags; typedef quint16 ExtraFlags; /* clang-format off */ -const int LINE_DEFAULT = 0; const int LINE_WRAPPED = (1 << 0); const int LINE_DOUBLEWIDTH = (1 << 1); const int LINE_DOUBLEHEIGHT_TOP = (1 << 2); @@ -55,8 +82,6 @@ const int LINE_DOUBLEHEIGHT_BOTTOM = (1 << 3); const int LINE_PROMPT_START = (1 << 4); const int LINE_INPUT_START = (1 << 5); const int LINE_OUTPUT_START = (1 << 6); -const int LINE_LEN_POS = 8; -const int LINE_LEN_MASK = (0xfff << LINE_LEN_POS); const RenditionFlags DEFAULT_RENDITION = 0; const RenditionFlags RE_BOLD = (1 << 0); @@ -97,8 +122,6 @@ const ExtraFlags EF_EMOJI_REPRESENTATION = (1 << 7); #define SetULColor(f, m) (((f) & ~EF_UNDERLINE_COLOR) | ((m) * EF_UNDERLINE_COLOR_1)) #define setRepl(f, m) (((f) & ~EF_REPL) | ((m) * EF_REPL_PROMPT)) -#define LineLength(f) static_cast(((f) & LINE_LEN_MASK) >> LINE_LEN_POS) -#define SetLineLength(f, l) (((f) & ~LINE_LEN_MASK) | ((l) << LINE_LEN_POS)) /* clang-format on */ /** diff --git a/src/filterHotSpots/TerminalImageFilterChain.cpp b/src/filterHotSpots/TerminalImageFilterChain.cpp index 98f553447..c5d7be2ae 100644 --- a/src/filterHotSpots/TerminalImageFilterChain.cpp +++ b/src/filterHotSpots/TerminalImageFilterChain.cpp @@ -48,12 +48,12 @@ void TerminalImageFilterChain::setImage(const Character *const image, int lines, for (int i = 0; i < lines; i++) { _linePositions->append(_buffer->length()); - decoder.decodeLine(image + i * columns, columns, LINE_DEFAULT); + decoder.decodeLine(image + i * columns, columns, LineProperty()); // pretend that each non-wrapped line ends with a newline character. // this prevents a link that occurs at the end of one line // being treated as part of a link that occurs at the start of the next line - if ((lineProperties.value(i, LINE_DEFAULT) & LINE_WRAPPED) == 0) { + if ((lineProperties.value(i, LineProperty()).flags.f.wrapped) == 0) { lineStream << QLatin1Char('\n'); } } diff --git a/src/history/HistoryScroll.h b/src/history/HistoryScroll.h index c126dc2af..d4f77c6ee 100644 --- a/src/history/HistoryScroll.h +++ b/src/history/HistoryScroll.h @@ -51,7 +51,7 @@ public: addCells(cells.data(), cells.size()); } - virtual void addLine(const LineProperty lineProperty = 0) = 0; + virtual void addLine(const LineProperty lineProperty = LineProperty()) = 0; // modify history virtual void removeCells() = 0; diff --git a/src/history/HistoryScrollFile.cpp b/src/history/HistoryScrollFile.cpp index e8ff55085..4bc40dfb0 100644 --- a/src/history/HistoryScrollFile.cpp +++ b/src/history/HistoryScrollFile.cpp @@ -45,17 +45,17 @@ int HistoryScrollFile::getLineLen(const int lineno) const bool HistoryScrollFile::isWrappedLine(const int lineno) const { - return (getLineProperty(lineno) & LINE_WRAPPED) > 0; + return (getLineProperty(lineno).flags.f.wrapped) > 0; } LineProperty HistoryScrollFile::getLineProperty(const int lineno) const { if (lineno >= 0 && lineno <= getLines()) { - LineProperty flag = 0; + LineProperty flag = LineProperty(); _lineflags.get(reinterpret_cast(&flag), sizeof(unsigned char), (lineno) * sizeof(unsigned char)); return flag; } - return 0; + return LineProperty(); } qint64 HistoryScrollFile::startOfLine(const int lineno) const @@ -134,12 +134,14 @@ int Konsole::HistoryScrollFile::reflowLines(const int columns, std::map columns && !(lineProperty & (LINE_DOUBLEHEIGHT_BOTTOM | LINE_DOUBLEHEIGHT_TOP))) { + while (reflowLineLen(startLine, endLine) > columns && !(lineProperty.flags.f.doubleheight_bottom | lineProperty.flags.f.doubleheight_top)) { startLine += (qint64)columns * sizeof(Character); - setNewLine(newLine, startLine, lineProperty | LINE_WRAPPED); + lineProperty.flags.f.wrapped = 1; + setNewLine(newLine, startLine, lineProperty); reflowFile->add(reinterpret_cast(&newLine), sizeof(reflowData)); } - setNewLine(newLine, endLine, lineProperty & ~LINE_WRAPPED); + lineProperty.flags.f.wrapped = 0; + setNewLine(newLine, endLine, lineProperty); reflowFile->add(reinterpret_cast(&newLine), sizeof(reflowData)); currentPos++; } diff --git a/src/history/HistoryScrollFile.h b/src/history/HistoryScrollFile.h index 7e350e181..7d63bdf17 100644 --- a/src/history/HistoryScrollFile.h +++ b/src/history/HistoryScrollFile.h @@ -37,7 +37,7 @@ public: { addCells(text, count); } // TODO: optimize, if there's any point - void addLine(LineProperty lineProperty = 0) override; + void addLine(LineProperty lineProperty = LineProperty()) override; // Modify history void removeCells() override; diff --git a/src/history/HistoryScrollNone.cpp b/src/history/HistoryScrollNone.cpp index 21c52f021..30b63be39 100644 --- a/src/history/HistoryScrollNone.cpp +++ b/src/history/HistoryScrollNone.cpp @@ -47,7 +47,7 @@ bool HistoryScrollNone::isWrappedLine(int /*lineno*/) const LineProperty HistoryScrollNone::getLineProperty(int /*lineno*/) const { - return 0; + return LineProperty(); } void HistoryScrollNone::getCells(int, int, int, Character[]) const diff --git a/src/history/HistoryScrollNone.h b/src/history/HistoryScrollNone.h index 6ecd2a5a8..372ab4601 100644 --- a/src/history/HistoryScrollNone.h +++ b/src/history/HistoryScrollNone.h @@ -33,7 +33,7 @@ public: void addCells(const Character a[], const int count) override; void addCellsMove(Character a[], const int count) override; - void addLine(const LineProperty lineProperty = 0) override; + void addLine(const LineProperty lineProperty = LineProperty()) override; // Modify history (do nothing here) void removeCells() override; diff --git a/src/history/compact/CompactHistoryScroll.cpp b/src/history/compact/CompactHistoryScroll.cpp index 006f2ae13..8bfe29e64 100644 --- a/src/history/compact/CompactHistoryScroll.cpp +++ b/src/history/compact/CompactHistoryScroll.cpp @@ -38,7 +38,7 @@ void CompactHistoryScroll::addCells(const Character a[], const int count) // store the (biased) start of next line + default flag // the flag is later updated when addLine is called - _lineDatas.push_back({static_cast(_cells.size() + _indexBias), LINE_DEFAULT}); + _lineDatas.push_back({static_cast(_cells.size() + _indexBias), LineProperty()}); if (_lineDatas.size() > _maxLineCount + 5) { removeLinesFromTop(5); @@ -51,7 +51,7 @@ void CompactHistoryScroll::addCellsMove(Character characters[], const int count) // store the (biased) start of next line + default flag // the flag is later updated when addLine is called - _lineDatas.push_back({static_cast(_cells.size() + _indexBias), LINE_DEFAULT}); + _lineDatas.push_back({static_cast(_cells.size() + _indexBias), LineProperty()}); if (_lineDatas.size() > _maxLineCount + 5) { removeLinesFromTop(5); @@ -131,7 +131,7 @@ void CompactHistoryScroll::removeCells() bool CompactHistoryScroll::isWrappedLine(const int lineNumber) const { Q_ASSERT((size_t)lineNumber < _lineDatas.size()); - return (_lineDatas.at(lineNumber).flag & LINE_WRAPPED) > 0; + return (_lineDatas.at(lineNumber).flag.flags.f.wrapped) > 0; } LineProperty CompactHistoryScroll::getLineProperty(const int lineNumber) const @@ -166,12 +166,14 @@ int CompactHistoryScroll::reflowLines(const int columns, std::map *del } // Now reflow the lines - while (reflowLineLen(startLine, endLine) > columns && !(lineProperty & (LINE_DOUBLEHEIGHT_BOTTOM | LINE_DOUBLEHEIGHT_TOP))) { + while (reflowLineLen(startLine, endLine) > columns && !(lineProperty.flags.f.doubleheight_bottom | lineProperty.flags.f.doubleheight_top)) { startLine += columns; - setNewLine(newLineData, startLine + _indexBias, lineProperty | LINE_WRAPPED); + lineProperty.flags.f.wrapped = 1; + setNewLine(newLineData, startLine + _indexBias, lineProperty); newPos++; } - setNewLine(newLineData, endLine + _indexBias, lineProperty & ~LINE_WRAPPED); + lineProperty.flags.f.wrapped = 0; + setNewLine(newLineData, endLine + _indexBias, lineProperty); currentPos++; newPos++; if (deltas && delta != newPos - currentPos) { diff --git a/src/history/compact/CompactHistoryScroll.h b/src/history/compact/CompactHistoryScroll.h index 168ce1fa8..a04aab094 100644 --- a/src/history/compact/CompactHistoryScroll.h +++ b/src/history/compact/CompactHistoryScroll.h @@ -31,7 +31,7 @@ public: void addCells(const Character a[], const int count) override; void addCellsMove(Character a[], const int count) override; - void addLine(const LineProperty lineProperty = 0) override; + void addLine(const LineProperty lineProperty = LineProperty()) override; void removeCells() override; diff --git a/src/terminalDisplay/TerminalDisplay.cpp b/src/terminalDisplay/TerminalDisplay.cpp index 3a207365c..179d1816d 100644 --- a/src/terminalDisplay/TerminalDisplay.cpp +++ b/src/terminalDisplay/TerminalDisplay.cpp @@ -1497,7 +1497,7 @@ QPair TerminalDisplay::getCharacterPosition(const QPoint &widgetPoint, const int columnMax = edge ? _usedColumns : _usedColumns - 1; const int xOffset = edge ? _terminalFont->fontWidth() / 2 : 0; int line = qBound(0, (widgetPoint.y() - contentsRect().top() - _contentRect.top()) / _terminalFont->fontHeight(), _usedLines - 1); - bool doubleWidth = line < _lineProperties.count() && _lineProperties[line] & LINE_DOUBLEWIDTH; + bool doubleWidth = line < _lineProperties.count() && _lineProperties[line].flags.f.doublewidth; bool shaped; int column = qBound(0, (widgetPoint.x() + xOffset - contentsRect().left() - _contentRect.left()) / _terminalFont->fontWidth() / (doubleWidth ? 2 : 1), columnMax); @@ -1710,7 +1710,7 @@ QPoint TerminalDisplay::findLineStart(const QPoint &pnt) while (lineInHistory > 0) { for (; line > 0; line--, lineInHistory--) { // Does previous line wrap around? - if ((lineProperties[line - 1] & LINE_WRAPPED) == 0) { + if ((lineProperties[line - 1].flags.f.wrapped) == 0) { return {0, lineInHistory - topVisibleLine}; } } @@ -1744,7 +1744,7 @@ QPoint TerminalDisplay::findLineEnd(const QPoint &pnt) while (lineInHistory < maxY) { for (; line < lineProperties.count() && lineInHistory < maxY; line++, lineInHistory++) { // Does current line wrap around? - if ((lineProperties[line] & LINE_WRAPPED) == 0) { + if ((lineProperties[line].flags.f.wrapped) == 0) { return {_columns - 1, lineInHistory - topVisibleLine}; } } @@ -1792,7 +1792,7 @@ QPoint TerminalDisplay::findWordStart(const QPoint &pnt) goto out; } else if (imgLine > 0) { // not the first line in the session - if ((lineProperties[imgLine - 1] & LINE_WRAPPED) != 0) { + if ((lineProperties[imgLine - 1].flags.f.wrapped) != 0) { // have continuation on prev line if (charClass(image[imgLoc - 1]) == selClass) { x = _columns; @@ -1878,7 +1878,7 @@ QPoint TerminalDisplay::findWordEnd(const QPoint &pnt) } goto out; } else if (i < lineCount - 1) { - if (((lineProperties[i] & LINE_WRAPPED) != 0) && charClass(image[j + 1]) == selClass && + if (((lineProperties[i].flags.f.wrapped) != 0) && charClass(image[j + 1]) == selClass && // A colon right before whitespace is never part of a word !(image[j + 1].character == ':' && charClass(image[j + 2]) == QLatin1Char(' '))) { x = -1; @@ -1888,7 +1888,7 @@ QPoint TerminalDisplay::findWordEnd(const QPoint &pnt) } goto out; } else if (y < maxY) { - if (i < lineCount && ((lineProperties[i] & LINE_WRAPPED) == 0)) { + if (i < lineCount && ((lineProperties[i].flags.f.wrapped) == 0)) { goto out; } break; @@ -2421,7 +2421,7 @@ QVariant TerminalDisplay::inputMethodQuery(Qt::InputMethodQuery query) const PlainTextDecoder decoder; decoder.begin(&stream); if (isCursorOnDisplay()) { - decoder.decodeLine(&_image[loc(0, cursorPos.y())], _usedColumns, LINE_DEFAULT); + decoder.decodeLine(&_image[loc(0, cursorPos.y())], _usedColumns, LineProperty()); } decoder.end(); return lineText; diff --git a/src/terminalDisplay/TerminalPainter.cpp b/src/terminalDisplay/TerminalPainter.cpp index 94d61b557..e9ccb6e03 100644 --- a/src/terminalDisplay/TerminalPainter.cpp +++ b/src/terminalDisplay/TerminalPainter.cpp @@ -120,7 +120,7 @@ void TerminalPainter::drawContents(Character *image, const int textY = topPadding + fontHeight * y; bool doubleHeightLinePair = false; int x = rect.x(); - LineProperty lineProperty = y < lineProperties.size() ? lineProperties[y] : 0; + LineProperty lineProperty = y < lineProperties.size() ? lineProperties[y] : LineProperty(); // Search for start of multi-column character if (image[m_parentDisplay->loc(rect.x(), y)].isRightHalfOfDoubleWide() && (x != 0)) { @@ -130,18 +130,18 @@ void TerminalPainter::drawContents(Character *image, bool doubleHeight = false; bool doubleWidthLine = false; - if ((lineProperty & LINE_DOUBLEWIDTH) != 0) { + if ((lineProperty.flags.f.doublewidth) != 0) { textScale.scale(2, 1); doubleWidthLine = true; } - doubleHeight = lineProperty & (LINE_DOUBLEHEIGHT_TOP | LINE_DOUBLEHEIGHT_BOTTOM); + doubleHeight = lineProperty.flags.f.doubleheight_top | lineProperty.flags.f.doubleheight_bottom; if (doubleHeight) { textScale.scale(1, 2); } if (y < lineProperties.size() - 1) { - if (((lineProperties[y] & LINE_DOUBLEHEIGHT_TOP) != 0) && ((lineProperties[y + 1] & LINE_DOUBLEHEIGHT_BOTTOM) != 0)) { + if (((lineProperties[y].flags.f.doubleheight_top) != 0) && ((lineProperties[y + 1].flags.f.doubleheight_bottom) != 0)) { doubleHeightLinePair = true; } } @@ -245,7 +245,7 @@ void TerminalPainter::drawContents(Character *image, paint.setRenderHint(QPainter::Antialiasing, false); paint.setWorldTransform(textScale.inverted(), true); - if ((lineProperty & LINE_PROMPT_START) + if ((lineProperty.flags.f.prompt_start) && ((semanticHints == Enum::HintsURL && m_parentDisplay->filterChain()->showUrlHint()) || semanticHints == Enum::HintsAlways)) { QPen pen(m_parentDisplay->terminalColor()->foregroundColor()); paint.setPen(pen); @@ -551,7 +551,7 @@ void TerminalPainter::drawCharacters(QPainter &painter, if (isLineCharString(text) && !m_parentDisplay->terminalFont()->useFontLineCharacters()) { int y = rect.y(); - if (lineProperty & LINE_DOUBLEHEIGHT_BOTTOM) { + if (lineProperty.flags.f.doubleheight_bottom) { y -= m_parentDisplay->terminalFont()->fontHeight() / 2; } @@ -561,7 +561,7 @@ void TerminalPainter::drawCharacters(QPainter &painter, int y = rect.y() + m_parentDisplay->terminalFont()->fontAscent(); int shifted = 0; - if (lineProperty & LINE_DOUBLEHEIGHT_BOTTOM) { + if (lineProperty.flags.f.doubleheight_bottom) { y -= m_parentDisplay->terminalFont()->fontHeight() / 2; } else { // We shift half way down here to center @@ -607,7 +607,7 @@ void TerminalPainter::drawInputMethodPreeditString(QPainter &painter, const QRec drawBackground(painter, rect, background, true); drawCursor(painter, rect, foreground, background, characterColor); - drawCharacters(painter, rect, inputMethodData.preeditString, style, characterColor, 0); + drawCharacters(painter, rect, inputMethodData.preeditString, style, characterColor, LineProperty()); inputMethodData.previousPreeditRect = rect; } @@ -989,7 +989,7 @@ void TerminalPainter::drawTextCharacters(QPainter &painter, if (isLineCharString(text) && !m_parentDisplay->terminalFont()->useFontLineCharacters()) { int y = rect.y(); - if (lineProperty & LINE_DOUBLEHEIGHT_BOTTOM) { + if (lineProperty.flags.f.doubleheight_bottom) { y -= m_parentDisplay->terminalFont()->fontHeight() / 2; } @@ -997,7 +997,7 @@ void TerminalPainter::drawTextCharacters(QPainter &painter, } else { int y = rect.y() + m_parentDisplay->terminalFont()->fontAscent(); - if (lineProperty & LINE_DOUBLEHEIGHT_BOTTOM) { + if (lineProperty.flags.f.doubleheight_bottom) { y -= m_parentDisplay->terminalFont()->fontHeight() / 2; } else { // We shift half way down here to center