forked from qt-creator/qt-creator
Highlighter: Apply specific ksyntax format attributes
If a ksyntax format explicitly defines font attributes like bold, italic, underline or strike through we now apply those attributes. If the format defines a colors, we first check whether the color is readable before setting it. Fixes: QTCREATORBUG-22646 Fixes: QTCREATORBUG-22229 Fixes: QTCREATORBUG-13545 Change-Id: Id0389b3c71a078dc6d6df74ee5de7f5d479a9bcb Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -44,6 +44,8 @@
|
||||
#include <QDir>
|
||||
#include <QMetaEnum>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
using namespace TextEditor;
|
||||
|
||||
static const char kDefinitionForMimeType[] = "definitionForMimeType";
|
||||
@@ -322,9 +324,77 @@ void Highlighter::highlightBlock(const QString &text)
|
||||
formatSpaces(text);
|
||||
}
|
||||
|
||||
static double luminance(const QColor &color)
|
||||
{
|
||||
// calculate the luminance based on
|
||||
// https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
|
||||
auto val = [](const double &colorVal) {
|
||||
return colorVal < 0.03928 ? colorVal / 12.92 : std::pow((colorVal + 0.055) / 1.055, 2.4);
|
||||
};
|
||||
|
||||
static QHash<QRgb, double> cache;
|
||||
QHash<QRgb, double>::iterator it = cache.find(color.rgb());
|
||||
if (it == cache.end()) {
|
||||
it = cache.insert(color.rgb(), 0.2126 * val(color.redF())
|
||||
+ 0.7152 * val(color.greenF())
|
||||
+ 0.0722 * val(color.blueF()));
|
||||
}
|
||||
return it.value();
|
||||
}
|
||||
|
||||
static double contrastRatio(const QColor &color1, const QColor &color2)
|
||||
{
|
||||
// calculate the contrast ratio based on
|
||||
// https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef
|
||||
auto contrast = (luminance(color1) + 0.05) / (luminance(color2) + 0.05);
|
||||
if (contrast < 1)
|
||||
return 1 / contrast;
|
||||
return contrast;
|
||||
}
|
||||
|
||||
static bool isReadableOn(const QColor &background, const QColor &foreground)
|
||||
{
|
||||
// following the W3C Recommendation on contrast for large Text
|
||||
// https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef
|
||||
return contrastRatio(background, foreground) > 3;
|
||||
}
|
||||
|
||||
void Highlighter::applyFormat(int offset, int length, const KSyntaxHighlighting::Format &format)
|
||||
{
|
||||
setFormat(offset, length, formatForCategory(format.textStyle()));
|
||||
const KSyntaxHighlighting::Theme defaultTheme;
|
||||
QTextCharFormat qformat = formatForCategory(format.textStyle());
|
||||
|
||||
if (format.hasTextColor(defaultTheme)) {
|
||||
const QColor textColor = format.textColor(defaultTheme);
|
||||
if (format.hasBackgroundColor(defaultTheme)) {
|
||||
const QColor backgroundColor = format.hasBackgroundColor(defaultTheme);
|
||||
if (isReadableOn(backgroundColor, textColor)) {
|
||||
qformat.setForeground(textColor);
|
||||
qformat.setBackground(backgroundColor);
|
||||
} else if (isReadableOn(qformat.background().color(), textColor)) {
|
||||
qformat.setForeground(textColor);
|
||||
}
|
||||
} else if (isReadableOn(qformat.background().color(), textColor)) {
|
||||
qformat.setForeground(textColor);
|
||||
}
|
||||
} else if (format.hasBackgroundColor(defaultTheme)) {
|
||||
const QColor backgroundColor = format.hasBackgroundColor(defaultTheme);
|
||||
if (isReadableOn(backgroundColor, qformat.foreground().color()))
|
||||
qformat.setBackground(backgroundColor);
|
||||
}
|
||||
|
||||
if (format.isBold(defaultTheme))
|
||||
qformat.setFontWeight(QFont::Bold);
|
||||
|
||||
if (format.isItalic(defaultTheme))
|
||||
qformat.setFontItalic(true);
|
||||
|
||||
if (format.isUnderline(defaultTheme))
|
||||
qformat.setFontUnderline(true);
|
||||
|
||||
if (format.isStrikeThrough(defaultTheme))
|
||||
qformat.setFontStrikeOut(true);
|
||||
setFormat(offset, length, qformat);
|
||||
}
|
||||
|
||||
void Highlighter::applyFolding(int offset,
|
||||
|
||||
Reference in New Issue
Block a user