Mercurial > hg > svgui
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 |