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