Commit 3b06b6f2 authored by pontaoski's avatar pontaoski 🌈 Committed by Kurt Hindenburg
Browse files

Improve appearance of text selection

By blending foreground & background instead of swapping them, you can
get a more visually appealing text selection.
parent 7c5f08a2
......@@ -603,7 +603,7 @@ void Screen::copyFromHistory(Character* dest, int startLine, int count) const
if (_selBegin != -1) {
for (int column = 0; column < _columns; column++) {
if (isSelected(column, line)) {
reverseRendition(dest[destLineOffset + column]);
dest[destLineOffset + column].rendition |= RE_SELECTED;
}
}
}
......@@ -626,7 +626,7 @@ void Screen::copyFromScreen(Character* dest , int startLine , int count) const
// invert selected text
if (_selBegin != -1 && isSelected(column, line + _history->getLines())) {
reverseRendition(dest[destIndex]);
dest[destIndex].rendition |= RE_SELECTED;
}
}
}
......
......@@ -37,6 +37,7 @@ const RenditionFlags RE_FAINT = (1 << 7);
const RenditionFlags RE_STRIKEOUT = (1 << 8);
const RenditionFlags RE_CONCEAL = (1 << 9);
const RenditionFlags RE_OVERLINE = (1 << 10);
const RenditionFlags RE_SELECTED = (1 << 11);
/**
* A single character in the terminal which consists of a unicode character
......
......@@ -28,6 +28,7 @@
#include <QTransform>
#include <QPen>
#include <QDebug>
#include <QtMath>
// we use this to force QPainter to display text in LTR mode
// more information can be found in: https://unicode.org/reports/tr9/
......@@ -313,12 +314,82 @@ namespace Konsole
return dirtyRegion;
}
QColor alphaBlend(const QColor &foreground, const QColor &background) {
const auto foregroundAlpha = foreground.alphaF();
const auto inverseForegroundAlpha = 1.0 - foregroundAlpha;
const auto backgroundAlpha = background.alphaF();
if (foregroundAlpha == 0.0) {
return background;
}
if (backgroundAlpha == 1.0) {
return QColor::fromRgb(
(foregroundAlpha*foreground.red()) + (inverseForegroundAlpha*background.red()),
(foregroundAlpha*foreground.green()) + (inverseForegroundAlpha*background.green()),
(foregroundAlpha*foreground.blue()) + (inverseForegroundAlpha*background.blue()),
0xff
);
} else {
const auto inverseBackgroundAlpha = (backgroundAlpha * inverseForegroundAlpha);
const auto finalAlpha = foregroundAlpha + inverseBackgroundAlpha;
Q_ASSERT(finalAlpha != 0.0);
return QColor::fromRgb(
(foregroundAlpha*foreground.red()) + (inverseBackgroundAlpha*background.red()),
(foregroundAlpha*foreground.green()) + (inverseBackgroundAlpha*background.green()),
(foregroundAlpha*foreground.blue()) + (inverseBackgroundAlpha*background.blue()),
finalAlpha
);
}
}
qreal wcag20AdjustColorPart(qreal v)
{
return v <= 0.03928 ? v/12.92 : qPow((v+0.055)/1.055, 2.4);
}
qreal wcag20RelativeLuminosity(const QColor &of)
{
auto r = of.redF(), g = of.greenF(), b = of.blueF();
const auto a = wcag20AdjustColorPart;
auto r2 = a(r), g2 = a(g), b2 = a(b);
return r2 * 0.2126 + g2 * 0.7152 + b2 * 0.0722;
}
qreal wcag20Contrast(const QColor &c1, const QColor &c2)
{
const auto l1 = wcag20RelativeLuminosity(c1)+0.05, l2 = wcag20RelativeLuminosity(c2)+0.05;
return (l1 > l2) ? l1/l2 : l2/l1;
}
QColor calculateBackgroundColor(const Character* style, const QColor *colorTable)
{
auto c1 = style->backgroundColor.color(colorTable);
if (!(style->rendition & RE_SELECTED)) {
return c1;
}
c1.setAlphaF(0.8);
const auto blend1 = alphaBlend(c1, colorTable[DEFAULT_FORE_COLOR]), blend2 = alphaBlend(c1, colorTable[DEFAULT_BACK_COLOR]);
const auto fg = style->foregroundColor.color(colorTable);
const auto contrast1 = wcag20Contrast(fg, blend1), contrast2 = wcag20Contrast(fg, blend2);
return (contrast1 < contrast2) ? blend1 : blend2;
}
void TerminalPainter::drawTextFragment(QPainter &painter, const QRect &rect, const QString &text,
const Character *style, const QColor *colorTable)
{
// setup painter
const QColor foregroundColor = style->foregroundColor.color(colorTable);
const QColor backgroundColor = style->backgroundColor.color(colorTable);
const QColor backgroundColor = calculateBackgroundColor(style, colorTable);
if (backgroundColor != colorTable[DEFAULT_BACK_COLOR]) {
drawBackground(painter, rect, backgroundColor, false);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment