annotate layer/ColourMapper.cpp @ 1556:ac8da42674ff spectrogram-export

Handle peaks
author Chris Cannam
date Tue, 07 Jan 2020 11:18:57 +0000
parents c8a6fd3f9dff
children
rev   line source
Chris@376 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@376 2
Chris@376 3 /*
Chris@376 4 Sonic Visualiser
Chris@376 5 An audio file viewer and annotation editor.
Chris@376 6 Centre for Digital Music, Queen Mary, University of London.
Chris@1199 7 This file copyright 2006-2016 Chris Cannam and QMUL.
Chris@376 8
Chris@376 9 This program is free software; you can redistribute it and/or
Chris@376 10 modify it under the terms of the GNU General Public License as
Chris@376 11 published by the Free Software Foundation; either version 2 of the
Chris@376 12 License, or (at your option) any later version. See the file
Chris@376 13 COPYING included with this distribution for more information.
Chris@376 14 */
Chris@376 15
Chris@376 16 #include "ColourMapper.h"
Chris@376 17
Chris@376 18 #include <iostream>
Chris@376 19
Chris@376 20 #include <cmath>
Chris@376 21
Chris@682 22 #include "base/Debug.h"
Chris@682 23
Chris@1012 24 #include <vector>
Chris@1012 25
Chris@1199 26 #include <QPainter>
Chris@1199 27
Chris@1012 28 using namespace std;
Chris@1012 29
Chris@1362 30 static vector<QColor> convertStrings(const vector<QString> &strs,
Chris@1362 31 bool reversed)
Chris@1012 32 {
Chris@1012 33 vector<QColor> converted;
Chris@1012 34 for (const auto &s: strs) converted.push_back(QColor(s));
Chris@1362 35 if (reversed) {
Chris@1362 36 reverse(converted.begin(), converted.end());
Chris@1362 37 }
Chris@1012 38 return converted;
Chris@1012 39 }
Chris@1012 40
Chris@1017 41 static vector<QColor> ice = convertStrings({
Chris@1015 42 // Based on ColorBrewer ylGnBu
Chris@1015 43 "#ffffff", "#ffff00", "#f7fcf0", "#e0f3db", "#ccebc5", "#a8ddb5",
Chris@1015 44 "#7bccc4", "#4eb3d3", "#2b8cbe", "#0868ac", "#084081", "#042040"
Chris@1362 45 },
Chris@1362 46 true);
Chris@1012 47
Chris@1017 48 static vector<QColor> cherry = convertStrings({
Chris@1016 49 "#f7f7f7", "#fddbc7", "#f4a582", "#d6604d", "#b2182b", "#dd3497",
Chris@1016 50 "#ae017e", "#7a0177", "#49006a"
Chris@1362 51 },
Chris@1362 52 true);
Chris@1362 53
Chris@1362 54 static vector<QColor> magma = convertStrings({
Chris@1362 55 "#FCFFB2", "#FCDF96", "#FBC17D", "#FBA368", "#FA8657", "#F66B4D",
Chris@1362 56 "#ED504A", "#E03B50", "#C92D59", "#B02363", "#981D69", "#81176D",
Chris@1362 57 "#6B116F", "#57096E", "#43006A", "#300060", "#1E0848", "#110B2D",
Chris@1362 58 "#080616", "#000005"
Chris@1362 59 },
Chris@1362 60 true);
Chris@1362 61
Chris@1362 62 static vector<QColor> cividis = convertStrings({
Chris@1362 63 "#00204c", "#00204e", "#002150", "#002251", "#002353", "#002355",
Chris@1362 64 "#002456", "#002558", "#00265a", "#00265b", "#00275d", "#00285f",
Chris@1362 65 "#002861", "#002963", "#002a64", "#002a66", "#002b68", "#002c6a",
Chris@1362 66 "#002d6c", "#002d6d", "#002e6e", "#002e6f", "#002f6f", "#002f6f",
Chris@1362 67 "#00306f", "#00316f", "#00316f", "#00326e", "#00336e", "#00346e",
Chris@1362 68 "#00346e", "#01356e", "#06366e", "#0a376d", "#0e376d", "#12386d",
Chris@1362 69 "#15396d", "#17396d", "#1a3a6c", "#1c3b6c", "#1e3c6c", "#203c6c",
Chris@1362 70 "#223d6c", "#243e6c", "#263e6c", "#273f6c", "#29406b", "#2b416b",
Chris@1362 71 "#2c416b", "#2e426b", "#2f436b", "#31446b", "#32446b", "#33456b",
Chris@1362 72 "#35466b", "#36466b", "#37476b", "#38486b", "#3a496b", "#3b496b",
Chris@1362 73 "#3c4a6b", "#3d4b6b", "#3e4b6b", "#404c6b", "#414d6b", "#424e6b",
Chris@1362 74 "#434e6b", "#444f6b", "#45506b", "#46506b", "#47516b", "#48526b",
Chris@1362 75 "#49536b", "#4a536b", "#4b546b", "#4c556b", "#4d556b", "#4e566b",
Chris@1362 76 "#4f576c", "#50586c", "#51586c", "#52596c", "#535a6c", "#545a6c",
Chris@1362 77 "#555b6c", "#565c6c", "#575d6d", "#585d6d", "#595e6d", "#5a5f6d",
Chris@1362 78 "#5b5f6d", "#5c606d", "#5d616e", "#5e626e", "#5f626e", "#5f636e",
Chris@1362 79 "#60646e", "#61656f", "#62656f", "#63666f", "#64676f", "#65676f",
Chris@1362 80 "#666870", "#676970", "#686a70", "#686a70", "#696b71", "#6a6c71",
Chris@1362 81 "#6b6d71", "#6c6d72", "#6d6e72", "#6e6f72", "#6f6f72", "#6f7073",
Chris@1362 82 "#707173", "#717273", "#727274", "#737374", "#747475", "#757575",
Chris@1362 83 "#757575", "#767676", "#777776", "#787876", "#797877", "#7a7977",
Chris@1362 84 "#7b7a77", "#7b7b78", "#7c7b78", "#7d7c78", "#7e7d78", "#7f7e78",
Chris@1362 85 "#807e78", "#817f78", "#828078", "#838178", "#848178", "#858278",
Chris@1362 86 "#868378", "#878478", "#888578", "#898578", "#8a8678", "#8b8778",
Chris@1362 87 "#8c8878", "#8d8878", "#8e8978", "#8f8a78", "#908b78", "#918c78",
Chris@1362 88 "#928c78", "#938d78", "#948e78", "#958f78", "#968f77", "#979077",
Chris@1362 89 "#989177", "#999277", "#9a9377", "#9b9377", "#9c9477", "#9d9577",
Chris@1362 90 "#9e9676", "#9f9776", "#a09876", "#a19876", "#a29976", "#a39a75",
Chris@1362 91 "#a49b75", "#a59c75", "#a69c75", "#a79d75", "#a89e74", "#a99f74",
Chris@1362 92 "#aaa074", "#aba174", "#aca173", "#ada273", "#aea373", "#afa473",
Chris@1362 93 "#b0a572", "#b1a672", "#b2a672", "#b4a771", "#b5a871", "#b6a971",
Chris@1362 94 "#b7aa70", "#b8ab70", "#b9ab70", "#baac6f", "#bbad6f", "#bcae6e",
Chris@1362 95 "#bdaf6e", "#beb06e", "#bfb16d", "#c0b16d", "#c1b26c", "#c2b36c",
Chris@1362 96 "#c3b46c", "#c5b56b", "#c6b66b", "#c7b76a", "#c8b86a", "#c9b869",
Chris@1362 97 "#cab969", "#cbba68", "#ccbb68", "#cdbc67", "#cebd67", "#d0be66",
Chris@1362 98 "#d1bf66", "#d2c065", "#d3c065", "#d4c164", "#d5c263", "#d6c363",
Chris@1362 99 "#d7c462", "#d8c561", "#d9c661", "#dbc760", "#dcc860", "#ddc95f",
Chris@1362 100 "#deca5e", "#dfcb5d", "#e0cb5d", "#e1cc5c", "#e3cd5b", "#e4ce5b",
Chris@1362 101 "#e5cf5a", "#e6d059", "#e7d158", "#e8d257", "#e9d356", "#ebd456",
Chris@1362 102 "#ecd555", "#edd654", "#eed753", "#efd852", "#f0d951", "#f1da50",
Chris@1362 103 "#f3db4f", "#f4dc4e", "#f5dd4d", "#f6de4c", "#f7df4b", "#f9e049",
Chris@1362 104 "#fae048", "#fbe147", "#fce246", "#fde345", "#ffe443", "#ffe542",
Chris@1362 105 "#ffe642", "#ffe743", "#ffe844", "#ffe945"
Chris@1362 106 },
Chris@1362 107 false);
Chris@1362 108
Chris@1012 109 static void
Chris@1012 110 mapDiscrete(double norm, vector<QColor> &colours, double &r, double &g, double &b)
Chris@1012 111 {
Chris@1015 112 int n = int(colours.size());
Chris@1012 113 double m = norm * (n-1);
Chris@1408 114 if (m >= n-1) { colours[n-1].getRgbF(&r, &g, &b, nullptr); return; }
Chris@1408 115 if (m <= 0) { colours[0].getRgbF(&r, &g, &b, nullptr); return; }
Chris@1012 116 int base(int(floor(m)));
Chris@1012 117 double prop0 = (base + 1.0) - m, prop1 = m - base;
Chris@1012 118 QColor c0(colours[base]), c1(colours[base+1]);
Chris@1012 119 r = c0.redF() * prop0 + c1.redF() * prop1;
Chris@1012 120 g = c0.greenF() * prop0 + c1.greenF() * prop1;
Chris@1012 121 b = c0.blueF() * prop0 + c1.blueF() * prop1;
Chris@1012 122 }
Chris@1012 123
Chris@1362 124 ColourMapper::ColourMapper(int map, bool inverted, double min, double max) :
Chris@376 125 m_map(map),
Chris@1362 126 m_inverted(inverted),
Chris@376 127 m_min(min),
Chris@376 128 m_max(max)
Chris@376 129 {
Chris@376 130 if (m_min == m_max) {
Chris@1265 131 SVCERR << "WARNING: ColourMapper: min == max (== " << m_min
Chris@682 132 << "), adjusting" << endl;
Chris@376 133 m_max = m_min + 1;
Chris@376 134 }
Chris@376 135 }
Chris@376 136
Chris@376 137 ColourMapper::~ColourMapper()
Chris@376 138 {
Chris@376 139 }
Chris@376 140
Chris@376 141 int
Chris@376 142 ColourMapper::getColourMapCount()
Chris@376 143 {
Chris@1362 144 return 15;
Chris@376 145 }
Chris@376 146
Chris@376 147 QString
Chris@1362 148 ColourMapper::getColourMapLabel(int n)
Chris@376 149 {
Chris@1362 150 // When adding a map, be sure to also update getColourMapCount()
Chris@1362 151
Chris@1071 152 if (n >= getColourMapCount()) return QObject::tr("<unknown>");
Chris@1362 153 ColourMap map = (ColourMap)n;
Chris@376 154
Chris@376 155 switch (map) {
Chris@1071 156 case Green: return QObject::tr("Green");
Chris@1071 157 case WhiteOnBlack: return QObject::tr("White on Black");
Chris@1071 158 case BlackOnWhite: return QObject::tr("Black on White");
Chris@1071 159 case Cherry: return QObject::tr("Cherry");
Chris@1071 160 case Wasp: return QObject::tr("Wasp");
Chris@1071 161 case Ice: return QObject::tr("Ice");
Chris@1071 162 case Sunset: return QObject::tr("Sunset");
Chris@1071 163 case FruitSalad: return QObject::tr("Fruit Salad");
Chris@1071 164 case Banded: return QObject::tr("Banded");
Chris@1071 165 case Highlight: return QObject::tr("Highlight");
Chris@1071 166 case Printer: return QObject::tr("Printer");
Chris@1071 167 case HighGain: return QObject::tr("High Gain");
Chris@1362 168 case BlueOnBlack: return QObject::tr("Blue on Black");
Chris@1362 169 case Cividis: return QObject::tr("Cividis");
Chris@1362 170 case Magma: return QObject::tr("Magma");
Chris@376 171 }
Chris@376 172
Chris@1071 173 return QObject::tr("<unknown>");
Chris@376 174 }
Chris@376 175
Chris@1362 176 QString
Chris@1362 177 ColourMapper::getColourMapId(int n)
Chris@1362 178 {
Chris@1362 179 if (n >= getColourMapCount()) return "<unknown>";
Chris@1362 180 ColourMap map = (ColourMap)n;
Chris@1362 181
Chris@1362 182 switch (map) {
Chris@1362 183 case Green: return "Green";
Chris@1362 184 case WhiteOnBlack: return "White on Black";
Chris@1362 185 case BlackOnWhite: return "Black on White";
Chris@1362 186 case Cherry: return "Cherry";
Chris@1362 187 case Wasp: return "Wasp";
Chris@1362 188 case Ice: return "Ice";
Chris@1362 189 case Sunset: return "Sunset";
Chris@1362 190 case FruitSalad: return "Fruit Salad";
Chris@1362 191 case Banded: return "Banded";
Chris@1362 192 case Highlight: return "Highlight";
Chris@1362 193 case Printer: return "Printer";
Chris@1362 194 case HighGain: return "High Gain";
Chris@1362 195 case BlueOnBlack: return "Blue on Black";
Chris@1362 196 case Cividis: return "Cividis";
Chris@1362 197 case Magma: return "Magma";
Chris@1362 198 }
Chris@1362 199
Chris@1362 200 return "<unknown>";
Chris@1362 201 }
Chris@1362 202
Chris@1362 203 int
Chris@1362 204 ColourMapper::getColourMapById(QString id)
Chris@1362 205 {
Chris@1362 206 ColourMap map = (ColourMap)getColourMapCount();
Chris@1362 207
Chris@1362 208 if (id == "Green") { map = Green; }
Chris@1362 209 else if (id == "White on Black") { map = WhiteOnBlack; }
Chris@1362 210 else if (id == "Black on White") { map = BlackOnWhite; }
Chris@1362 211 else if (id == "Cherry") { map = Cherry; }
Chris@1362 212 else if (id == "Wasp") { map = Wasp; }
Chris@1362 213 else if (id == "Ice") { map = Ice; }
Chris@1362 214 else if (id == "Sunset") { map = Sunset; }
Chris@1362 215 else if (id == "Fruit Salad") { map = FruitSalad; }
Chris@1362 216 else if (id == "Banded") { map = Banded; }
Chris@1362 217 else if (id == "Highlight") { map = Highlight; }
Chris@1362 218 else if (id == "Printer") { map = Printer; }
Chris@1362 219 else if (id == "High Gain") { map = HighGain; }
Chris@1362 220 else if (id == "Blue on Black") { map = BlueOnBlack; }
Chris@1362 221 else if (id == "Cividis") { map = Cividis; }
Chris@1362 222 else if (id == "Magma") { map = Magma; }
Chris@1362 223
Chris@1362 224 if (map == (ColourMap)getColourMapCount()) {
Chris@1362 225 return -1;
Chris@1362 226 } else {
Chris@1362 227 return int(map);
Chris@1362 228 }
Chris@1362 229 }
Chris@1362 230
Chris@1362 231 int
Chris@1362 232 ColourMapper::getBackwardCompatibilityColourMap(int n)
Chris@1362 233 {
Chris@1362 234 /* Returned value should be an index into the series
Chris@1362 235 * (Default/Green, Sunset, WhiteOnBlack, BlackOnWhite, RedOnBlue,
Chris@1362 236 * YellowOnBlack, BlueOnBlack, FruitSalad, Banded, Highlight,
Chris@1362 237 * Printer, HighGain). Minimum 0, maximum 11.
Chris@1362 238 */
Chris@1362 239
Chris@1362 240 if (n >= getColourMapCount()) return 0;
Chris@1362 241 ColourMap map = (ColourMap)n;
Chris@1362 242
Chris@1362 243 switch (map) {
Chris@1362 244 case Green: return 0;
Chris@1362 245 case WhiteOnBlack: return 2;
Chris@1362 246 case BlackOnWhite: return 3;
Chris@1362 247 case Cherry: return 4;
Chris@1362 248 case Wasp: return 5;
Chris@1362 249 case Ice: return 6;
Chris@1362 250 case Sunset: return 1;
Chris@1362 251 case FruitSalad: return 7;
Chris@1362 252 case Banded: return 8;
Chris@1362 253 case Highlight: return 9;
Chris@1362 254 case Printer: return 10;
Chris@1362 255 case HighGain: return 11;
Chris@1362 256 case BlueOnBlack: return 6;
Chris@1362 257 case Cividis: return 6;
Chris@1362 258 case Magma: return 1;
Chris@1362 259 }
Chris@1362 260
Chris@1362 261 return 0;
Chris@1362 262 }
Chris@1362 263
Chris@376 264 QColor
Chris@902 265 ColourMapper::map(double value) const
Chris@376 266 {
Chris@902 267 double norm = (value - m_min) / (m_max - m_min);
Chris@902 268 if (norm < 0.0) norm = 0.0;
Chris@902 269 if (norm > 1.0) norm = 1.0;
Chris@1362 270
Chris@1362 271 if (m_inverted) {
Chris@1362 272 norm = 1.0 - norm;
Chris@1362 273 }
Chris@376 274
Chris@902 275 double h = 0.0, s = 0.0, v = 0.0, r = 0.0, g = 0.0, b = 0.0;
Chris@376 276 bool hsv = true;
Chris@376 277
Chris@911 278 double blue = 0.6666, pieslice = 0.3333;
Chris@376 279
Chris@376 280 if (m_map >= getColourMapCount()) return Qt::black;
Chris@1362 281 ColourMap map = (ColourMap)m_map;
Chris@376 282
Chris@376 283 switch (map) {
Chris@376 284
Chris@1017 285 case Green:
Chris@902 286 h = blue - norm * 2.0 * pieslice;
Chris@902 287 s = 0.5f + norm/2.0;
Chris@376 288 v = norm;
Chris@376 289 break;
Chris@376 290
Chris@376 291 case WhiteOnBlack:
Chris@376 292 r = g = b = norm;
Chris@376 293 hsv = false;
Chris@376 294 break;
Chris@376 295
Chris@376 296 case BlackOnWhite:
Chris@902 297 r = g = b = 1.0 - norm;
Chris@376 298 hsv = false;
Chris@376 299 break;
Chris@376 300
Chris@1017 301 case Cherry:
Chris@1015 302 hsv = false;
Chris@1017 303 mapDiscrete(norm, cherry, r, g, b);
Chris@376 304 break;
Chris@376 305
Chris@1017 306 case Wasp:
Chris@902 307 h = 0.15;
Chris@902 308 s = 1.0;
Chris@376 309 v = norm;
Chris@376 310 break;
Chris@1362 311
Chris@1362 312 case BlueOnBlack:
Chris@1362 313 h = blue;
Chris@1362 314 s = 1.0;
Chris@1362 315 v = norm * 2.0;
Chris@1362 316 if (v > 1.0) {
Chris@1362 317 v = 1.0;
Chris@1362 318 s = 1.0 - (sqrt(norm) - 0.707) * 3.413;
Chris@1362 319 if (s < 0.0) s = 0.0;
Chris@1362 320 if (s > 1.0) s = 1.0;
Chris@1362 321 }
Chris@1362 322 break;
Chris@376 323
Chris@376 324 case Sunset:
Chris@902 325 r = (norm - 0.24) * 2.38;
Chris@902 326 if (r > 1.0) r = 1.0;
Chris@902 327 if (r < 0.0) r = 0.0;
Chris@902 328 g = (norm - 0.64) * 2.777;
Chris@902 329 if (g > 1.0) g = 1.0;
Chris@902 330 if (g < 0.0) g = 0.0;
Chris@376 331 b = (3.6f * norm);
Chris@902 332 if (norm > 0.277) b = 2.0 - b;
Chris@902 333 if (b > 1.0) b = 1.0;
Chris@902 334 if (b < 0.0) b = 0.0;
Chris@376 335 hsv = false;
Chris@376 336 break;
Chris@376 337
Chris@376 338 case FruitSalad:
Chris@902 339 h = blue + (pieslice/6.0) - norm;
Chris@902 340 if (h < 0.0) h += 1.0;
Chris@902 341 s = 1.0;
Chris@902 342 v = 1.0;
Chris@376 343 break;
Chris@376 344
Chris@376 345 case Banded:
Chris@376 346 if (norm < 0.125) return Qt::darkGreen;
Chris@376 347 else if (norm < 0.25) return Qt::green;
Chris@376 348 else if (norm < 0.375) return Qt::darkBlue;
Chris@376 349 else if (norm < 0.5) return Qt::blue;
Chris@376 350 else if (norm < 0.625) return Qt::darkYellow;
Chris@376 351 else if (norm < 0.75) return Qt::yellow;
Chris@376 352 else if (norm < 0.875) return Qt::darkRed;
Chris@376 353 else return Qt::red;
Chris@376 354 break;
Chris@376 355
Chris@376 356 case Highlight:
Chris@376 357 if (norm > 0.99) return Qt::white;
Chris@376 358 else return Qt::darkBlue;
Chris@376 359
Chris@376 360 case Printer:
Chris@376 361 if (norm > 0.8) {
Chris@902 362 r = 1.0;
Chris@376 363 } else if (norm > 0.7) {
Chris@902 364 r = 0.9;
Chris@376 365 } else if (norm > 0.6) {
Chris@902 366 r = 0.8;
Chris@376 367 } else if (norm > 0.5) {
Chris@902 368 r = 0.7;
Chris@376 369 } else if (norm > 0.4) {
Chris@902 370 r = 0.6;
Chris@376 371 } else if (norm > 0.3) {
Chris@902 372 r = 0.5;
Chris@376 373 } else if (norm > 0.2) {
Chris@902 374 r = 0.4;
Chris@376 375 } else {
Chris@902 376 r = 0.0;
Chris@376 377 }
Chris@902 378 r = g = b = 1.0 - r;
Chris@376 379 hsv = false;
Chris@376 380 break;
Chris@536 381
Chris@536 382 case HighGain:
Chris@902 383 if (norm <= 1.0 / 256.0) {
Chris@902 384 norm = 0.0;
Chris@536 385 } else {
Chris@904 386 norm = 0.1f + (pow(((norm - 0.5) * 2.0), 3.0) + 1.0) / 2.081;
Chris@536 387 }
Chris@536 388 // now as for Sunset
Chris@902 389 r = (norm - 0.24) * 2.38;
Chris@902 390 if (r > 1.0) r = 1.0;
Chris@902 391 if (r < 0.0) r = 0.0;
Chris@902 392 g = (norm - 0.64) * 2.777;
Chris@902 393 if (g > 1.0) g = 1.0;
Chris@902 394 if (g < 0.0) g = 0.0;
Chris@536 395 b = (3.6f * norm);
Chris@902 396 if (norm > 0.277) b = 2.0 - b;
Chris@902 397 if (b > 1.0) b = 1.0;
Chris@902 398 if (b < 0.0) b = 0.0;
Chris@536 399 hsv = false;
Chris@536 400 /*
Chris@902 401 if (r > 1.0) r = 1.0;
Chris@902 402 r = g = b = 1.0 - r;
Chris@536 403 hsv = false;
Chris@536 404 */
Chris@536 405 break;
Chris@1012 406
Chris@1017 407 case Ice:
Chris@1012 408 hsv = false;
Chris@1017 409 mapDiscrete(norm, ice, r, g, b);
Chris@1362 410 break;
Chris@1362 411
Chris@1362 412 case Cividis:
Chris@1362 413 hsv = false;
Chris@1362 414 mapDiscrete(norm, cividis, r, g, b);
Chris@1362 415 break;
Chris@1362 416
Chris@1362 417 case Magma:
Chris@1362 418 hsv = false;
Chris@1362 419 mapDiscrete(norm, magma, r, g, b);
Chris@1362 420 break;
Chris@376 421 }
Chris@376 422
Chris@376 423 if (hsv) {
Chris@376 424 return QColor::fromHsvF(h, s, v);
Chris@376 425 } else {
Chris@376 426 return QColor::fromRgbF(r, g, b);
Chris@376 427 }
Chris@376 428 }
Chris@376 429
Chris@376 430 QColor
Chris@376 431 ColourMapper::getContrastingColour() const
Chris@376 432 {
Chris@376 433 if (m_map >= getColourMapCount()) return Qt::white;
Chris@1362 434 ColourMap map = (ColourMap)m_map;
Chris@376 435
Chris@376 436 switch (map) {
Chris@376 437
Chris@1017 438 case Green:
Chris@376 439 return QColor(255, 150, 50);
Chris@376 440
Chris@376 441 case WhiteOnBlack:
Chris@376 442 return Qt::red;
Chris@376 443
Chris@376 444 case BlackOnWhite:
Chris@376 445 return Qt::darkGreen;
Chris@376 446
Chris@1017 447 case Cherry:
Chris@376 448 return Qt::green;
Chris@376 449
Chris@1017 450 case Wasp:
Chris@376 451 return QColor::fromHsv(240, 255, 255);
Chris@376 452
Chris@1017 453 case Ice:
Chris@376 454 return Qt::red;
Chris@376 455
Chris@376 456 case Sunset:
Chris@376 457 return Qt::white;
Chris@376 458
Chris@376 459 case FruitSalad:
Chris@376 460 return Qt::white;
Chris@376 461
Chris@376 462 case Banded:
Chris@376 463 return Qt::cyan;
Chris@376 464
Chris@376 465 case Highlight:
Chris@376 466 return Qt::red;
Chris@376 467
Chris@376 468 case Printer:
Chris@376 469 return Qt::red;
Chris@536 470
Chris@536 471 case HighGain:
Chris@536 472 return Qt::red;
Chris@1362 473
Chris@1362 474 case BlueOnBlack:
Chris@1362 475 return Qt::red;
Chris@1362 476
Chris@1362 477 case Cividis:
Chris@1362 478 return Qt::white;
Chris@1362 479
Chris@1362 480 case Magma:
Chris@1362 481 return Qt::white;
Chris@376 482 }
Chris@376 483
Chris@376 484 return Qt::white;
Chris@376 485 }
Chris@376 486
Chris@376 487 bool
Chris@376 488 ColourMapper::hasLightBackground() const
Chris@376 489 {
Chris@376 490 if (m_map >= getColourMapCount()) return false;
Chris@1362 491 ColourMap map = (ColourMap)m_map;
Chris@376 492
Chris@376 493 switch (map) {
Chris@376 494
Chris@376 495 case BlackOnWhite:
Chris@376 496 case Printer:
Chris@536 497 case HighGain:
Chris@376 498 return true;
Chris@376 499
Chris@1017 500 case Green:
Chris@805 501 case Sunset:
Chris@805 502 case WhiteOnBlack:
Chris@1017 503 case Cherry:
Chris@1017 504 case Wasp:
Chris@1017 505 case Ice:
Chris@805 506 case FruitSalad:
Chris@805 507 case Banded:
Chris@805 508 case Highlight:
Chris@1362 509 case BlueOnBlack:
Chris@1362 510 case Cividis:
Chris@1362 511 case Magma:
Chris@805 512
Chris@376 513 default:
Chris@376 514 return false;
Chris@376 515 }
Chris@376 516 }
Chris@376 517
Chris@1199 518 QPixmap
Chris@1199 519 ColourMapper::getExamplePixmap(QSize size) const
Chris@1199 520 {
Chris@1199 521 QPixmap pmap(size);
Chris@1199 522 pmap.fill(Qt::white);
Chris@1199 523 QPainter paint(&pmap);
Chris@376 524
Chris@1199 525 int w = size.width(), h = size.height();
Chris@1199 526
Chris@1199 527 int margin = 2;
Chris@1199 528 if (w < 4 || h < 4) margin = 0;
Chris@1199 529 else if (w < 8 || h < 8) margin = 1;
Chris@1199 530
Chris@1199 531 int n = w - margin*2;
Chris@1199 532
Chris@1199 533 for (int x = 0; x < n; ++x) {
Chris@1199 534 double value = m_min + ((m_max - m_min) * x) / (n-1);
Chris@1199 535 QColor colour(map(value));
Chris@1199 536 paint.setPen(colour);
Chris@1199 537 paint.drawLine(x + margin, margin, x + margin, h - margin);
Chris@1199 538 }
Chris@1199 539
Chris@1199 540 return pmap;
Chris@1199 541 }
Chris@1199 542
Chris@1199 543