source: trunk/SRC/ToBeReviewed/COULEURS/getcolor.pro @ 114

Last change on this file since 114 was 114, checked in by smasson, 18 years ago

new compilation options (compile_opt idl2, strictarrsubs) in each routine

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 13.5 KB
Line 
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
182FUNCTION COLOR24, number
183;
184  compile_opt idl2, strictarrsubs
185;
186
187   ; This FUNCTION accepts a [red, green, blue] triple that
188   ; describes a particular color and returns a 24-bit long
189   ; integer that is equivalent to that color. The color is
190   ; described in terms of a hexidecimal number (e.g., FF206A)
191   ; where the left two digits represent the blue color, the
192   ; middle two digits represent the green color, and the right
193   ; two digits represent the red color.
194   ;
195   ; The triple can be either a row or column vector of 3 elements.
196
197ON_ERROR, 1
198
199IF N_ELEMENTS(number) NE 3 THEN $
200   MESSAGE, 'Augument must be a three-element vector.'
201
202IF MAX(number) GT 255 OR MIN(number) LT 0 THEN $
203   MESSAGE, 'Argument values must be in range of 0-255'
204
205base16 = [[1L, 16L], [256L, 4096L], [65536L, 1048576L]]
206
207num24bit = 0L
208
209FOR j=0,2 DO num24bit = num24bit + ((number[j] MOD 16) * base16[0,j]) + $
210   (Fix(number[j]/16) * base16[1,j])
211
212RETURN, num24bit
213END ; ************************  of COLOR24  ******************************
214
215
216
217FUNCTION GETCOLOR, thisColor, index, TRUE=truecolor, $
218   NAMES=colornames, LOAD=load, START=start
219;
220  compile_opt idl2, strictarrsubs
221;
222
223   ; Set up the color vectors.
224
225names  = ['Black', 'Magenta', 'Cyan', 'Yellow', 'Green']
226rvalue = [  0,        255,       0,      255,       0  ]
227gvalue = [  0,          0,     255,      255,     255  ]
228bvalue = [  0,        255,     255,        0,       0  ]
229names  = [names,  'Red', 'Blue', 'Navy', 'Gold', 'Pink']
230rvalue = [rvalue,  255,     0,      0,    255,    255  ]
231gvalue = [gvalue,    0,     0,      0,    187,    127  ]
232bvalue = [bvalue,    0,   255,    115,      0,    127  ]
233names  = [names,  'Aqua', 'Orchid', 'Gray', 'Sky', 'Beige', 'White']
234rvalue = [rvalue,   112,     219,     127,    0,     255,     255  ]
235gvalue = [gvalue,   219,     112,     127,  163,     171,     255  ]
236bvalue = [bvalue,   147,     219,     127,  255,     127,     255  ]
237
238   ; Did the user ask for a specific color? If not, return
239   ; all the colors. If the user asked for a specific color,
240   ; find out if a 24-bit value is required. Return to main
241   ; IDL level if an error occurs.
242
243ON_Error, 1
244np = N_Params()
245IF Keyword_Set(start) EQ 0 THEN start = !D.TABLE_SIZE - 17
246
247   ; User ask for the color names?
248
249IF Keyword_Set(colornames) THEN RETURN, names ELSE names = StrUpCase(names)
250
251   ; If no positional parameter, return all colors.
252
253IF np EQ 0 THEN BEGIN
254
255   ; Did the user want a 24-bit value? If so, call COLOR24.
256
257   IF Keyword_Set(trueColor) THEN BEGIN
258      returnColor = LonArr(16)
259      FOR j=0,15 DO returnColor[j] = Color24([rvalue[j], gvalue[j], bvalue[j]])
260
261         ; If LOAD keyword set, return a color structure.
262
263      IF Keyword_Set(load) THEN BEGIN
264         returnValue = Create_Struct('black', returnColor[0])
265         FOR j=1,15 DO returnValue = Create_Struct(returnValue, names[j], returnColor[j])
266         returnColor = returnValue
267      ENDIF
268
269      RETURN, returnColor
270   ENDIF
271
272   ; If color decomposition is ON, return 24-bit values.
273
274   IF Float(!Version.Release) GE 5.2 THEN BEGIN
275      IF (!D.Name EQ 'X' OR !D.Name EQ 'WIN' OR !D.Name EQ 'MAC') THEN BEGIN
276         Device, Get_Decomposed=decomposedState
277      ENDIF ELSE decomposedState = 0
278      IF decomposedState EQ 1 THEN BEGIN
279         returnColor = LonArr(16)
280         FOR j=0,15 DO returnColor[j] = Color24([rvalue[j], gvalue[j], bvalue[j]])
281         IF Keyword_Set(load) THEN BEGIN
282            returnValue = Create_Struct('black', returnColor[0])
283            FOR j=1,15 DO returnValue = Create_Struct(returnValue, names[j], returnColor[j])
284            RETURN, returnValue
285         ENDIF
286         RETURN, returnColor
287      ENDIF
288
289      IF Keyword_Set(load) THEN BEGIN
290         TVLCT, Reform([rvalue, gvalue, bvalue], 16, 3), start
291         returnValue = Create_Struct('black', start)
292         FOR j=1,15 DO returnValue = Create_Struct(returnValue, names[j], start+j)
293         RETURN, returnValue
294      ENDIF
295
296      returnColor = REFORM([rvalue, gvalue, bvalue], 16, 3)
297      RETURN, returnColor
298
299   ENDIF
300
301   IF Keyword_Set(load) THEN BEGIN
302      TVLCT, Reform([rvalue, gvalue, bvalue], 16, 3), start
303      returnValue = Create_Struct('black', start)
304      FOR j=1,15 DO returnValue = Create_Struct(returnValue, names[j], start+j)
305      RETURN, returnValue
306   ENDIF
307
308   returnColor = REFORM([rvalue, gvalue, bvalue], 16, 3)
309   RETURN, returnColor
310
311ENDIF
312
313   ; Check synonyms of colors.
314
315IF StrUpCase(thisColor) EQ 'GREY' THEN thisColor = 'GRAY'
316IF StrUpCase(thisColor) EQ 'CHARCOAL' THEN thisColor = 'GRAY'
317IF StrUpCase(thisColor) EQ 'AQUAMARINE' THEN thisColor = 'AQUA'
318IF StrUpCase(thisColor) EQ 'SKYBLUE' THEN thisColor = 'SKY'
319
320   ; Make sure the parameter is an uppercase string.
321
322varInfo = SIZE(thisColor)
323IF varInfo[varInfo[0] + 1] NE 7 THEN $
324   MESSAGE, 'The color name must be a string.'
325thisColor = STRUPCASE(thisColor)
326
327   ; Get the color triple for this color.
328
329colorIndex = WHERE(names EQ thisColor)
330
331   ; If you can't find it. Issue an infomational message,
332   ; set the index to a YELLOW color, and continue.
333
334IF colorIndex[0] LT 0 THEN BEGIN
335   MESSAGE, "Can't find color. Returning YELLOW.", /INFORMATIONAL
336   colorIndex = 3
337ENDIF
338
339   ; Get the color triple.
340
341r = rvalue[colorIndex]
342g = gvalue[colorIndex]
343b = bvalue[colorIndex]
344returnColor = REFORM([r, g, b], 1, 3)
345
346   ; Did the user want a 24-bit value? If so, call COLOR24.
347
348IF KEYWORD_SET(trueColor) THEN BEGIN
349   returnColor = COLOR24(returnColor)
350   RETURN, returnColor
351ENDIF
352
353   ; If color decomposition is ON, return 24-bit value.
354
355IF Float(!Version.Release) GE 5.2 THEN BEGIN
356
357      IF (!D.Name EQ 'X' OR !D.Name EQ 'WIN' OR !D.Name EQ 'MAC') THEN BEGIN
358         Device, Get_Decomposed=decomposedState
359      ENDIF ELSE decomposedState = 0
360
361   IF decomposedState EQ 1 THEN BEGIN
362
363         ; Before you change return color, load index if requested.
364
365      IF N_Elements(index) NE 0 THEN BEGIN
366         index = 0 > index < (!D.Table_Size-1)
367         TVLCT, returnColor, index
368      ENDIF
369
370      returnColor = COLOR24(returnColor)
371      RETURN, returnColor
372   ENDIF
373ENDIF
374
375   ; Did the user specify a color index? If so, load it.
376
377IF N_Elements(index) NE 0 THEN BEGIN
378   index = 0 > index < (!D.Table_Size-1)
379   TVLCT, returnColor, index
380   returnColor = index
381ENDIF
382
383RETURN, returnColor
384END
Note: See TracBrowser for help on using the repository browser.