comparison base/ColourMapper.cpp @ 277:3b8008d09541

* Add a colour database, and Add New Colour function to the colour combo in property box. The colour property is only correctly handled in the waveform layer so far. * Add en_GB translation, to translate those annoying Color texts in the Qt colour picker dialog.
author Chris Cannam
date Wed, 11 Jul 2007 17:21:37 +0000
parents
children
comparison
equal deleted inserted replaced
276:657825878970 277:3b8008d09541
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2
3 /*
4 Sonic Visualiser
5 An audio file viewer and annotation editor.
6 Centre for Digital Music, Queen Mary, University of London.
7 This file copyright 2006-2007 Chris Cannam and QMUL.
8
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
11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version. See the file
13 COPYING included with this distribution for more information.
14 */
15
16 #include "ColourMapper.h"
17
18 #include <iostream>
19
20 #include <cmath>
21
22 ColourMapper::ColourMapper(int map, float min, float max) :
23 QObject(),
24 m_map(map),
25 m_min(min),
26 m_max(max)
27 {
28 if (m_min == m_max) {
29 std::cerr << "WARNING: ColourMapper: min == max (== " << m_min
30 << "), adjusting" << std::endl;
31 m_max = m_min + 1;
32 }
33 }
34
35 ColourMapper::~ColourMapper()
36 {
37 }
38
39 int
40 ColourMapper::getColourMapCount()
41 {
42 return 11;
43 }
44
45 QString
46 ColourMapper::getColourMapName(int n)
47 {
48 if (n >= getColourMapCount()) return tr("<unknown>");
49 StandardMap map = (StandardMap)n;
50
51 switch (map) {
52 case DefaultColours: return tr("Default");
53 case WhiteOnBlack: return tr("White on Black");
54 case BlackOnWhite: return tr("Black on White");
55 case RedOnBlue: return tr("Red on Blue");
56 case YellowOnBlack: return tr("Yellow on Black");
57 case BlueOnBlack: return tr("Blue on Black");
58 case Sunset: return tr("Sunset");
59 case FruitSalad: return tr("Fruit Salad");
60 case Banded: return tr("Banded");
61 case Highlight: return tr("Highlight");
62 case Printer: return tr("Printer");
63 }
64
65 return tr("<unknown>");
66 }
67
68 QColor
69 ColourMapper::map(float value) const
70 {
71 float norm = (value - m_min) / (m_max - m_min);
72 if (norm < 0.f) norm = 0.f;
73 if (norm > 1.f) norm = 1.f;
74
75 float h = 0.f, s = 0.f, v = 0.f, r = 0.f, g = 0.f, b = 0.f;
76 bool hsv = true;
77
78 // float red = 0.f, green = 0.3333f;
79 float blue = 0.6666f, pieslice = 0.3333f;
80
81 if (m_map >= getColourMapCount()) return Qt::black;
82 StandardMap map = (StandardMap)m_map;
83
84 switch (map) {
85
86 case DefaultColours:
87 h = blue - norm * 2.f * pieslice;
88 s = 0.5f + norm/2.f;
89 v = norm;
90 break;
91
92 case WhiteOnBlack:
93 r = g = b = norm;
94 hsv = false;
95 break;
96
97 case BlackOnWhite:
98 r = g = b = 1.f - norm;
99 hsv = false;
100 break;
101
102 case RedOnBlue:
103 h = blue - pieslice/4.f + norm * (pieslice + pieslice/4.f);
104 s = 1.f;
105 v = norm;
106 break;
107
108 case YellowOnBlack:
109 h = 0.15f;
110 s = 1.f;
111 v = norm;
112 break;
113
114 case BlueOnBlack:
115 h = blue;
116 s = 1.f;
117 v = norm * 2.f;
118 if (v > 1.f) {
119 v = 1.f;
120 s = 1.f - (sqrtf(norm) - 0.707f) * 3.413f;
121 if (s < 0.f) s = 0.f;
122 if (s > 1.f) s = 1.f;
123 }
124 break;
125
126 case Sunset:
127 r = (norm - 0.24f) * 2.38f;
128 if (r > 1.f) r = 1.f;
129 if (r < 0.f) r = 0.f;
130 g = (norm - 0.64f) * 2.777f;
131 if (g > 1.f) g = 1.f;
132 if (g < 0.f) g = 0.f;
133 b = (3.6f * norm);
134 if (norm > 0.277f) b = 2.f - b;
135 if (b > 1.f) b = 1.f;
136 if (b < 0.f) b = 0.f;
137 hsv = false;
138 break;
139
140 case FruitSalad:
141 h = blue + (pieslice/6.f) - norm;
142 if (h < 0.f) h += 1.f;
143 s = 1.f;
144 v = 1.f;
145 break;
146
147 case Banded:
148 if (norm < 0.125) return Qt::darkGreen;
149 else if (norm < 0.25) return Qt::green;
150 else if (norm < 0.375) return Qt::darkBlue;
151 else if (norm < 0.5) return Qt::blue;
152 else if (norm < 0.625) return Qt::darkYellow;
153 else if (norm < 0.75) return Qt::yellow;
154 else if (norm < 0.875) return Qt::darkRed;
155 else return Qt::red;
156 break;
157
158 case Highlight:
159 if (norm > 0.99) return Qt::white;
160 else return Qt::darkBlue;
161
162 case Printer:
163 if (norm > 0.8) {
164 r = 1.f;
165 } else if (norm > 0.7) {
166 r = 0.9f;
167 } else if (norm > 0.6) {
168 r = 0.8f;
169 } else if (norm > 0.5) {
170 r = 0.7f;
171 } else if (norm > 0.4) {
172 r = 0.6f;
173 } else if (norm > 0.3) {
174 r = 0.5f;
175 } else if (norm > 0.2) {
176 r = 0.4f;
177 } else {
178 r = 0.f;
179 }
180 r = g = b = 1.f - r;
181 hsv = false;
182 break;
183 }
184
185 if (hsv) {
186 return QColor::fromHsvF(h, s, v);
187 } else {
188 return QColor::fromRgbF(r, g, b);
189 }
190 }
191
192 QColor
193 ColourMapper::getContrastingColour() const
194 {
195 if (m_map >= getColourMapCount()) return Qt::white;
196 StandardMap map = (StandardMap)m_map;
197
198 switch (map) {
199
200 case DefaultColours:
201 return QColor(255, 150, 50);
202
203 case WhiteOnBlack:
204 return Qt::red;
205
206 case BlackOnWhite:
207 return Qt::darkGreen;
208
209 case RedOnBlue:
210 return Qt::green;
211
212 case YellowOnBlack:
213 return QColor::fromHsv(240, 255, 255);
214
215 case BlueOnBlack:
216 return Qt::red;
217
218 case Sunset:
219 return Qt::white;
220
221 case FruitSalad:
222 return Qt::white;
223
224 case Banded:
225 return Qt::cyan;
226
227 case Highlight:
228 return Qt::red;
229
230 case Printer:
231 return Qt::red;
232 }
233
234 return Qt::white;
235 }
236
237 bool
238 ColourMapper::hasLightBackground() const
239 {
240 if (m_map >= getColourMapCount()) return false;
241 StandardMap map = (StandardMap)m_map;
242
243 switch (map) {
244
245 case BlackOnWhite:
246 case Printer:
247 return true;
248
249 default:
250 return false;
251 }
252 }
253
254