diff layer/ColourMapper.cpp @ 1216:dc2af6616c83

Merge from branch 3.0-integration
author Chris Cannam
date Fri, 13 Jan 2017 10:29:50 +0000
parents 73d43e410a6b
children 6e724c81f18f
line wrap: on
line diff
--- a/layer/ColourMapper.cpp	Fri Mar 04 12:23:31 2016 +0000
+++ b/layer/ColourMapper.cpp	Fri Jan 13 10:29:50 2017 +0000
@@ -4,7 +4,7 @@
     Sonic Visualiser
     An audio file viewer and annotation editor.
     Centre for Digital Music, Queen Mary, University of London.
-    This file copyright 2006-2007 Chris Cannam and QMUL.
+    This file copyright 2006-2016 Chris Cannam and QMUL.
     
     This program is free software; you can redistribute it and/or
     modify it under the terms of the GNU General Public License as
@@ -21,8 +21,47 @@
 
 #include "base/Debug.h"
 
+#include <vector>
+
+#include <QPainter>
+
+using namespace std;
+
+static vector<QColor> convertStrings(const vector<QString> &strs)
+{
+    vector<QColor> converted;
+    for (const auto &s: strs) converted.push_back(QColor(s));
+    reverse(converted.begin(), converted.end());
+    return converted;
+}
+
+static vector<QColor> ice = convertStrings({
+        // Based on ColorBrewer ylGnBu
+        "#ffffff", "#ffff00", "#f7fcf0", "#e0f3db", "#ccebc5", "#a8ddb5",
+        "#7bccc4", "#4eb3d3", "#2b8cbe", "#0868ac", "#084081", "#042040"
+        });
+
+static vector<QColor> cherry = convertStrings({
+        "#f7f7f7", "#fddbc7", "#f4a582", "#d6604d", "#b2182b", "#dd3497",
+        "#ae017e", "#7a0177", "#49006a"
+        });
+    
+static void
+mapDiscrete(double norm, vector<QColor> &colours, double &r, double &g, double &b)
+{
+    int n = int(colours.size());
+    double m = norm * (n-1);
+    if (m >= n-1) { colours[n-1].getRgbF(&r, &g, &b, 0); return; }
+    if (m <= 0) { colours[0].getRgbF(&r, &g, &b, 0); return; }
+    int base(int(floor(m)));
+    double prop0 = (base + 1.0) - m, prop1 = m - base;
+    QColor c0(colours[base]), c1(colours[base+1]);
+    r = c0.redF() * prop0 + c1.redF() * prop1;
+    g = c0.greenF() * prop0 + c1.greenF() * prop1;
+    b = c0.blueF() * prop0 + c1.blueF() * prop1;
+}
+
 ColourMapper::ColourMapper(int map, double min, double max) :
-    QObject(),
     m_map(map),
     m_min(min),
     m_max(max)
@@ -47,25 +86,25 @@
 QString
 ColourMapper::getColourMapName(int n)
 {
-    if (n >= getColourMapCount()) return tr("<unknown>");
+    if (n >= getColourMapCount()) return QObject::tr("<unknown>");
     StandardMap map = (StandardMap)n;
 
     switch (map) {
-    case DefaultColours:   return tr("Default");
-    case WhiteOnBlack:     return tr("White on Black");
-    case BlackOnWhite:     return tr("Black on White");
-    case RedOnBlue:        return tr("Red on Blue");
-    case YellowOnBlack:    return tr("Yellow on Black");
-    case BlueOnBlack:      return tr("Blue on Black");
-    case Sunset:           return tr("Sunset");
-    case FruitSalad:       return tr("Fruit Salad");
-    case Banded:           return tr("Banded");
-    case Highlight:        return tr("Highlight");
-    case Printer:          return tr("Printer");
-    case HighGain:         return tr("High Gain");
+    case Green:            return QObject::tr("Green");
+    case WhiteOnBlack:     return QObject::tr("White on Black");
+    case BlackOnWhite:     return QObject::tr("Black on White");
+    case Cherry:           return QObject::tr("Cherry");
+    case Wasp:             return QObject::tr("Wasp");
+    case Ice:              return QObject::tr("Ice");
+    case Sunset:           return QObject::tr("Sunset");
+    case FruitSalad:       return QObject::tr("Fruit Salad");
+    case Banded:           return QObject::tr("Banded");
+    case Highlight:        return QObject::tr("Highlight");
+    case Printer:          return QObject::tr("Printer");
+    case HighGain:         return QObject::tr("High Gain");
     }
 
-    return tr("<unknown>");
+    return QObject::tr("<unknown>");
 }
 
 QColor
@@ -85,7 +124,7 @@
 
     switch (map) {
 
-    case DefaultColours:
+    case Green:
         h = blue - norm * 2.0 * pieslice;
         s = 0.5f + norm/2.0;
         v = norm;
@@ -101,30 +140,17 @@
         hsv = false;
         break;
 
-    case RedOnBlue:
-        h = blue - pieslice/4.0 + norm * (pieslice + pieslice/4.0);
-        s = 1.0;
-        v = norm;
+    case Cherry:
+        hsv = false;
+        mapDiscrete(norm, cherry, r, g, b);
         break;
 
-    case YellowOnBlack:
+    case Wasp:
         h = 0.15;
         s = 1.0;
         v = norm;
         break;
 
-    case BlueOnBlack:
-        h = blue;
-        s = 1.0;
-        v = norm * 2.0;
-        if (v > 1.0) {
-            v = 1.0;
-            s = 1.0 - (sqrt(norm) - 0.707) * 3.413;
-            if (s < 0.0) s = 0.0;
-            if (s > 1.0) s = 1.0;
-        }
-        break;
-
     case Sunset:
         r = (norm - 0.24) * 2.38;
         if (r > 1.0) r = 1.0;
@@ -207,6 +233,10 @@
         hsv = false;
 */
         break;
+
+    case Ice:
+        hsv = false;
+        mapDiscrete(norm, ice, r, g, b);
     }
 
     if (hsv) {
@@ -224,7 +254,7 @@
 
     switch (map) {
 
-    case DefaultColours:
+    case Green:
         return QColor(255, 150, 50);
 
     case WhiteOnBlack:
@@ -233,13 +263,13 @@
     case BlackOnWhite:
         return Qt::darkGreen;
 
-    case RedOnBlue:
+    case Cherry:
         return Qt::green;
 
-    case YellowOnBlack:
+    case Wasp:
         return QColor::fromHsv(240, 255, 255);
 
-    case BlueOnBlack:
+    case Ice:
         return Qt::red;
 
     case Sunset:
@@ -277,12 +307,12 @@
     case HighGain:
         return true;
 
-    case DefaultColours:
+    case Green:
     case Sunset:
     case WhiteOnBlack:
-    case RedOnBlue:
-    case YellowOnBlack:
-    case BlueOnBlack:
+    case Cherry:
+    case Wasp:
+    case Ice:
     case FruitSalad:
     case Banded:
     case Highlight:
@@ -292,4 +322,29 @@
     }
 }
 
+QPixmap
+ColourMapper::getExamplePixmap(QSize size) const
+{
+    QPixmap pmap(size);
+    pmap.fill(Qt::white);
+    QPainter paint(&pmap);
 
+    int w = size.width(), h = size.height();
+    
+    int margin = 2;
+    if (w < 4 || h < 4) margin = 0;
+    else if (w < 8 || h < 8) margin = 1;
+
+    int n = w - margin*2;
+    
+    for (int x = 0; x < n; ++x) {
+        double value = m_min + ((m_max - m_min) * x) / (n-1);
+        QColor colour(map(value));
+        paint.setPen(colour);
+        paint.drawLine(x + margin, margin, x + margin, h - margin);
+    }
+    
+    return pmap;
+}
+
+