1 | ;+ |
---|
2 | ; NAME: |
---|
3 | ; GETCOLOR |
---|
4 | ; |
---|
5 | ; PURPOSE: |
---|
6 | ; The original purpose of this function was to enable the |
---|
7 | ; user to specify one of the 16 colors supported by the |
---|
8 | ; McIDAS color map by name. Over time, however, the function |
---|
9 | ; has become a general purpose function for handling and |
---|
10 | ; supporting drawing colors in a device-independent way. |
---|
11 | ; In particular, I have been looking for ways to write color |
---|
12 | ; handling code that will work transparently on both 8-bit and |
---|
13 | ; 24-bit machines. On 24-bit machines, the code should work the |
---|
14 | ; same where color decomposition is turned on or off. |
---|
15 | ; |
---|
16 | ; (The 16 supported colors in GETCOLOR come from the McIDAS color |
---|
17 | ; table offered on the IDL newsgroup by Liam Gumley.) |
---|
18 | ; |
---|
19 | ; CATEGORY: |
---|
20 | ; Graphics, Color Specification. |
---|
21 | ; |
---|
22 | ; CALLING SEQUENCE: |
---|
23 | ; result = GETCOLOR(color) |
---|
24 | ; |
---|
25 | ; OPTIONAL INPUT PARAMETERS: |
---|
26 | ; COLOR: A string with the "name" of the color. Valid names are: |
---|
27 | ; black |
---|
28 | ; magenta |
---|
29 | ; cyan |
---|
30 | ; yellow |
---|
31 | ; green |
---|
32 | ; red |
---|
33 | ; blue |
---|
34 | ; navy |
---|
35 | ; gold |
---|
36 | ; pink |
---|
37 | ; aqua |
---|
38 | ; orchid |
---|
39 | ; gray |
---|
40 | ; sky |
---|
41 | ; beige |
---|
42 | ; white |
---|
43 | ; |
---|
44 | ; The color YELLOW is returned if the color name can't be resolved. |
---|
45 | ; Case is unimportant. |
---|
46 | ; |
---|
47 | ; If the function is called with just this single input parameter, |
---|
48 | ; the return value is either a 1-by-3 array containing the RGB values of |
---|
49 | ; that particular color, or a 24-bit integer that can be "decomposed" into |
---|
50 | ; that particular color, depending upon the state of the TRUE keyword and |
---|
51 | ; upon whether color decomposition is turned on or off. The state of color |
---|
52 | ; decomposition can ONLY be determined if the program is being run in |
---|
53 | ; IDL 5.2 or higher. |
---|
54 | ; |
---|
55 | ; INDEX: The color table index where the specified color should be loaded. |
---|
56 | ; If this parameter is passed, then the return value of the function is the |
---|
57 | ; index number and not the color triple. (If color decomposition is turned |
---|
58 | ; on AND the user specifies an index parameter, the color is loaded in the |
---|
59 | ; color table at the proper index, but a 24-bit value is returned to the |
---|
60 | ; user in IDL 5.2 and higher.) |
---|
61 | ; |
---|
62 | ; If no positional parameter is present, then the return value is either a 16-by-3 |
---|
63 | ; byte array containing the RGB values of all 16 colors or it is a 16-element |
---|
64 | ; long integer array containing color values that can be decomposed into colors. |
---|
65 | ; The 16-by-3 array is appropriate for loading color tables with the TVLCT command: |
---|
66 | ; |
---|
67 | ; Device, Decomposed=0 |
---|
68 | ; colors = GetColor() |
---|
69 | ; TVLCT, colors, 100 |
---|
70 | ; |
---|
71 | ; |
---|
72 | ; INPUT KEYWORD PARAMETERS: |
---|
73 | ; |
---|
74 | ; NAMES: If this keyword is set, the return value of the function is |
---|
75 | ; a 16-element string array containing the names of the colors. |
---|
76 | ; These names would be appropriate, for example, in building |
---|
77 | ; a list widget with the names of the colors. If the NAMES |
---|
78 | ; keyword is set, the COLOR and INDEX parameters are ignored. |
---|
79 | ; |
---|
80 | ; listID = Widget_List(baseID, Value=GetColor(/Names), YSize=16) |
---|
81 | ; |
---|
82 | ; LOAD: If this keyword is set, all 16 colors are automatically loaded |
---|
83 | ; starting at the color index specified by the START keyword. |
---|
84 | ; Note that setting this keyword means that the return value of the |
---|
85 | ; function will be a structure, with each field of the structure |
---|
86 | ; corresponding to a color name. The value of each field will be |
---|
87 | ; an index number (set by the START keyword) corresponding to the |
---|
88 | ; associated color, or a 24-bit long integer value that creates the |
---|
89 | ; color on a true-color device. What you have as the field values is |
---|
90 | ; determined by the TRUE keyword or whether color decomposition is on |
---|
91 | ; or off in the absense of the TRUE keyword. It will either be a 1-by-3 |
---|
92 | ; byte array or a long integer value. |
---|
93 | ; |
---|
94 | ; START: The starting color index number if the LOAD keyword is set. This keyword |
---|
95 | ; value is ignored unless the LOAD keyword is also set. The keyword is also |
---|
96 | ; ignored if the TRUE keyword is set or if color decomposition in on in |
---|
97 | ; IDL 5.2 and higher. The default value for the START keyword is |
---|
98 | ; !D.TABLE_SIZE - 17. |
---|
99 | ; |
---|
100 | ; TRUE: If this keyword is set, the specified color triple is returned |
---|
101 | ; as a 24-bit integer equivalent. The lowest 8 bits correspond to |
---|
102 | ; the red value; the middle 8 bits to the green value; and the |
---|
103 | ; highest 8 bits correspond to the blue value. In IDL 5.2 and higher, |
---|
104 | ; if color decomposition is turned on, it is as though this keyword |
---|
105 | ; were set. |
---|
106 | ; |
---|
107 | ; COMMON BLOCKS: |
---|
108 | ; None. |
---|
109 | ; |
---|
110 | ; SIDE EFFECTS: |
---|
111 | ; None. |
---|
112 | ; |
---|
113 | ; RESTRICTIONS: |
---|
114 | ; The TRUE keyword causes the START keyword to be ignored. |
---|
115 | ; The NAMES keyword causes the COLOR, INDEX, START, and TRUE parameters to be ignored. |
---|
116 | ; The COLOR parameter is ignored if the LOAD keyword is used. |
---|
117 | ; On systems where it is possible to tell the state of color decomposition |
---|
118 | ; (i.e., IDL 5.2 and higher), a 24-bit value (or values) is automatically |
---|
119 | ; returned if color decomposition is ON. |
---|
120 | ; |
---|
121 | ; EXAMPLE: |
---|
122 | ; To load a yellow color in color index 100 and plot in yellow, type: |
---|
123 | ; |
---|
124 | ; yellow = GETCOLOR('yellow', 100) |
---|
125 | ; PLOT, data, COLOR=yellow |
---|
126 | ; |
---|
127 | ; or, |
---|
128 | ; |
---|
129 | ; PLOT, data, COLOR=GETCOLOR('yellow', 100) |
---|
130 | ; |
---|
131 | ; To do the same thing on a 24-bit color system with decomposed color on, type: |
---|
132 | ; |
---|
133 | ; PLOT, data, COLOR=GETCOLOR('yellow', /TRUE) |
---|
134 | ; |
---|
135 | ; or in IDL 5.2 and higher, |
---|
136 | ; |
---|
137 | ; DEVICE, Decomposed=1 |
---|
138 | ; PLOT, data, COLOR=GETCOLOR('yellow') |
---|
139 | ; |
---|
140 | ; To load all 16 colors into the current color table, starting at |
---|
141 | ; color index 200, type: |
---|
142 | ; |
---|
143 | ; TVLCT, GETCOLOR(), 200 |
---|
144 | ; |
---|
145 | ; To add the color names to a list widget: |
---|
146 | ; |
---|
147 | ; listID = Widget_List(baseID, Value=GetColor(/Names), YSize=16) |
---|
148 | ; |
---|
149 | ; To load all 16 colors and have the color indices returned in a structure: |
---|
150 | ; |
---|
151 | ; DEVICE, Decomposed=0 |
---|
152 | ; colors = GetColor(/Load, Start=1) |
---|
153 | ; HELP, colors, /Structure |
---|
154 | ; PLOT, data, COLOR=colors.yellow |
---|
155 | ; |
---|
156 | ; To get the direct color values as 24-bit integers in color structure fields: |
---|
157 | ; |
---|
158 | ; DEVICE, Decomposed=1 |
---|
159 | ; colors = GetColor(/Load) |
---|
160 | ; PLOT, data, COLOR=colors.yellow |
---|
161 | ; |
---|
162 | ; Note that the START keyword value is ignored if on a 24-bit device, |
---|
163 | ; so it is possible to write completely device-independent code by |
---|
164 | ; writing code like this: |
---|
165 | ; |
---|
166 | ; colors = GetColor(/Load) |
---|
167 | ; PLOT, data, Color=colors.yellow |
---|
168 | ; |
---|
169 | ; MODIFICATION HISTORY: |
---|
170 | ; Written by: David Fanning, 10 February 96. |
---|
171 | ; Fixed a bug in which N_ELEMENTS was spelled wrong. 7 Dec 96. DWF |
---|
172 | ; Added the McIDAS colors to the program. 24 Feb 99. DWF |
---|
173 | ; Added the INDEX parameter to the program 8 Mar 99. DWF |
---|
174 | ; Added the NAMES keyword at insistence of Martin Schultz. 10 Mar 99. DWF |
---|
175 | ; Reorderd the colors so black is first and white is last. 7 June 99. DWF |
---|
176 | ; Added automatic recognition of DECOMPOSED=1 state. 7 June 99. DWF |
---|
177 | ; Added LOAD AND START keywords. 7 June 99. DWF. |
---|
178 | ;- |
---|
179 | |
---|
180 | |
---|
181 | |
---|
182 | FUNCTION COLOR24, number |
---|
183 | |
---|
184 | ; This FUNCTION accepts a [red, green, blue] triple that |
---|
185 | ; describes a particular color and returns a 24-bit long |
---|
186 | ; integer that is equivalent to that color. The color is |
---|
187 | ; described in terms of a hexidecimal number (e.g., FF206A) |
---|
188 | ; where the left two digits represent the blue color, the |
---|
189 | ; middle two digits represent the green color, and the right |
---|
190 | ; two digits represent the red color. |
---|
191 | ; |
---|
192 | ; The triple can be either a row or column vector of 3 elements. |
---|
193 | |
---|
194 | ON_ERROR, 1 |
---|
195 | |
---|
196 | IF N_ELEMENTS(number) NE 3 THEN $ |
---|
197 | MESSAGE, 'Augument must be a three-element vector.' |
---|
198 | |
---|
199 | IF MAX(number) GT 255 OR MIN(number) LT 0 THEN $ |
---|
200 | MESSAGE, 'Argument values must be in range of 0-255' |
---|
201 | |
---|
202 | base16 = [[1L, 16L], [256L, 4096L], [65536L, 1048576L]] |
---|
203 | |
---|
204 | num24bit = 0L |
---|
205 | |
---|
206 | FOR j=0,2 DO num24bit = num24bit + ((number(j) MOD 16) * base16(0,j)) + $ |
---|
207 | (Fix(number(j)/16) * base16(1,j)) |
---|
208 | |
---|
209 | RETURN, num24bit |
---|
210 | END ; ************************ of COLOR24 ****************************** |
---|
211 | |
---|
212 | |
---|
213 | |
---|
214 | FUNCTION GETCOLOR, thisColor, index, TRUE=truecolor, $ |
---|
215 | NAMES=colornames, LOAD=load, START=start |
---|
216 | |
---|
217 | ; Set up the color vectors. |
---|
218 | |
---|
219 | names = ['Black', 'Magenta', 'Cyan', 'Yellow', 'Green'] |
---|
220 | rvalue = [ 0, 255, 0, 255, 0 ] |
---|
221 | gvalue = [ 0, 0, 255, 255, 255 ] |
---|
222 | bvalue = [ 0, 255, 255, 0, 0 ] |
---|
223 | names = [names, 'Red', 'Blue', 'Navy', 'Gold', 'Pink'] |
---|
224 | rvalue = [rvalue, 255, 0, 0, 255, 255 ] |
---|
225 | gvalue = [gvalue, 0, 0, 0, 187, 127 ] |
---|
226 | bvalue = [bvalue, 0, 255, 115, 0, 127 ] |
---|
227 | names = [names, 'Aqua', 'Orchid', 'Gray', 'Sky', 'Beige', 'White'] |
---|
228 | rvalue = [rvalue, 112, 219, 127, 0, 255, 255 ] |
---|
229 | gvalue = [gvalue, 219, 112, 127, 163, 171, 255 ] |
---|
230 | bvalue = [bvalue, 147, 219, 127, 255, 127, 255 ] |
---|
231 | |
---|
232 | ; Did the user ask for a specific color? If not, return |
---|
233 | ; all the colors. If the user asked for a specific color, |
---|
234 | ; find out if a 24-bit value is required. Return to main |
---|
235 | ; IDL level if an error occurs. |
---|
236 | |
---|
237 | ON_Error, 1 |
---|
238 | np = N_Params() |
---|
239 | IF Keyword_Set(start) EQ 0 THEN start = !D.TABLE_SIZE - 17 |
---|
240 | |
---|
241 | ; User ask for the color names? |
---|
242 | |
---|
243 | IF Keyword_Set(colornames) THEN RETURN, names ELSE names = StrUpCase(names) |
---|
244 | |
---|
245 | ; If no positional parameter, return all colors. |
---|
246 | |
---|
247 | IF np EQ 0 THEN BEGIN |
---|
248 | |
---|
249 | ; Did the user want a 24-bit value? If so, call COLOR24. |
---|
250 | |
---|
251 | IF Keyword_Set(trueColor) THEN BEGIN |
---|
252 | returnColor = LonArr(16) |
---|
253 | FOR j=0,15 DO returnColor[j] = Color24([rvalue[j], gvalue[j], bvalue[j]]) |
---|
254 | |
---|
255 | ; If LOAD keyword set, return a color structure. |
---|
256 | |
---|
257 | IF Keyword_Set(load) THEN BEGIN |
---|
258 | returnValue = Create_Struct('black', returnColor[0]) |
---|
259 | FOR j=1,15 DO returnValue = Create_Struct(returnValue, names[j], returnColor[j]) |
---|
260 | returnColor = returnValue |
---|
261 | ENDIF |
---|
262 | |
---|
263 | RETURN, returnColor |
---|
264 | ENDIF |
---|
265 | |
---|
266 | ; If color decomposition is ON, return 24-bit values. |
---|
267 | |
---|
268 | IF Float(!Version.Release) GE 5.2 THEN BEGIN |
---|
269 | IF (!D.Name EQ 'X' OR !D.Name EQ 'WIN' OR !D.Name EQ 'MAC') THEN BEGIN |
---|
270 | Device, Get_Decomposed=decomposedState |
---|
271 | ENDIF ELSE decomposedState = 0 |
---|
272 | IF decomposedState EQ 1 THEN BEGIN |
---|
273 | returnColor = LonArr(16) |
---|
274 | FOR j=0,15 DO returnColor[j] = Color24([rvalue[j], gvalue[j], bvalue[j]]) |
---|
275 | IF Keyword_Set(load) THEN BEGIN |
---|
276 | returnValue = Create_Struct('black', returnColor[0]) |
---|
277 | FOR j=1,15 DO returnValue = Create_Struct(returnValue, names[j], returnColor[j]) |
---|
278 | RETURN, returnValue |
---|
279 | ENDIF |
---|
280 | RETURN, returnColor |
---|
281 | ENDIF |
---|
282 | |
---|
283 | IF Keyword_Set(load) THEN BEGIN |
---|
284 | TVLCT, Reform([rvalue, gvalue, bvalue], 16, 3), start |
---|
285 | returnValue = Create_Struct('black', start) |
---|
286 | FOR j=1,15 DO returnValue = Create_Struct(returnValue, names[j], start+j) |
---|
287 | RETURN, returnValue |
---|
288 | ENDIF |
---|
289 | |
---|
290 | returnColor = REFORM([rvalue, gvalue, bvalue], 16, 3) |
---|
291 | RETURN, returnColor |
---|
292 | |
---|
293 | ENDIF |
---|
294 | |
---|
295 | IF Keyword_Set(load) THEN BEGIN |
---|
296 | TVLCT, Reform([rvalue, gvalue, bvalue], 16, 3), start |
---|
297 | returnValue = Create_Struct('black', start) |
---|
298 | FOR j=1,15 DO returnValue = Create_Struct(returnValue, names[j], start+j) |
---|
299 | RETURN, returnValue |
---|
300 | ENDIF |
---|
301 | |
---|
302 | returnColor = REFORM([rvalue, gvalue, bvalue], 16, 3) |
---|
303 | RETURN, returnColor |
---|
304 | |
---|
305 | ENDIF |
---|
306 | |
---|
307 | ; Check synonyms of colors. |
---|
308 | |
---|
309 | IF StrUpCase(thisColor) EQ 'GREY' THEN thisColor = 'GRAY' |
---|
310 | IF StrUpCase(thisColor) EQ 'CHARCOAL' THEN thisColor = 'GRAY' |
---|
311 | IF StrUpCase(thisColor) EQ 'AQUAMARINE' THEN thisColor = 'AQUA' |
---|
312 | IF StrUpCase(thisColor) EQ 'SKYBLUE' THEN thisColor = 'SKY' |
---|
313 | |
---|
314 | ; Make sure the parameter is an uppercase string. |
---|
315 | |
---|
316 | varInfo = SIZE(thisColor) |
---|
317 | IF varInfo(varInfo(0) + 1) NE 7 THEN $ |
---|
318 | MESSAGE, 'The color name must be a string.' |
---|
319 | thisColor = STRUPCASE(thisColor) |
---|
320 | |
---|
321 | ; Get the color triple for this color. |
---|
322 | |
---|
323 | colorIndex = WHERE(names EQ thisColor) |
---|
324 | |
---|
325 | ; If you can't find it. Issue an infomational message, |
---|
326 | ; set the index to a YELLOW color, and continue. |
---|
327 | |
---|
328 | IF colorIndex(0) LT 0 THEN BEGIN |
---|
329 | MESSAGE, "Can't find color. Returning YELLOW.", /INFORMATIONAL |
---|
330 | colorIndex = 3 |
---|
331 | ENDIF |
---|
332 | |
---|
333 | ; Get the color triple. |
---|
334 | |
---|
335 | r = rvalue(colorIndex) |
---|
336 | g = gvalue(colorIndex) |
---|
337 | b = bvalue(colorIndex) |
---|
338 | returnColor = REFORM([r, g, b], 1, 3) |
---|
339 | |
---|
340 | ; Did the user want a 24-bit value? If so, call COLOR24. |
---|
341 | |
---|
342 | IF KEYWORD_SET(trueColor) THEN BEGIN |
---|
343 | returnColor = COLOR24(returnColor) |
---|
344 | RETURN, returnColor |
---|
345 | ENDIF |
---|
346 | |
---|
347 | ; If color decomposition is ON, return 24-bit value. |
---|
348 | |
---|
349 | IF Float(!Version.Release) GE 5.2 THEN BEGIN |
---|
350 | |
---|
351 | IF (!D.Name EQ 'X' OR !D.Name EQ 'WIN' OR !D.Name EQ 'MAC') THEN BEGIN |
---|
352 | Device, Get_Decomposed=decomposedState |
---|
353 | ENDIF ELSE decomposedState = 0 |
---|
354 | |
---|
355 | IF decomposedState EQ 1 THEN BEGIN |
---|
356 | |
---|
357 | ; Before you change return color, load index if requested. |
---|
358 | |
---|
359 | IF N_Elements(index) NE 0 THEN BEGIN |
---|
360 | index = 0 > index < (!D.Table_Size-1) |
---|
361 | TVLCT, returnColor, index |
---|
362 | ENDIF |
---|
363 | |
---|
364 | returnColor = COLOR24(returnColor) |
---|
365 | RETURN, returnColor |
---|
366 | ENDIF |
---|
367 | ENDIF |
---|
368 | |
---|
369 | ; Did the user specify a color index? If so, load it. |
---|
370 | |
---|
371 | IF N_Elements(index) NE 0 THEN BEGIN |
---|
372 | index = 0 > index < (!D.Table_Size-1) |
---|
373 | TVLCT, returnColor, index |
---|
374 | returnColor = index |
---|
375 | ENDIF |
---|
376 | |
---|
377 | RETURN, returnColor |
---|
378 | END |
---|