diff --git a/src/Utils.cpp b/src/Utils.cpp
index 8176cb43..0d3e9384 100644
--- a/src/Utils.cpp
+++ b/src/Utils.cpp
@@ -15,6 +15,8 @@
using TimelineEvent = mtx::events::collections::TimelineEvents;
+QHash<QString, QString> authorColors_;
+
QString
utils::localUser()
{
@@ -382,6 +384,126 @@ utils::linkColor()
return QPalette().color(QPalette::Link).name();
}
+int
+utils::hashQString(const QString &input)
+{
+ auto hash = 0;
+
+ for (int i = 0; i < input.length(); i++) {
+ hash = input.at(i).digitValue() + ((hash << 5) - hash);
+ }
+
+ return hash;
+}
+
+QString
+utils::generateContrastingHexColor(const QString &input, const QString &background)
+{
+ const QColor backgroundCol(background);
+ const qreal backgroundLum = luminance(background);
+
+ // Create a color for the input
+ auto hash = hashQString(input);
+ // create a hue value based on the hash of the input.
+ auto userHue = qAbs(hash % 360);
+ // start with moderate saturation and lightness values.
+ auto sat = 220;
+ auto lightness = 125;
+
+ // converting to a QColor makes the luminance calc easier.
+ QColor inputColor = QColor::fromHsl(userHue, sat, lightness);
+
+ // calculate the initial luminance and contrast of the
+ // generated color. It's possible that no additional
+ // work will be necessary.
+ auto lum = luminance(inputColor);
+ auto contrast = computeContrast(lum, backgroundLum);
+
+ // If the contrast doesn't meet our criteria,
+ // try again and again until they do by modifying first
+ // the lightness and then the saturation of the color.
+ while (contrast < 5) {
+ // if our lightness is at it's bounds, try changing
+ // saturation instead.
+ if (lightness == 242 || lightness == 13) {
+ qreal newSat = qBound(26.0, sat * 1.25, 242.0);
+
+ inputColor.setHsl(userHue, qFloor(newSat), lightness);
+ auto tmpLum = luminance(inputColor);
+ auto higherContrast = computeContrast(tmpLum, backgroundLum);
+ if (higherContrast > contrast) {
+ contrast = higherContrast;
+ sat = newSat;
+ } else {
+ newSat = qBound(26.0, sat / 1.25, 242.0);
+ inputColor.setHsl(userHue, qFloor(newSat), lightness);
+ tmpLum = luminance(inputColor);
+ auto lowerContrast = computeContrast(tmpLum, backgroundLum);
+ if (lowerContrast > contrast) {
+ contrast = lowerContrast;
+ sat = newSat;
+ }
+ }
+ } else {
+ qreal newLightness = qBound(13.0, lightness * 1.25, 242.0);
+
+ inputColor.setHsl(userHue, sat, qFloor(newLightness));
+
+ auto tmpLum = luminance(inputColor);
+ auto higherContrast = computeContrast(tmpLum, backgroundLum);
+
+ // Check to make sure we have actually improved contrast
+ if (higherContrast > contrast) {
+ contrast = higherContrast;
+ lightness = newLightness;
+ // otherwise, try going the other way instead.
+ } else {
+ newLightness = qBound(13.0, lightness / 1.25, 242.0);
+ inputColor.setHsl(userHue, sat, qFloor(newLightness));
+ tmpLum = luminance(inputColor);
+ auto lowerContrast = computeContrast(tmpLum, backgroundLum);
+ if (lowerContrast > contrast) {
+ contrast = lowerContrast;
+ lightness = newLightness;
+ }
+ }
+ }
+ }
+
+ // get the hex value of the generated color.
+ auto colorHex = inputColor.name();
+
+ return colorHex;
+}
+
+qreal
+utils::computeContrast(const qreal &one, const qreal &two)
+{
+ auto ratio = (one + 0.05) / (two + 0.05);
+
+ if (two > one) {
+ ratio = 1 / ratio;
+ }
+
+ return ratio;
+}
+
+qreal
+utils::luminance(const QColor &col)
+{
+ int colRgb[3] = {col.red(), col.green(), col.blue()};
+ qreal lumRgb[3];
+
+ for (int i = 0; i < 3; i++) {
+ qreal v = colRgb[i] / 255.0;
+ v <= 0.03928 ? lumRgb[i] = v / 12.92 : lumRgb[i] = qPow((v + 0.055) / 1.055, 2.4);
+ }
+
+ auto lum = lumRgb[0] * 0.2126 + lumRgb[1] * 0.7152 + lumRgb[2] * 0.0722;
+
+ return lum;
+}
+
void
utils::centerWidget(QWidget *widget, QWidget *parent)
{
|