annotate layer/ColourMapper.cpp @ 1534:bfd8b22fd67c

Fix #1904 Scrolling colour 3d plot does not always work when in View normalisation mode. We shouldn't imagine we've just invalidated the cache if the truth is that we've only just created the renderer
author Chris Cannam
date Wed, 09 Oct 2019 13:45:17 +0100
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