comparison 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
comparison
equal deleted inserted replaced
1048:e8102ff5573b 1216:dc2af6616c83
2 2
3 /* 3 /*
4 Sonic Visualiser 4 Sonic Visualiser
5 An audio file viewer and annotation editor. 5 An audio file viewer and annotation editor.
6 Centre for Digital Music, Queen Mary, University of London. 6 Centre for Digital Music, Queen Mary, University of London.
7 This file copyright 2006-2007 Chris Cannam and QMUL. 7 This file copyright 2006-2016 Chris Cannam and QMUL.
8 8
9 This program is free software; you can redistribute it and/or 9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License as 10 modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2 of the 11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version. See the file 12 License, or (at your option) any later version. See the file
19 19
20 #include <cmath> 20 #include <cmath>
21 21
22 #include "base/Debug.h" 22 #include "base/Debug.h"
23 23
24 #include <vector>
25
26 #include <QPainter>
27
28 using namespace std;
29
30 static vector<QColor> convertStrings(const vector<QString> &strs)
31 {
32 vector<QColor> converted;
33 for (const auto &s: strs) converted.push_back(QColor(s));
34 reverse(converted.begin(), converted.end());
35 return converted;
36 }
37
38 static vector<QColor> ice = convertStrings({
39 // Based on ColorBrewer ylGnBu
40 "#ffffff", "#ffff00", "#f7fcf0", "#e0f3db", "#ccebc5", "#a8ddb5",
41 "#7bccc4", "#4eb3d3", "#2b8cbe", "#0868ac", "#084081", "#042040"
42 });
43
44 static vector<QColor> cherry = convertStrings({
45 "#f7f7f7", "#fddbc7", "#f4a582", "#d6604d", "#b2182b", "#dd3497",
46 "#ae017e", "#7a0177", "#49006a"
47 });
48
49 static void
50 mapDiscrete(double norm, vector<QColor> &colours, double &r, double &g, double &b)
51 {
52 int n = int(colours.size());
53 double m = norm * (n-1);
54 if (m >= n-1) { colours[n-1].getRgbF(&r, &g, &b, 0); return; }
55 if (m <= 0) { colours[0].getRgbF(&r, &g, &b, 0); return; }
56 int base(int(floor(m)));
57 double prop0 = (base + 1.0) - m, prop1 = m - base;
58 QColor c0(colours[base]), c1(colours[base+1]);
59 r = c0.redF() * prop0 + c1.redF() * prop1;
60 g = c0.greenF() * prop0 + c1.greenF() * prop1;
61 b = c0.blueF() * prop0 + c1.blueF() * prop1;
62 }
63
24 ColourMapper::ColourMapper(int map, double min, double max) : 64 ColourMapper::ColourMapper(int map, double min, double max) :
25 QObject(),
26 m_map(map), 65 m_map(map),
27 m_min(min), 66 m_min(min),
28 m_max(max) 67 m_max(max)
29 { 68 {
30 if (m_min == m_max) { 69 if (m_min == m_max) {
45 } 84 }
46 85
47 QString 86 QString
48 ColourMapper::getColourMapName(int n) 87 ColourMapper::getColourMapName(int n)
49 { 88 {
50 if (n >= getColourMapCount()) return tr("<unknown>"); 89 if (n >= getColourMapCount()) return QObject::tr("<unknown>");
51 StandardMap map = (StandardMap)n; 90 StandardMap map = (StandardMap)n;
52 91
53 switch (map) { 92 switch (map) {
54 case DefaultColours: return tr("Default"); 93 case Green: return QObject::tr("Green");
55 case WhiteOnBlack: return tr("White on Black"); 94 case WhiteOnBlack: return QObject::tr("White on Black");
56 case BlackOnWhite: return tr("Black on White"); 95 case BlackOnWhite: return QObject::tr("Black on White");
57 case RedOnBlue: return tr("Red on Blue"); 96 case Cherry: return QObject::tr("Cherry");
58 case YellowOnBlack: return tr("Yellow on Black"); 97 case Wasp: return QObject::tr("Wasp");
59 case BlueOnBlack: return tr("Blue on Black"); 98 case Ice: return QObject::tr("Ice");
60 case Sunset: return tr("Sunset"); 99 case Sunset: return QObject::tr("Sunset");
61 case FruitSalad: return tr("Fruit Salad"); 100 case FruitSalad: return QObject::tr("Fruit Salad");
62 case Banded: return tr("Banded"); 101 case Banded: return QObject::tr("Banded");
63 case Highlight: return tr("Highlight"); 102 case Highlight: return QObject::tr("Highlight");
64 case Printer: return tr("Printer"); 103 case Printer: return QObject::tr("Printer");
65 case HighGain: return tr("High Gain"); 104 case HighGain: return QObject::tr("High Gain");
66 } 105 }
67 106
68 return tr("<unknown>"); 107 return QObject::tr("<unknown>");
69 } 108 }
70 109
71 QColor 110 QColor
72 ColourMapper::map(double value) const 111 ColourMapper::map(double value) const
73 { 112 {
83 if (m_map >= getColourMapCount()) return Qt::black; 122 if (m_map >= getColourMapCount()) return Qt::black;
84 StandardMap map = (StandardMap)m_map; 123 StandardMap map = (StandardMap)m_map;
85 124
86 switch (map) { 125 switch (map) {
87 126
88 case DefaultColours: 127 case Green:
89 h = blue - norm * 2.0 * pieslice; 128 h = blue - norm * 2.0 * pieslice;
90 s = 0.5f + norm/2.0; 129 s = 0.5f + norm/2.0;
91 v = norm; 130 v = norm;
92 break; 131 break;
93 132
99 case BlackOnWhite: 138 case BlackOnWhite:
100 r = g = b = 1.0 - norm; 139 r = g = b = 1.0 - norm;
101 hsv = false; 140 hsv = false;
102 break; 141 break;
103 142
104 case RedOnBlue: 143 case Cherry:
105 h = blue - pieslice/4.0 + norm * (pieslice + pieslice/4.0); 144 hsv = false;
106 s = 1.0; 145 mapDiscrete(norm, cherry, r, g, b);
107 v = norm; 146 break;
108 break; 147
109 148 case Wasp:
110 case YellowOnBlack:
111 h = 0.15; 149 h = 0.15;
112 s = 1.0; 150 s = 1.0;
113 v = norm; 151 v = norm;
114 break;
115
116 case BlueOnBlack:
117 h = blue;
118 s = 1.0;
119 v = norm * 2.0;
120 if (v > 1.0) {
121 v = 1.0;
122 s = 1.0 - (sqrt(norm) - 0.707) * 3.413;
123 if (s < 0.0) s = 0.0;
124 if (s > 1.0) s = 1.0;
125 }
126 break; 152 break;
127 153
128 case Sunset: 154 case Sunset:
129 r = (norm - 0.24) * 2.38; 155 r = (norm - 0.24) * 2.38;
130 if (r > 1.0) r = 1.0; 156 if (r > 1.0) r = 1.0;
205 if (r > 1.0) r = 1.0; 231 if (r > 1.0) r = 1.0;
206 r = g = b = 1.0 - r; 232 r = g = b = 1.0 - r;
207 hsv = false; 233 hsv = false;
208 */ 234 */
209 break; 235 break;
236
237 case Ice:
238 hsv = false;
239 mapDiscrete(norm, ice, r, g, b);
210 } 240 }
211 241
212 if (hsv) { 242 if (hsv) {
213 return QColor::fromHsvF(h, s, v); 243 return QColor::fromHsvF(h, s, v);
214 } else { 244 } else {
222 if (m_map >= getColourMapCount()) return Qt::white; 252 if (m_map >= getColourMapCount()) return Qt::white;
223 StandardMap map = (StandardMap)m_map; 253 StandardMap map = (StandardMap)m_map;
224 254
225 switch (map) { 255 switch (map) {
226 256
227 case DefaultColours: 257 case Green:
228 return QColor(255, 150, 50); 258 return QColor(255, 150, 50);
229 259
230 case WhiteOnBlack: 260 case WhiteOnBlack:
231 return Qt::red; 261 return Qt::red;
232 262
233 case BlackOnWhite: 263 case BlackOnWhite:
234 return Qt::darkGreen; 264 return Qt::darkGreen;
235 265
236 case RedOnBlue: 266 case Cherry:
237 return Qt::green; 267 return Qt::green;
238 268
239 case YellowOnBlack: 269 case Wasp:
240 return QColor::fromHsv(240, 255, 255); 270 return QColor::fromHsv(240, 255, 255);
241 271
242 case BlueOnBlack: 272 case Ice:
243 return Qt::red; 273 return Qt::red;
244 274
245 case Sunset: 275 case Sunset:
246 return Qt::white; 276 return Qt::white;
247 277
275 case BlackOnWhite: 305 case BlackOnWhite:
276 case Printer: 306 case Printer:
277 case HighGain: 307 case HighGain:
278 return true; 308 return true;
279 309
280 case DefaultColours: 310 case Green:
281 case Sunset: 311 case Sunset:
282 case WhiteOnBlack: 312 case WhiteOnBlack:
283 case RedOnBlue: 313 case Cherry:
284 case YellowOnBlack: 314 case Wasp:
285 case BlueOnBlack: 315 case Ice:
286 case FruitSalad: 316 case FruitSalad:
287 case Banded: 317 case Banded:
288 case Highlight: 318 case Highlight:
289 319
290 default: 320 default:
291 return false; 321 return false;
292 } 322 }
293 } 323 }
294 324
295 325 QPixmap
326 ColourMapper::getExamplePixmap(QSize size) const
327 {
328 QPixmap pmap(size);
329 pmap.fill(Qt::white);
330 QPainter paint(&pmap);
331
332 int w = size.width(), h = size.height();
333
334 int margin = 2;
335 if (w < 4 || h < 4) margin = 0;
336 else if (w < 8 || h < 8) margin = 1;
337
338 int n = w - margin*2;
339
340 for (int x = 0; x < n; ++x) {
341 double value = m_min + ((m_max - m_min) * x) / (n-1);
342 QColor colour(map(value));
343 paint.setPen(colour);
344 paint.drawLine(x + margin, margin, x + margin, h - margin);
345 }
346
347 return pmap;
348 }
349
350