1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtOpenGL module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40/*!
41 \class QGLColormap
42 \brief The QGLColormap class is used for installing custom colormaps into
43 a QGLWidget.
44
45 \obsolete
46 \inmodule QtOpenGL
47 \ingroup painting-3D
48 \ingroup shared
49
50 QGLColormap provides a platform independent way of specifying and
51 installing indexed colormaps for a QGLWidget. QGLColormap is
52 especially useful when using the OpenGL color-index mode.
53
54 Under X11 you must use an X server that supports either a \c
55 PseudoColor or \c DirectColor visual class. If your X server
56 currently only provides a \c GrayScale, \c TrueColor, \c
57 StaticColor or \c StaticGray visual, you will not be able to
58 allocate colorcells for writing. If this is the case, try setting
59 your X server to 8 bit mode. It should then provide you with at
60 least a \c PseudoColor visual. Note that you may experience
61 colormap flashing if your X server is running in 8 bit mode.
62
63 The size() of the colormap is always set to 256
64 colors. Note that under Windows you can also install colormaps
65 in child widgets.
66
67 This class uses \l{implicit sharing} as a memory and speed
68 optimization.
69
70 Example of use:
71 \snippet code/src_opengl_qglcolormap.cpp 0
72
73 \sa QGLWidget::setColormap(), QGLWidget::colormap()
74*/
75
76/*!
77 \fn Qt::HANDLE QGLColormap::handle()
78
79 \internal
80
81 Returns the handle for this color map.
82*/
83
84/*!
85 \fn void QGLColormap::setHandle(Qt::HANDLE handle)
86
87 \internal
88
89 Sets the handle for this color map to \a handle.
90*/
91
92#include "qglcolormap.h"
93
94QT_BEGIN_NAMESPACE
95
96QGLColormap::QGLColormapData QGLColormap::shared_null = { Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0 };
97
98/*!
99 Construct a QGLColormap.
100*/
101QGLColormap::QGLColormap()
102 : d(&shared_null)
103{
104 d->ref.ref();
105}
106
107
108/*!
109 Construct a shallow copy of \a map.
110*/
111QGLColormap::QGLColormap(const QGLColormap &map)
112 : d(map.d)
113{
114 d->ref.ref();
115}
116
117/*!
118 Dereferences the QGLColormap and deletes it if this was the last
119 reference to it.
120*/
121QGLColormap::~QGLColormap()
122{
123 if (!d->ref.deref())
124 cleanup(d);
125}
126
127void QGLColormap::cleanup(QGLColormap::QGLColormapData *x)
128{
129 delete x->cells;
130 x->cells = 0;
131 delete x;
132}
133
134/*!
135 Assign a shallow copy of \a map to this QGLColormap.
136*/
137QGLColormap & QGLColormap::operator=(const QGLColormap &map)
138{
139 map.d->ref.ref();
140 if (!d->ref.deref())
141 cleanup(d);
142 d = map.d;
143 return *this;
144}
145
146/*!
147 \fn void QGLColormap::detach()
148 \internal
149
150 Detaches this QGLColormap from the shared block.
151*/
152
153void QGLColormap::detach_helper()
154{
155 QGLColormapData *x = new QGLColormapData;
156 x->ref.storeRelaxed(1);
157 x->cmapHandle = 0;
158 x->cells = 0;
159 if (d->cells) {
160 x->cells = new QVector<QRgb>(256);
161 *x->cells = *d->cells;
162 }
163 if (!d->ref.deref())
164 cleanup(d);
165 d = x;
166}
167
168/*!
169 Set cell at index \a idx in the colormap to color \a color.
170*/
171void QGLColormap::setEntry(int idx, QRgb color)
172{
173 detach();
174 if (!d->cells)
175 d->cells = new QVector<QRgb>(256);
176 d->cells->replace(idx, color);
177}
178
179/*!
180 Set an array of cells in this colormap. \a count is the number of
181 colors that should be set, \a colors is the array of colors, and
182 \a base is the starting index. The first element in \a colors
183 is set at \a base in the colormap.
184*/
185void QGLColormap::setEntries(int count, const QRgb *colors, int base)
186{
187 detach();
188 if (!d->cells)
189 d->cells = new QVector<QRgb>(256);
190
191 Q_ASSERT_X(colors && base >= 0 && (base + count) <= d->cells->size(), "QGLColormap::setEntries",
192 "preconditions not met");
193 for (int i = 0; i < count; ++i)
194 setEntry(base + i, colors[i]);
195}
196
197/*!
198 Returns the QRgb value in the colorcell with index \a idx.
199*/
200QRgb QGLColormap::entryRgb(int idx) const
201{
202 if (d == &shared_null || !d->cells)
203 return 0;
204 else
205 return d->cells->at(idx);
206}
207
208/*!
209 \overload
210
211 Set the cell with index \a idx in the colormap to color \a color.
212*/
213void QGLColormap::setEntry(int idx, const QColor &color)
214{
215 setEntry(idx, color.rgb());
216}
217
218/*!
219 Returns the QRgb value in the colorcell with index \a idx.
220*/
221QColor QGLColormap::entryColor(int idx) const
222{
223 if (d == &shared_null || !d->cells)
224 return QColor();
225 else
226 return QColor(d->cells->at(idx));
227}
228
229/*!
230 Returns \c true if the colormap is empty or it is not in use
231 by a QGLWidget; otherwise returns \c false.
232
233 A colormap with no color values set is considered to be empty.
234 For historical reasons, a colormap that has color values set
235 but which is not in use by a QGLWidget is also considered empty.
236
237 Compare size() with zero to determine if the colormap is empty
238 regardless of whether it is in use by a QGLWidget or not.
239
240 \sa size()
241*/
242bool QGLColormap::isEmpty() const
243{
244 return d == &shared_null || d->cells == 0 || d->cells->size() == 0 || d->cmapHandle == 0;
245}
246
247
248/*!
249 Returns the number of colorcells in the colormap.
250*/
251int QGLColormap::size() const
252{
253 return d->cells ? d->cells->size() : 0;
254}
255
256/*!
257 Returns the index of the color \a color. If \a color is not in the
258 map, -1 is returned.
259*/
260int QGLColormap::find(QRgb color) const
261{
262 if (d->cells)
263 return d->cells->indexOf(color);
264 return -1;
265}
266
267/*!
268 Returns the index of the color that is the closest match to color
269 \a color.
270*/
271int QGLColormap::findNearest(QRgb color) const
272{
273 int idx = find(color);
274 if (idx >= 0)
275 return idx;
276 int mapSize = size();
277 int mindist = 200000;
278 int r = qRed(color);
279 int g = qGreen(color);
280 int b = qBlue(color);
281 int rx, gx, bx, dist;
282 for (int i = 0; i < mapSize; ++i) {
283 QRgb ci = d->cells->at(i);
284 rx = r - qRed(ci);
285 gx = g - qGreen(ci);
286 bx = b - qBlue(ci);
287 dist = rx * rx + gx * gx + bx * bx; // calculate distance
288 if (dist < mindist) { // minimal?
289 mindist = dist;
290 idx = i;
291 }
292 }
293 return idx;
294}
295
296QT_END_NAMESPACE
297