source: trunk/COULEURS/getcolor.pro @ 2

Last change on this file since 2 was 2, checked in by opalod, 22 years ago

Initial revision

  • 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   ; 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
194ON_ERROR, 1
195
196IF N_ELEMENTS(number) NE 3 THEN $
197   MESSAGE, 'Augument must be a three-element vector.'
198
199IF MAX(number) GT 255 OR MIN(number) LT 0 THEN $
200   MESSAGE, 'Argument values must be in range of 0-255'
201
202base16 = [[1L, 16L], [256L, 4096L], [65536L, 1048576L]]
203
204num24bit = 0L
205
206FOR j=0,2 DO num24bit = num24bit + ((number(j) MOD 16) * base16(0,j)) + $
207   (Fix(number(j)/16) * base16(1,j))
208
209RETURN, num24bit
210END ; ************************  of COLOR24  ******************************
211
212
213
214FUNCTION GETCOLOR, thisColor, index, TRUE=truecolor, $
215   NAMES=colornames, LOAD=load, START=start
216
217   ; Set up the color vectors.
218
219names  = ['Black', 'Magenta', 'Cyan', 'Yellow', 'Green']
220rvalue = [  0,        255,       0,      255,       0  ]
221gvalue = [  0,          0,     255,      255,     255  ]
222bvalue = [  0,        255,     255,        0,       0  ]
223names  = [names,  'Red', 'Blue', 'Navy', 'Gold', 'Pink']
224rvalue = [rvalue,  255,     0,      0,    255,    255  ]
225gvalue = [gvalue,    0,     0,      0,    187,    127  ]
226bvalue = [bvalue,    0,   255,    115,      0,    127  ]
227names  = [names,  'Aqua', 'Orchid', 'Gray', 'Sky', 'Beige', 'White']
228rvalue = [rvalue,   112,     219,     127,    0,     255,     255  ]
229gvalue = [gvalue,   219,     112,     127,  163,     171,     255  ]
230bvalue = [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
237ON_Error, 1
238np = N_Params()
239IF Keyword_Set(start) EQ 0 THEN start = !D.TABLE_SIZE - 17
240
241   ; User ask for the color names?
242
243IF Keyword_Set(colornames) THEN RETURN, names ELSE names = StrUpCase(names)
244
245   ; If no positional parameter, return all colors.
246
247IF 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
305ENDIF
306
307   ; Check synonyms of colors.
308
309IF StrUpCase(thisColor) EQ 'GREY' THEN thisColor = 'GRAY'
310IF StrUpCase(thisColor) EQ 'CHARCOAL' THEN thisColor = 'GRAY'
311IF StrUpCase(thisColor) EQ 'AQUAMARINE' THEN thisColor = 'AQUA'
312IF StrUpCase(thisColor) EQ 'SKYBLUE' THEN thisColor = 'SKY'
313
314   ; Make sure the parameter is an uppercase string.
315
316varInfo = SIZE(thisColor)
317IF varInfo(varInfo(0) + 1) NE 7 THEN $
318   MESSAGE, 'The color name must be a string.'
319thisColor = STRUPCASE(thisColor)
320
321   ; Get the color triple for this color.
322
323colorIndex = 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
328IF colorIndex(0) LT 0 THEN BEGIN
329   MESSAGE, "Can't find color. Returning YELLOW.", /INFORMATIONAL
330   colorIndex = 3
331ENDIF
332
333   ; Get the color triple.
334
335r = rvalue(colorIndex)
336g = gvalue(colorIndex)
337b = bvalue(colorIndex)
338returnColor = REFORM([r, g, b], 1, 3)
339
340   ; Did the user want a 24-bit value? If so, call COLOR24.
341
342IF KEYWORD_SET(trueColor) THEN BEGIN
343   returnColor = COLOR24(returnColor)
344   RETURN, returnColor
345ENDIF
346
347   ; If color decomposition is ON, return 24-bit value.
348
349IF 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
367ENDIF
368
369   ; Did the user specify a color index? If so, load it.
370
371IF N_Elements(index) NE 0 THEN BEGIN
372   index = 0 > index < (!D.Table_Size-1)
373   TVLCT, returnColor, index
374   returnColor = index
375ENDIF
376
377RETURN, returnColor
378END
Note: See TracBrowser for help on using the repository browser.