diff --git a/src/libs/utils/ansiescapecodehandler.cpp b/src/libs/utils/ansiescapecodehandler.cpp index 14d5dd8f8e1..f2db87cc95d 100644 --- a/src/libs/utils/ansiescapecodehandler.cpp +++ b/src/libs/utils/ansiescapecodehandler.cpp @@ -168,9 +168,11 @@ QList AnsiEscapeCodeHandler::parseText(const FormattedText &input break; case RgbTextColor: case RgbBackgroundColor: + // See http://en.wikipedia.org/wiki/ANSI_escape_code#Colors if (++i >= numbers.size()) break; - if (numbers.at(i).toInt() == 2) { + switch (numbers.at(i).toInt()) { + case 2: // RGB set with format: 38;2;;; if ((i + 3) < numbers.size()) { (code == RgbTextColor) ? @@ -183,10 +185,36 @@ QList AnsiEscapeCodeHandler::parseText(const FormattedText &input setFormatScope(charFormat); } i += 3; - } else if (numbers.at(i).toInt() == 5) { - // rgb set with format: 38;5; - // unsupported because of unclear documentation, so we just skip + break; + case 5: + // 256 color mode with format: 38;5; + uint index = numbers.at(i + 1).toInt(); + + QColor color; + if (index < 8) { + // The first 8 colors are standard low-intensity ANSI colors. + color = ansiColor(index); + } else if (index < 16) { + // The next 8 colors are standard high-intensity ANSI colors. + color = ansiColor(index - 8).lighter(150); + } else if (index < 232) { + // The next 216 colors are a 6x6x6 RGB cube. + uint o = index - 16; + color = QColor((o / 36) * 51, ((o / 6) % 6) * 51, (o % 6) * 51); + } else { + // The last 24 colors are a greyscale gradient. + uint grey = (index - 232) * 11; + color = QColor(grey, grey, grey); + } + + if (code == RgbTextColor) + charFormat.setForeground(color); + else + charFormat.setBackground(color); + + setFormatScope(charFormat); ++i; + break; } break; default: diff --git a/tests/auto/utils/ansiescapecodehandler/tst_ansiescapecodehandler.cpp b/tests/auto/utils/ansiescapecodehandler/tst_ansiescapecodehandler.cpp index 530f8d8870f..0b7a877732f 100644 --- a/tests/auto/utils/ansiescapecodehandler/tst_ansiescapecodehandler.cpp +++ b/tests/auto/utils/ansiescapecodehandler/tst_ansiescapecodehandler.cpp @@ -59,6 +59,7 @@ private Q_SLOTS: private: const QString red; + const QString mustard; const QString bold; const QString normal; const QString normal1; @@ -66,6 +67,7 @@ private: tst_AnsiEscapeCodeHandler::tst_AnsiEscapeCodeHandler() : red(ansiEscape("31m")), + mustard(ansiEscape("38;5;220m")), bold(ansiEscape("1m")), normal(ansiEscape("0m")), normal1(ansiEscape("m")) @@ -110,6 +112,18 @@ void tst_AnsiEscapeCodeHandler::testSimpleFormat_data() << FormattedText("red", redFormat) << FormattedText(" text", defaultFormat)); + // Test 256-color text-color change + { + QTextCharFormat mustardFormat; + mustardFormat.setForeground(QColor(255, 204, 0)); + const QString text = "This is " + mustard + "mustard" + normal + " text"; + QTest::newRow("Text-color change (ANSI 256 color)") << text << QTextCharFormat() + << (FormattedTextList() + << FormattedText("This is ", defaultFormat) + << FormattedText("mustard", mustardFormat) + << FormattedText(" text", defaultFormat)); + } + // Test text format change to bold QTextCharFormat boldFormat; boldFormat.setFontWeight(QFont::Bold);