1
2 /*
3 A* -------------------------------------------------------------------
4 B* This file contains source code for the PyMOL computer program
5 C* copyright 1998-2000 by Warren Lyford Delano of DeLano Scientific.
6 D* -------------------------------------------------------------------
7 E* It is unlawful to modify or remove this copyright notice.
8 F* -------------------------------------------------------------------
9 G* Please see the accompanying LICENSE file for further information.
10 H* -------------------------------------------------------------------
11 I* Additional authors of this source file include:
12 -*
13 -*
14 -*
15 Z* -------------------------------------------------------------------
16 */
17 #include"os_python.h"
18 #include"os_predef.h"
19 #include"os_std.h"
20
21 #include"Base.h"
22 #include"OOMac.h"
23 #include"MemoryDebug.h"
24 #include"Ortho.h"
25 #include"Word.h"
26
27 #include"Color.h"
28 #include"PConv.h"
29 #include"ObjectGadgetRamp.h"
30 #include"Util.h"
31 #include"Executive.h"
32 #include"MyPNG.h"
33 #include"Scene.h"
34 #include"OVContext.h"
35 #include"OVreturns.h"
36
37 static int AutoColor[] = {
38 26, /* carbon */
39 5, /* cyan */
40 154, /* lightmagenta */
41 6, /* yellow */
42 9, /* salmon */
43 29, /* hydrogen */
44 11, /* slate */
45 13, /* orange */
46 10, /* lime */
47 5262, /* deepteal */
48 12, /* hotpink */
49 36, /* yelloworange */
50 5271, /* violetpurple */
51 124, /* grey70 */
52 17, /* marine */
53 18, /* olive */
54 5270, /* smudge */
55 20, /* teal */
56 5272, /* dirtyviolet */
57 52, /* wheat */
58 5258, /* deepsalmon */
59 5274, /* lightpink */
60 5257, /* aquamarine */
61 5256, /* paleyellow */
62 15, /* limegreen */
63 5277, /* skyblue */
64 5279, /* warmpink */
65 5276, /* limon */
66 53, /* violet */
67 5278, /* bluewhite */
68 5275, /* greencyan */
69 5269, /* sand */
70 22, /* forest */
71 5266, /* lightteal */
72 5280, /* darksalmon */
73 5267, /* splitpea */
74 5268, /* raspberry */
75 104, /* grey50 */
76 23, /* deepblue */
77 51, /* brown */
78 };
79
80 static int nAutoColor = 40;
81 static void lookup_color(CColor * I, const float *in, float *out, int big_endian);
82
ColorGetBkrdContColor(PyMOLGlobals * G,float * rgb,int invert_flag)83 void ColorGetBkrdContColor(PyMOLGlobals * G, float *rgb, int invert_flag)
84 {
85 const float *bkrd = ColorGet(G, SettingGet_color(G, NULL, NULL, cSetting_bg_rgb));
86
87 if(!invert_flag) {
88 if((bkrd[0] + bkrd[1] + bkrd[2]) > 0.5F) {
89 rgb[0] = 1.0F;
90 rgb[1] = 1.0F;
91 rgb[2] = 1.0F;
92 } else {
93 rgb[0] = 0.0F;
94 rgb[1] = 0.0F;
95 rgb[2] = 0.0F;
96 }
97 }
98
99 {
100 int a;
101 for(a = 0; a < 3; a++)
102 if(fabs(bkrd[a] - rgb[a]) < 0.5F) {
103 rgb[a] = 1.0F - rgb[a];
104 if(fabs(bkrd[a] - rgb[a]) < 0.5F) {
105 if(bkrd[a] > 0.5F)
106 rgb[a] = 0.0F;
107 else
108 rgb[a] = 1.0F;
109 }
110 }
111 }
112 }
113
ColorGet32BitWord(PyMOLGlobals * G,const float * rgba)114 unsigned int ColorGet32BitWord(PyMOLGlobals * G, const float *rgba)
115 {
116 CColor *I = G->Color;
117 unsigned int rc, gc, bc, ac;
118 unsigned int result;
119
120 rc = (int) (255 * rgba[0] + 0.49999F);
121 gc = (int) (255 * rgba[1] + 0.49999F);
122 bc = (int) (255 * rgba[2] + 0.49999F);
123 ac = (int) (255 * rgba[3] + 0.49999F);
124
125 if(rc > 255)
126 rc = 255;
127 if(bc > 255)
128 bc = 255;
129 if(gc > 255)
130 gc = 255;
131 if(ac > 255)
132 ac = 255;
133
134 if(I->BigEndian) {
135 result = (rc << 24) | (gc << 16) | (bc << 8) | ac;
136 } else {
137 result = (ac << 24) | (bc << 16) | (gc << 8) | rc;
138 }
139 return result;
140 }
141
ColorGetNext(PyMOLGlobals * G)142 int ColorGetNext(PyMOLGlobals * G)
143 {
144 int result;
145 int next;
146 next = SettingGetGlobal_i(G, cSetting_auto_color_next);
147
148 if(next >= nAutoColor)
149 next = 0;
150 result = AutoColor[next];
151 next++;
152 if(next >= nAutoColor)
153 next = 0;
154 SettingSetGlobal_i(G, cSetting_auto_color_next, next);
155 return (result);
156 }
157
ColorGetCurrent(PyMOLGlobals * G)158 int ColorGetCurrent(PyMOLGlobals * G)
159 {
160 int result;
161 int next;
162 next = SettingGetGlobal_i(G, cSetting_auto_color_next);
163 next--;
164 if(next < 0)
165 next = (nAutoColor - 1);
166 result = AutoColor[next];
167 return (result);
168 }
169
ColorCheckRamped(PyMOLGlobals * G,int index)170 int ColorCheckRamped(PyMOLGlobals * G, int index)
171 {
172 return (index <= (cColorExtCutoff));
173 }
174
ColorGetRamp(PyMOLGlobals * G,int index)175 ObjectGadgetRamp *ColorGetRamp(PyMOLGlobals * G, int index)
176 {
177 CColor *I = G->Color;
178 ObjectGadgetRamp *result = NULL;
179 if(index <= cColorExtCutoff) {
180 index = cColorExtCutoff - index;
181 if(index < I->NExt) {
182 if(!I->Ext[index].Ptr) {
183 if(I->Ext[index].Name) {
184 const char *name = I->Ext[index].Name;
185 I->Ext[index].Ptr = (void *) ExecutiveFindObjectByName(G, name);
186 }
187 }
188 if(I->Ext[index].Ptr)
189 result = (ObjectGadgetRamp *) I->Ext[index].Ptr;
190 }
191 }
192 return result;
193 }
194
ColorGetRamped(PyMOLGlobals * G,int index,const float * vertex,float * color,int state)195 int ColorGetRamped(PyMOLGlobals * G, int index, const float *vertex, float *color, int state)
196 {
197 CColor *I = G->Color;
198 int ok = false;
199 if(index <= cColorExtCutoff) {
200 index = cColorExtCutoff - index;
201 if(index < I->NExt) {
202 if(!I->Ext[index].Ptr) {
203 if(I->Ext[index].Name) {
204 const char *name = I->Ext[index].Name;
205 I->Ext[index].Ptr = (void *) ExecutiveFindObjectByName(G, name);
206 }
207 }
208 if(I->Ext[index].Ptr)
209 ok = ObjectGadgetRampInterVertex((ObjectGadgetRamp *) I->Ext[index].Ptr,
210 vertex, color, state);
211 }
212
213 }
214 if(!ok) {
215 color[0] = 1.0;
216 color[1] = 1.0;
217 color[2] = 1.0;
218 } else if(I->LUTActive) {
219 lookup_color(I, color, color, I->BigEndian);
220 }
221 return (ok);
222 }
223
224 /* Color::ColorGetCheckRamped -- This function gets a color as 3 floats from an index and writes it into
225 * the color argument. If the index is a ramp, then it uses the vertex and state arguments to lookup the
226 * color value in the ramp.
227 * NOTES: does not support index values cColorObject(-5) or cColorAtomic(-4) color since the object
228 * or atom color is not passed in.
229 *
230 * PARAMS
231 *
232 * index - color index value
233 * vertex - x/y/z used for ramp lookup (if color index is a ramp)
234 * color - output color array of 3 floats
235 * state - state lookup if ramp
236 *
237 * RETURN VALUE: returns whether the color index is dependent on a ramp.
238 *
239 */
ColorGetCheckRamped(PyMOLGlobals * G,int index,const float * vertex,float * color,int state)240 bool ColorGetCheckRamped(PyMOLGlobals * G, int index, const float *vertex, float *color, int state)
241 {
242 bool isRamped = false;
243 if(ColorCheckRamped(G, index)) {
244 ColorGetRamped(G, index, vertex, color, state);
245 isRamped = true;
246 } else {
247 copy3f(ColorGet(G, index), color);
248 }
249 return isRamped;
250 }
251
ColorFindExtByName(PyMOLGlobals * G,const char * name,int null_okay,int * best)252 static int ColorFindExtByName(PyMOLGlobals * G, const char *name, int null_okay, int *best)
253 {
254 CColor *I = G->Color;
255 int result = -1;
256 int wm;
257 int a;
258 int mybest;
259 if(!best)
260 best = &mybest;
261 *best = 0;
262 for(a = 0; a < I->NExt; a++) {
263 const char *color_name = I->Ext[a].Name;
264 if(color_name) {
265 wm = WordMatch(G, name, color_name, true);
266 if(wm < 0) {
267 if(null_okay || (I->Ext[a].Ptr)) {
268 result = a;
269 *best = 0;
270 break;
271 }
272 } else if((wm > 0) && ((*best) < wm)) {
273 if(null_okay || (I->Ext[a].Ptr)) {
274 result = a;
275 *best = wm;
276 }
277 }
278 }
279 }
280 return (result);
281 }
282
283 /**
284 * Map name to index (idx[name] = index)
285 *
286 * @return pointer to stored name string
287 */
reg_name(std::unordered_map<std::string,CColor::ColorIdx> & idx,int index,const char * name)288 static const char* reg_name(
289 std::unordered_map<std::string, CColor::ColorIdx>& idx, int index,
290 const char* name)
291 {
292 auto handle = idx.emplace(name, index);
293
294 if (!handle.second) {
295 handle.first->second = index;
296 }
297
298 return handle.first->first.c_str();
299 }
300
ColorRegisterExt(PyMOLGlobals * G,const char * name,void * ptr,int type)301 void ColorRegisterExt(PyMOLGlobals * G, const char *name, void *ptr, int type)
302 {
303 CColor *I = G->Color;
304 int a;
305
306 a = ColorFindExtByName(G, name, true, NULL);
307 if(a < 0) {
308 VLACheck(I->Ext, ExtRec, I->NExt);
309 a = I->NExt;
310 I->NExt++;
311 I->Ext[a].Name = reg_name(I->Idx, cColorExtCutoff - a, name);
312 }
313 if(a >= 0) {
314 I->Ext[a].Ptr = ptr;
315 I->Ext[a].Type = type;
316 }
317 }
318
ColorForgetExt(PyMOLGlobals * G,const char * name)319 void ColorForgetExt(PyMOLGlobals * G, const char *name)
320 {
321 CColor *I = G->Color;
322 int a;
323 a = ColorFindExtByName(G, name, true, NULL);
324
325 if(a >= 0) { /* currently leaks memory in I->Ext array -- TODO fix */
326 if(I->Ext[a].Name) {
327 I->Idx.erase(I->Ext[a].Name);
328 }
329 I->Ext[a].Name = 0;
330 I->Ext[a].Ptr = NULL;
331 }
332 }
333
ColorExtAsPyList(PyMOLGlobals * G)334 PyObject *ColorExtAsPyList(PyMOLGlobals * G)
335 {
336 CColor *I = G->Color;
337 PyObject *result, *list;
338 ExtRec *ext;
339 int a;
340
341 result = PyList_New(I->NExt);
342 ext = I->Ext;
343 for(a = 0; a < I->NExt; a++) {
344 list = PyList_New(2);
345 {
346 const char *name = ext->Name ? ext->Name : "";
347 PyList_SetItem(list, 0, PyString_FromString(name));
348 }
349 PyList_SetItem(list, 1, PyInt_FromLong(ext->Type));
350 PyList_SetItem(result, a, list);
351 ext++;
352 }
353 return (result);
354 }
355
356
357 /*========================================================================*/
ColorAsPyList(PyMOLGlobals * G)358 PyObject *ColorAsPyList(PyMOLGlobals * G)
359 {
360 CColor *I = G->Color;
361 PyObject *result, *list;
362 ColorRec *color;
363 int n_custom = 0;
364 int a, c;
365 color = I->Color;
366 for(a = 0; a < I->NColor; a++) {
367 if(color->Custom || color->LutColorFlag)
368 n_custom++;
369 color++;
370 }
371 result = PyList_New(n_custom);
372 c = 0;
373 color = I->Color;
374 for(a = 0; a < I->NColor; a++) {
375 if(color->Custom || color->LutColorFlag) {
376 list = PyList_New(7);
377 {
378 const char *name = color->Name;
379 PyList_SetItem(list, 0, PyString_FromString(name));
380 }
381 PyList_SetItem(list, 1, PyInt_FromLong(a));
382 PyList_SetItem(list, 2, PConvFloatArrayToPyList(color->Color, 3));
383 PyList_SetItem(list, 3, PyInt_FromLong((int) color->Custom));
384 PyList_SetItem(list, 4, PyInt_FromLong((int) color->LutColorFlag));
385 PyList_SetItem(list, 5, PConvFloatArrayToPyList(color->LutColor, 3));
386 PyList_SetItem(list, 6, PyInt_FromLong((int) color->Fixed));
387 PyList_SetItem(result, c, list);
388 c++;
389 }
390 color++;
391 }
392 return (result);
393 }
394
395 /*========================================================================*/
ColorConvertOldSessionIndex(PyMOLGlobals * G,int index)396 int ColorConvertOldSessionIndex(PyMOLGlobals * G, int index)
397 {
398 CColor *I = G->Color;
399 if(index > cColorExtCutoff) {
400 if(I->HaveOldSessionColors) {
401 ColorRec *col = I->Color + (I->NColor - 1);
402 int a;
403 for(a = I->NColor - 1; a >= 0; a--) {
404 if(index == col->old_session_index) {
405 index = a;
406 break;
407 }
408 col--;
409 }
410 }
411 } else if(I->HaveOldSessionExtColors) {
412 ExtRec *ext = I->Ext + (I->NExt - 1);
413 int a;
414 for(a = I->NExt - 1; a >= 0; a--) {
415 if(index == ext->old_session_index) {
416 index = cColorExtCutoff - a;
417 break;
418 }
419 ext--;
420 }
421 }
422 return index; /* failsafe */
423 }
424
ColorExtFromPyList(PyMOLGlobals * G,PyObject * list,int partial_restore)425 int ColorExtFromPyList(PyMOLGlobals * G, PyObject * list, int partial_restore)
426 {
427 int n_ext = 0;
428 int a;
429 int ok = true;
430 CColor *I = G->Color;
431 PyObject *rec;
432 ExtRec *ext;
433
434 if(partial_restore) {
435 ext = I->Ext;
436 for(a = 0; a < I->NExt; a++) {
437 ext->old_session_index = 0;
438 ext++;
439 }
440 I->HaveOldSessionExtColors = true;
441 } else {
442 I->HaveOldSessionExtColors = false;
443 }
444
445 if(ok)
446 ok = (list != NULL);
447 if(ok)
448 ok = PyList_Check(list);
449
450 /* TO SUPPORT BACKWARDS COMPATIBILITY...
451 Always check ll when adding new PyList_GetItem's */
452
453 if(ok) {
454 n_ext = PyList_Size(list);
455 if(partial_restore) {
456 VLACheck(I->Ext, ExtRec, n_ext + I->NExt);
457 ext = I->Ext + I->NExt;
458 } else {
459 VLACheck(I->Ext, ExtRec, n_ext);
460 ext = I->Ext;
461 }
462 for(a = 0; a < n_ext; a++) {
463 rec = PyList_GetItem(list, a);
464 if(ok)
465 ok = (rec != NULL);
466 if(ok)
467 ok = PyList_Check(rec);
468 if(ok) {
469 WordType name;
470 ok = PConvPyStrToStr(PyList_GetItem(rec, 0), name, sizeof(WordType));
471 ext->Name = reg_name(I->Idx, cColorExtCutoff - a, name);
472 }
473 if(ok)
474 ok = PConvPyIntToInt(PyList_GetItem(rec, 1), &ext->Type);
475 ext->old_session_index = cColorExtCutoff - a;
476 ext++;
477 }
478 if(ok)
479 I->NExt = (ext - I->Ext);
480
481 }
482 return (ok);
483 }
484
485
486 /*========================================================================*/
ColorFromPyList(PyMOLGlobals * G,PyObject * list,int partial_restore)487 int ColorFromPyList(PyMOLGlobals * G, PyObject * list, int partial_restore)
488 {
489 int n_custom = 0;
490 int a;
491 int index = 0, old_session_index = 0;
492 int ok = true;
493 int ll = 0;
494 CColor *I = G->Color;
495 PyObject *rec;
496 ColorRec *color = NULL;
497
498 if(partial_restore) {
499 color = I->Color;
500 for(a = 0; a < I->NColor; a++) {
501 color->old_session_index = 0;
502 color++;
503 }
504 }
505 I->HaveOldSessionColors = false;
506
507 if(ok)
508 ok = (list != NULL);
509 if(ok)
510 ok = PyList_Check(list);
511 if(ok) {
512 n_custom = PyList_Size(list);
513 for(a = 0; a < n_custom; a++) {
514 rec = PyList_GetItem(list, a);
515 if(ok)
516 ok = (rec != NULL);
517 if(ok)
518 ok = PyList_Check(rec);
519 if(ok)
520 ll = PyList_Size(rec);
521 /* TO SUPPORT BACKWARDS COMPATIBILITY...
522 Always check ll when adding new PyList_GetItem's */
523 if(ok)
524 ok = PConvPyIntToInt(PyList_GetItem(rec, 1), &index);
525 if(ok) {
526 old_session_index = index;
527 if(partial_restore) {
528 if(I->NColor > index) { /* conflicts with an existing color... */
529 I->HaveOldSessionColors = true;
530 index = I->NColor;
531 }
532 }
533 if(index >= I->NColor) {
534 VLACheck(I->Color, ColorRec, index); /* auto-zeros */
535 I->NColor = index + 1;
536 }
537 color = I->Color + index;
538 color->old_session_index = old_session_index;
539 if(ok) {
540 WordType name;
541 ok = PConvPyStrToStr(PyList_GetItem(rec, 0), name, sizeof(WordType));
542 color->Name = reg_name(I->Idx, index, name);
543 }
544 if(ok)
545 ok = PConvPyListToFloatArrayInPlace(PyList_GetItem(rec, 2), color->Color, 3);
546 if(PyList_Size(rec) >= 6) {
547 if(ok)
548 ok = PConvPyIntToChar(PyList_GetItem(rec, 3), &color->Custom);
549 if(ok)
550 ok = PConvPyIntToChar(PyList_GetItem(rec, 4), &color->LutColorFlag);
551 if(ok)
552 ok =
553 PConvPyListToFloatArrayInPlace(PyList_GetItem(rec, 5), color->LutColor, 3);
554 } else {
555 if(ok) {
556 color->Custom = true;
557 }
558 }
559 }
560 if(ok && (ll > 6)) {
561 if(ok)
562 ok = PConvPyIntToChar(PyList_GetItem(rec, 6), &color->Fixed);
563 } else if(ok && color) {
564 color->Fixed = false;
565 }
566 if(!ok)
567 break;
568 }
569 }
570 return (ok);
571 }
572
573 /*========================================================================*/
ColorDef(PyMOLGlobals * G,const char * name,const float * v,int mode,int quiet)574 void ColorDef(PyMOLGlobals * G, const char *name, const float *v, int mode, int quiet)
575 {
576 CColor *I = G->Color;
577 int color = -1;
578 int a;
579 int wm;
580
581 {
582 auto it = I->Idx.find(name);
583 if(it != I->Idx.end()){
584 color = it->second;
585 }
586 }
587
588 if(color < 0) {
589 for(a = 0; a < I->NColor; a++) {
590 auto* color_name = I->Color[a].Name;
591 if(color_name) {
592 wm = WordMatch(G, name, color_name, true);
593 if(wm < 0) {
594 color = a;
595 break;
596 }
597 }
598 }
599 }
600
601 if(color < 0) {
602 color = I->NColor;
603 VLACheck(I->Color, ColorRec, I->NColor);
604 I->NColor++;
605 I->Color[color].Name = reg_name(I->Idx, color, name);
606 }
607
608 I->Color[color].Color[0] = v[0];
609 I->Color[color].Color[1] = v[1];
610 I->Color[color].Color[2] = v[2];
611
612 switch (mode) {
613 case 1:
614 I->Color[color].Fixed = true;
615 break;
616 default:
617 I->Color[color].Fixed = false;
618 break;
619 }
620
621 I->Color[color].Custom = true;
622 ColorUpdateFromLut(G, color);
623
624 if(!quiet) {
625 PRINTFB(G, FB_Executive, FB_Actions)
626 " Color: \"%s\" defined as [ %3.3f, %3.3f, %3.3f ].\n", name, v[0], v[1], v[2]
627 ENDFB(G);
628
629 }
630
631 PRINTFD(G, FB_Color)
632 " Color: and assigned number %d.\n", color ENDFD;
633 }
634
635
636 /*========================================================================*/
ColorGetIndex(PyMOLGlobals * G,const char * name)637 int ColorGetIndex(PyMOLGlobals * G, const char *name)
638 {
639 CColor *I = G->Color;
640 int color = -1; /* default for unknown is white */
641 int ext_color;
642 int a;
643 int i;
644 int wm, best = 0;
645 int ext_best = 0;
646 int is_numeric = true;
647 int found = false;
648
649 {
650 const char *c;
651 c = name;
652 while(*c) {
653 if((((*c) < '0') || ((*c) > '9')) && ((*c) != '-')) {
654 is_numeric = false;
655 break;
656 }
657 c++;
658 }
659 }
660
661 if(is_numeric) {
662 if(sscanf(name, "%d", &i)) {
663 if((i < I->NColor) && (i >= 0))
664 return (i);
665 else if(i == cColorNewAuto)
666 return (ColorGetNext(G));
667 else if(i == cColorCurAuto)
668 return (ColorGetCurrent(G));
669 else if(i == cColorAtomic)
670 return cColorAtomic;
671 else if(i == cColorObject)
672 return cColorObject;
673 else if(i == cColorFront)
674 return cColorFront;
675 else if(i == cColorBack)
676 return cColorBack;
677 else if(i == -1)
678 return -1;
679 if (i & cColor_TRGB_Bits)
680 return i;
681 }
682 }
683 if((name[0] == '0') && (name[1] == 'x')) { /* explicit hex RGB 0x000000 */
684 int tmp_color;
685 if(sscanf(name + 2, "%x", (unsigned int *) &tmp_color) == 1) {
686 tmp_color = (cColor_TRGB_Bits |
687 (tmp_color & 0x00FFFFFF) | ((tmp_color >> 2) & 0x3F000000));
688 return tmp_color;
689 }
690 }
691 if(WordMatch(G, name, "default", true))
692 return (-1);
693 if(WordMatch(G, name, "auto", true))
694 return (ColorGetNext(G));
695 if(WordMatch(G, name, "current", true))
696 return (ColorGetCurrent(G));
697 if(WordMatch(G, name, "atomic", true))
698 return (cColorAtomic);
699 if(WordMatch(G, name, "object", true))
700 return (cColorObject);
701 if(WordMatch(G, name, "front", true))
702 return (cColorFront);
703 if(WordMatch(G, name, "back", true))
704 return (cColorBack);
705
706 { /* search for a perfect match (fast!) */
707 auto it = I->Idx.find(name);
708 if(it != I->Idx.end()){
709 found = true;
710 color = it->second;
711 }
712 }
713 if(!found) { /* search for an imperfect match */
714 for(a = 0; a < I->NColor; a++) {
715 auto* color_name = I->Color[a].Name;
716 if(color_name) {
717 wm = WordMatch(G, name, color_name, true);
718 if(wm < 0) {
719 color = a;
720 best = 0;
721 break;
722 } else if((wm > 0) && (best < wm)) {
723 color = a;
724 best = wm;
725 }
726 }
727 }
728 if(best || (color < 0)) {
729 ext_color = ColorFindExtByName(G, name, true, &ext_best);
730 if(ext_color >= 0) {
731 ext_color = cColorExtCutoff - ext_color; /* indicates external */
732 if((!ext_best) || (ext_best > best)) /* perfect or better match? */
733 color = ext_color;
734 }
735 }
736 }
737 return (color);
738 }
739
740
741 /*========================================================================*/
ColorGetNamed(PyMOLGlobals * G,const char * name)742 const float *ColorGetNamed(PyMOLGlobals * G, const char *name)
743 {
744 return (ColorGet(G, ColorGetIndex(G, name)));
745 }
746
747
748 /*========================================================================*/
ColorGetName(PyMOLGlobals * G,int index)749 const char *ColorGetName(PyMOLGlobals * G, int index)
750 {
751 CColor *I = G->Color;
752 if((index >= 0) && (index < I->NColor)) {
753 return I->Color[index].Name;
754 } else if((index & cColor_TRGB_Mask) == cColor_TRGB_Bits) {
755 index = (((index & 0xFFFFFF) | ((index << 2) & 0xFC000000) | /* convert 6 bits of trans into 8 */
756 ((index >> 4) & 0x03000000)));
757 if(index & 0xFF000000) /* if transparent */
758 sprintf(I->RGBName, "0x%08x", index);
759 else /* else */
760 sprintf(I->RGBName, "0x%06x", index);
761 return I->RGBName;
762 } else if(index <= cColorExtCutoff) {
763 int a = cColorExtCutoff - index;
764 if(a < I->NExt) {
765 return I->Ext[a].Name;
766 } else
767 return NULL;
768 }
769 return (NULL);
770 }
771
772
773 /*========================================================================*/
ColorGetStatus(PyMOLGlobals * G,int index)774 int ColorGetStatus(PyMOLGlobals * G, int index)
775 {
776 CColor *I = G->Color;
777 /* return 0 if color is invalid, -1 if hidden;
778 1 otherwise */
779 int result = 0;
780 if((index >= 0) && (index < I->NColor)) {
781 auto* color_name = I->Color[index].Name;
782 if(color_name) {
783 const char* c = color_name;
784 result = 1;
785 while(*c) {
786 if(((*c) >= '0') && ((*c) <= '9')) {
787 result = -1;
788 break;
789 }
790 c++;
791 }
792 }
793 }
794 return (result);
795 }
796
797
798 /*========================================================================*/
ColorGetNColor(PyMOLGlobals * G)799 int ColorGetNColor(PyMOLGlobals * G)
800 {
801 CColor *I = G->Color;
802 return (I->NColor);
803 }
804
805
806 /*========================================================================*/
ColorFree(PyMOLGlobals * G)807 void ColorFree(PyMOLGlobals * G)
808 {
809 CColor *I = G->Color;
810 VLAFreeP(I->Color);
811 VLAFreeP(I->Ext);
812 DeleteP(I);
813 }
814
815
816 /*========================================================================*/
817
ColorReset(PyMOLGlobals * G)818 void ColorReset(PyMOLGlobals * G)
819 {
820
821 /* PyMOL core color names
822
823 1 1 1 white
824 .5 .5 .5 grey/gray
825 0 0 0 black
826
827 1 0 0 red
828 0 1 0 green
829 0 0 1 blue
830
831 1 1 0 yellow
832 1 0 1 magenta
833 0 1 1 cyan
834
835 1 1 .5 paleyellow .
836 1 .5 1 violet .
837 .5 1 1 aquamarine .
838
839 1 .5 .5 deepsalmon .
840 .5 1 .5 palegreen .
841 .5 .5 1 slate .
842
843 .75 .75 0 olive .
844 .75 0 .75 purple .
845 0 .75 .75 teal .
846
847 .6 .6 .1 deepolive .
848 .6 .1 .6 deeppurple .
849 .1 .6 .6 deepteal .
850
851 1 .5 0 orange .
852 1 0 .5 hotpink .
853 .5 1 0 chartreuse .
854 0 1 .5 limegreen .
855 0 .5 1 marine .
856 .5 0 1 purpleblue .
857
858 */
859
860 CColor *I = G->Color;
861 ColorRec *color = I->Color;
862 int n_color = 0;
863
864 char name[10];
865 int a;
866 int set1;
867 float f;
868 float spectrumS[13][3] = {
869 {1.0, 0.0, 1.0}, /* magenta - 0 */
870 {0.5, 0.0, 1.0},
871 {0.0, 0.0, 1.0}, /* blue - 166.66 */
872 {0.0, 0.5, 1.0},
873 {0.0, 1.0, 1.0}, /* cyan - 333.33 */
874
875 {0.0, 1.0, 0.5},
876 {0.0, 1.0, 0.0}, /* green - 500 */
877 {0.5, 1.0, 0.0},
878 {1.0, 1.0, 0.0}, /* yellow - 666.66 */
879 {1.0, 0.5, 0.0},
880
881 {1.0, 0.0, 0.0}, /* red - 833.33 */
882 {1.0, 0.0, 0.5},
883 {1.0, 0.0, 1.0}, /* magenta - 999 */
884 };
885
886 float spectrumR[13][3] = {
887 {1.0, 1.0, 0.0}, /* yellow - 0 */
888 {0.5, 1.0, 0.0}, /* chartreuse */
889 {0.0, 1.0, 0.0}, /* green - 166.66 */
890 {0.0, 1.0, 0.5}, /* limegreen */
891 {0.0, 1.0, 1.0}, /* cyan - 333.33 */
892
893 {0.0, 0.5, 1.0}, /* marine */
894 {0.0, 0.0, 1.0}, /* blue - 500 */
895 {0.5, 0.0, 1.0}, /* purpleblue */
896 {1.0, 0.0, 1.0}, /* magenta - 666.66 */
897 {1.0, 0.0, 0.5}, /* hotpink */
898
899 {1.0, 0.0, 0.0}, /* red - 833.33 */
900 {1.0, 0.5, 0.0}, /* orange */
901 {1.0, 1.0, 0.0}, /* yellow - 999 */
902 };
903
904 float spectrumC[][3] = {
905 {1.0, 1.0, 0.0}, /* yellow - 0 */
906 {0.0, 0.0, 1.0}, /* blue - 83.333 */
907 {1.0, 0.0, 0.0}, /* red - 167.67 */
908 {0.0, 1.0, 0.0}, /* green - 250.00 */
909 {1.0, 0.0, 1.0}, /* magenta - 333.33 */
910
911 {0.0, 1.0, 1.0}, /* cyan - 416.67 */
912 {1.0, 1.0, 0.0}, /* yellow - 500.00 */
913 {0.0, 1.0, 0.0}, /* green - 583.33 */
914 {0.0, 0.0, 1.0}, /* blue - 666.67 */
915 {1.0, 0.0, 1.0}, /* magenta - 750.00 */
916
917 {1.0, 1.0, 0.0}, /* yellow - 833.33 */
918 {1.0, 0.0, 0.0}, /* red - 916.67 */
919 {0.0, 1.0, 1.0}, /* cyan - 999 */
920 };
921
922 float spectrumW[][3] = {
923 {1.0, 1.0, 0.0}, /* yellow - 0 */
924 {1.0, 1.0, 1.0}, /* white */
925 {0.0, 0.0, 1.0}, /* blue - 83.333 */
926 {1.0, 1.0, 1.0}, /* white */
927 {1.0, 0.0, 0.0}, /* red - 166.67 */
928
929 {1.0, 1.0, 1.0}, /* white */
930 {0.0, 1.0, 0.0}, /* green - 250.00 */
931 {1.0, 1.0, 1.0}, /* white */
932 {1.0, 0.0, 1.0}, /* magenta - 333.33 */
933 {1.0, 1.0, 1.0}, /* white */
934
935 {0.0, 1.0, 1.0}, /* cyan - 416.67 */
936 {1.0, 1.0, 1.0}, /* white */
937 {1.0, 1.0, 0.0}, /* yellow - 500.00 */
938 {1.0, 1.0, 1.0}, /* white */
939 {0.0, 1.0, 0.0}, /* green - 583.33 */
940
941 {1.0, 1.0, 1.0}, /* white */
942 {0.0, 0.0, 1.0}, /* blue - 666.67 */
943 {1.0, 1.0, 1.0}, /* white */
944 {1.0, 0.0, 1.0}, /* magenta - 750.00 */
945 {1.0, 1.0, 1.0}, /* white */
946
947 {1.0, 1.0, 0.0}, /* yellow - 833.33 */
948 {1.0, 1.0, 1.0}, /* white */
949 {1.0, 0.0, 0.0}, /* red - 916.67 */
950 {1.0, 1.0, 1.0}, /* white */
951 {0.0, 1.0, 1.0}, /* cyan - 999 */
952 };
953
954 float spectrumO[29][3] = {
955 /* a rainbow with perceptive color balancing and extra blue/red at the ends */
956 {1.0, 0.0, 1.0}, /* violet */
957 {0.8F, 0.0, 1.0},
958
959 {0.5F, 0.0, 1.0}, /* blend */
960
961 {0.0, 0.0, 1.0}, /* blue */
962 {0.0, 0.0, 1.0}, /* blue */
963 {0.0, 0.2F, 1.0},
964
965 {0.0, 0.5F, 1.0}, /* blend */
966
967 {0.0, 0.8F, 1.0},
968 {0.0, 1.0, 1.0}, /* cyan */
969 {0.0, 1.0, 0.8F},
970
971 {0.0, 1.0, 0.5F}, /* blend */
972
973 {0.0, 1.0, 0.2F},
974 {0.0, 1.0, 0.0}, /* green */
975 {0.2F, 1.0, 0.0},
976
977 {0.5F, 1.0, 0.0}, /* blend */
978
979 {0.8F, 1.0, 0.0},
980 {1.0, 1.0, 0.0}, /* yellow */
981 {1.0, 0.9F, 0.0},
982
983 {1.0, 0.75F, 0.0}, /* blend */
984
985 {1.0, 0.6F, 0.0},
986 {1.0, 0.5F, 0.0}, /* orange */
987 {1.0, 0.4F, 0.0},
988
989 {1.0, 0.3F, 0.0}, /* blend */
990
991 {1.0, 0.2F, 0.0},
992 {1.0, 0.0, 0.0}, /* red */
993 {1.0, 0.0, 0.0}, /* red */
994
995 {1.0, 0.0, 0.5F}, /* blend */
996
997 {1.0, 0.0, 0.8F}, /* violet */
998 {1.0, 0.0, 1.0}, /* violet */
999 };
1000
1001 I->Idx.clear();
1002
1003 /* BLUE->VIOLET->RED r546 to r909 */
1004 /* BLUE->CYAN->GREEN->YELLOW->RED s182 to s909 */
1005 /* BLUE->WHITE->RED w00 to */
1006
1007 color->Name = reg_name(I->Idx, n_color, "white");
1008 color->Color[0] = 1.0F;
1009 color->Color[1] = 1.0F;
1010 color->Color[2] = 1.0F;
1011 n_color++;
1012 color++;
1013
1014 color->Name = reg_name(I->Idx, n_color, "black");
1015 color->Color[0] = 0.0F;
1016 color->Color[1] = 0.0F;
1017 color->Color[2] = 0.0F;
1018 n_color++;
1019 color++;
1020
1021 color->Name = reg_name(I->Idx, n_color, "blue");
1022 color->Color[0] = 0.0F;
1023 color->Color[1] = 0.0F;
1024 color->Color[2] = 1.0F;
1025 n_color++;
1026 color++;
1027
1028 color->Name = reg_name(I->Idx, n_color, "green");
1029 color->Color[0] = 0.0F;
1030 color->Color[1] = 1.0F;
1031 color->Color[2] = 0.0F;
1032 n_color++;
1033 color++;
1034
1035 color->Name = reg_name(I->Idx, n_color, "red");
1036 color->Color[0] = 1.0F;
1037 color->Color[1] = 0.0F;
1038 color->Color[2] = 0.0F;
1039 n_color++;
1040 color++;
1041
1042 color->Name = reg_name(I->Idx, n_color, "cyan");
1043 color->Color[0] = 0.0F;
1044 color->Color[1] = 1.0F;
1045 color->Color[2] = 1.0F;
1046 n_color++;
1047 color++;
1048
1049 color->Name = reg_name(I->Idx, n_color, "yellow");
1050 color->Color[0] = 1.0F;
1051 color->Color[1] = 1.0F;
1052 color->Color[2] = 0.0F;
1053 n_color++;
1054 color++;
1055
1056 color->Name = reg_name(I->Idx, n_color, "dash");
1057 color->Color[0] = 1.0F;
1058 color->Color[1] = 1.0F;
1059 color->Color[2] = 0.0F;
1060 n_color++;
1061 color++;
1062
1063 color->Name = reg_name(I->Idx, n_color, "magenta");
1064 color->Color[0] = 1.0F;
1065 color->Color[1] = 0.0F;
1066 color->Color[2] = 1.0F;
1067 n_color++;
1068 color++;
1069
1070 color->Name = reg_name(I->Idx, n_color, "salmon");
1071 color->Color[0] = 1.0F;
1072 color->Color[1] = 0.6F; /* was 0.5 */
1073 color->Color[2] = 0.6F; /* wat 0.5 */
1074 n_color++;
1075 color++;
1076
1077 color->Name = reg_name(I->Idx, n_color, "lime");
1078 color->Color[0] = 0.5F;
1079 color->Color[1] = 1.0F;
1080 color->Color[2] = 0.5F;
1081 n_color++;
1082 color++;
1083
1084 color->Name = reg_name(I->Idx, n_color, "slate");
1085 color->Color[0] = 0.5F;
1086 color->Color[1] = 0.5F;
1087 color->Color[2] = 1.0F;
1088 n_color++;
1089 color++;
1090
1091 color->Name = reg_name(I->Idx, n_color, "hotpink");
1092 color->Color[0] = 1.0F;
1093 color->Color[1] = 0.0F;
1094 color->Color[2] = 0.5F;
1095 n_color++;
1096 color++;
1097
1098 color->Name = reg_name(I->Idx, n_color, "orange");
1099 color->Color[0] = 1.0F;
1100 color->Color[1] = 0.5F;
1101 color->Color[2] = 0.0F;
1102 n_color++;
1103 color++;
1104
1105 color->Name = reg_name(I->Idx, n_color, "chartreuse"); /* AKA puke green */
1106 color->Color[0] = 0.5F;
1107 color->Color[1] = 1.0F;
1108 color->Color[2] = 0.0F;
1109 n_color++;
1110 color++;
1111
1112 color->Name = reg_name(I->Idx, n_color, "limegreen");
1113 color->Color[0] = 0.0F;
1114 color->Color[1] = 1.0F;
1115 color->Color[2] = 0.5F;
1116 n_color++;
1117 color++;
1118
1119 color->Name = reg_name(I->Idx, n_color, "purpleblue"); /* legacy name */
1120 color->Color[0] = 0.5F;
1121 color->Color[1] = 0.0F;
1122 color->Color[2] = 1.0F;
1123 n_color++;
1124 color++;
1125
1126 color->Name = reg_name(I->Idx, n_color, "marine");
1127 color->Color[0] = 0.0F;
1128 color->Color[1] = 0.5F;
1129 color->Color[2] = 1.0F;
1130 n_color++;
1131 color++;
1132
1133 color->Name = reg_name(I->Idx, n_color, "olive");
1134 color->Color[0] = 0.77F;
1135 color->Color[1] = 0.70F;
1136 color->Color[2] = 0.00F;
1137 n_color++;
1138 color++;
1139
1140 color->Name = reg_name(I->Idx, n_color, "purple");
1141 color->Color[0] = 0.75F;
1142 color->Color[1] = 0.00F;
1143 color->Color[2] = 0.75F;
1144 n_color++;
1145 color++;
1146
1147 color->Name = reg_name(I->Idx, n_color, "teal");
1148 color->Color[0] = 0.00F;
1149 color->Color[1] = 0.75F;
1150 color->Color[2] = 0.75F;
1151 n_color++;
1152 color++;
1153
1154 color->Name = reg_name(I->Idx, n_color, "ruby");
1155 color->Color[0] = 0.6F;
1156 color->Color[1] = 0.2F;
1157 color->Color[2] = 0.2F;
1158 n_color++;
1159 color++;
1160
1161 color->Name = reg_name(I->Idx, n_color, "forest");
1162 color->Color[0] = 0.2F;
1163 color->Color[1] = 0.6F;
1164 color->Color[2] = 0.2F;
1165 n_color++;
1166 color++;
1167
1168 color->Name = reg_name(I->Idx, n_color, "deepblue"); /* was "deep" */
1169 color->Color[0] = 0.25F;
1170 color->Color[1] = 0.25F;
1171 color->Color[2] = 0.65F;
1172 n_color++;
1173 color++;
1174
1175 color->Name = reg_name(I->Idx, n_color, "grey"); /* english spelling */
1176 color->Color[0] = 0.5F;
1177 color->Color[1] = 0.5F;
1178 color->Color[2] = 0.5F;
1179 n_color++;
1180 color++;
1181
1182 color->Name = reg_name(I->Idx, n_color, "gray"); /* american spelling */
1183 color->Color[0] = 0.5F;
1184 color->Color[1] = 0.5F;
1185 color->Color[2] = 0.5F;
1186 n_color++;
1187 color++;
1188
1189 color->Name = reg_name(I->Idx, n_color, "carbon");
1190 color->Color[0] = 0.2F;
1191 color->Color[1] = 1.0F;
1192 color->Color[2] = 0.2F;
1193 n_color++;
1194 color++;
1195
1196 color->Name = reg_name(I->Idx, n_color, "nitrogen");
1197 color->Color[0] = 0.2F;
1198 color->Color[1] = 0.2F;
1199 color->Color[2] = 1.0F;
1200 n_color++;
1201 color++;
1202
1203 color->Name = reg_name(I->Idx, n_color, "oxygen");
1204 color->Color[0] = 1.0F;
1205 color->Color[1] = 0.3F;
1206 color->Color[2] = 0.3F;
1207 n_color++;
1208 color++;
1209
1210 color->Name = reg_name(I->Idx, n_color, "hydrogen");
1211 color->Color[0] = 0.9F;
1212 color->Color[1] = 0.9F;
1213 color->Color[2] = 0.9F;
1214 n_color++;
1215 color++;
1216
1217 color->Name = reg_name(I->Idx, n_color, "brightorange");
1218 color->Color[0] = 1.0F;
1219 color->Color[1] = 0.7F;
1220 color->Color[2] = 0.2F;
1221 n_color++;
1222 color++;
1223
1224 color->Name = reg_name(I->Idx, n_color, "sulfur");
1225 color->Color[0] = 0.9F; /* needs to be far enough from "yellow" */
1226 color->Color[1] = 0.775F; /* to be resolved, while still slightly on */
1227 color->Color[2] = 0.25F; /* the yellow side of yelloworange */
1228 n_color++;
1229 color++;
1230
1231 color->Name = reg_name(I->Idx, n_color, "tv_red");
1232 color->Color[0] = 1.0F;
1233 color->Color[1] = 0.2F;
1234 color->Color[2] = 0.2F;
1235 n_color++;
1236 color++;
1237
1238 color->Name = reg_name(I->Idx, n_color, "tv_green");
1239 color->Color[0] = 0.2F;
1240 color->Color[1] = 1.0F;
1241 color->Color[2] = 0.2F;
1242 n_color++;
1243 color++;
1244
1245 color->Name = reg_name(I->Idx, n_color, "tv_blue");
1246 color->Color[0] = 0.3F;
1247 color->Color[1] = 0.3F;
1248 color->Color[2] = 1.0F;
1249 n_color++;
1250 color++;
1251
1252 color->Name = reg_name(I->Idx, n_color, "tv_yellow");
1253 color->Color[0] = 1.0F;
1254 color->Color[1] = 1.0F;
1255 color->Color[2] = 0.2F;
1256 n_color++;
1257 color++;
1258
1259 color->Name = reg_name(I->Idx, n_color, "yelloworange");
1260 color->Color[0] = 1.0F;
1261 color->Color[1] = 0.87F;
1262 color->Color[2] = 0.37F;
1263 n_color++;
1264 color++;
1265
1266 color->Name = reg_name(I->Idx, n_color, "tv_orange");
1267 color->Color[0] = 1.0F;
1268 color->Color[1] = 0.55F;
1269 color->Color[2] = 0.15F;
1270 n_color++;
1271 color++;
1272
1273 color->Name = reg_name(I->Idx, n_color, "br0");
1274 color->Color[0] = 0.1F;
1275 color->Color[1] = 0.1F;
1276 color->Color[2] = 1.0F;
1277 n_color++;
1278 color++;
1279
1280 color->Name = reg_name(I->Idx, n_color, "br1");
1281 color->Color[0] = 0.2F;
1282 color->Color[1] = 0.1F;
1283 color->Color[2] = 0.9F;
1284 n_color++;
1285 color++;
1286
1287 color->Name = reg_name(I->Idx, n_color, "br2");
1288 color->Color[0] = 0.3F;
1289 color->Color[1] = 0.1F;
1290 color->Color[2] = 0.8F;
1291 n_color++;
1292 color++;
1293
1294 color->Name = reg_name(I->Idx, n_color, "br3");
1295 color->Color[0] = 0.4F;
1296 color->Color[1] = 0.1F;
1297 color->Color[2] = 0.7F;
1298 n_color++;
1299 color++;
1300
1301 color->Name = reg_name(I->Idx, n_color, "br4");
1302 color->Color[0] = 0.5F;
1303 color->Color[1] = 0.1F;
1304 color->Color[2] = 0.6F;
1305 n_color++;
1306 color++;
1307
1308 color->Name = reg_name(I->Idx, n_color, "br5");
1309 color->Color[0] = 0.6F;
1310 color->Color[1] = 0.1F;
1311 color->Color[2] = 0.5F;
1312 n_color++;
1313 color++;
1314
1315 color->Name = reg_name(I->Idx, n_color, "br6");
1316 color->Color[0] = 0.7F;
1317 color->Color[1] = 0.1F;
1318 color->Color[2] = 0.4F;
1319 n_color++;
1320 color++;
1321
1322 color->Name = reg_name(I->Idx, n_color, "br7");
1323 color->Color[0] = 0.8F;
1324 color->Color[1] = 0.1F;
1325 color->Color[2] = 0.3F;
1326 n_color++;
1327 color++;
1328
1329 color->Name = reg_name(I->Idx, n_color, "br8");
1330 color->Color[0] = 0.9F;
1331 color->Color[1] = 0.1F;
1332 color->Color[2] = 0.2F;
1333 n_color++;
1334 color++;
1335
1336 color->Name = reg_name(I->Idx, n_color, "br9");
1337 color->Color[0] = 1.0F;
1338 color->Color[1] = 0.1F;
1339 color->Color[2] = 0.1F;
1340 n_color++;
1341 color++;
1342
1343 color->Name = reg_name(I->Idx, n_color, "pink");
1344 color->Color[0] = 1.0F;
1345 color->Color[1] = 0.65F;
1346 color->Color[2] = 0.85F;
1347 n_color++;
1348 color++;
1349
1350 color->Name = reg_name(I->Idx, n_color, "firebrick");
1351 color->Color[0] = 0.698F;
1352 color->Color[1] = 0.13F;
1353 color->Color[2] = 0.13F;
1354 n_color++;
1355 color++;
1356
1357 color->Name = reg_name(I->Idx, n_color, "chocolate");
1358 color->Color[0] = 0.555F;
1359 color->Color[1] = 0.222F;
1360 color->Color[2] = 0.111F;
1361 n_color++;
1362 color++;
1363
1364 color->Name = reg_name(I->Idx, n_color, "brown");
1365 color->Color[0] = 0.65F;
1366 color->Color[1] = 0.32F;
1367 color->Color[2] = 0.17F;
1368 n_color++;
1369 color++;
1370
1371 color->Name = reg_name(I->Idx, n_color, "wheat");
1372 color->Color[0] = 0.99F;
1373 color->Color[1] = 0.82F;
1374 color->Color[2] = 0.65F;
1375 n_color++;
1376 color++;
1377
1378 color->Name = reg_name(I->Idx, n_color, "violet");
1379 color->Color[0] = 1.0F;
1380 color->Color[1] = 0.5F;
1381 color->Color[2] = 1.0F;
1382 n_color++;
1383 color++;
1384
1385 /* greybow */
1386
1387 strcpy(name, "grey00"); /* english spelling */
1388 for(a = 0; a < 100; a = a + 1) {
1389 name[5] = (a % 10) + '0';
1390 name[4] = ((a % 100) / 10) + '0';
1391 /* sprintf(color->Name,"grey%02d",a); */
1392 color->Name = reg_name(I->Idx, n_color, name);
1393 color->Color[0] = a / 99.0F;
1394 color->Color[1] = a / 99.0F;
1395 color->Color[2] = a / 99.0F;
1396 n_color++;
1397 color++;
1398 }
1399
1400 color->Name = reg_name(I->Idx, n_color, "lightmagenta");
1401 color->Color[0] = 1.0F;
1402 color->Color[1] = 0.2F;
1403 color->Color[2] = 0.8F;
1404 n_color++;
1405 color++;
1406
1407 #define A_DIV 83.333333333F
1408
1409 /* full spectrum (s000-s999) */
1410
1411 strcpy(name, "s000");
1412 for(a = 0; a < 1000; a = a + 1) {
1413 set1 = (int) (a / A_DIV);
1414 name[3] = (a % 10) + '0';
1415 name[2] = ((a % 100) / 10) + '0';
1416 name[1] = ((a % 1000) / 100) + '0';
1417 /* sprintf(color->Name,"s%03d",a); */
1418 f = 1.0F - (a - (set1 * A_DIV)) / A_DIV;
1419 color->Name = reg_name(I->Idx, n_color, name);
1420 color->Color[0] = f * spectrumS[set1][0] + (1.0F - f) * spectrumS[set1 + 1][0];
1421 color->Color[1] = f * spectrumS[set1][1] + (1.0F - f) * spectrumS[set1 + 1][1];
1422 color->Color[2] = f * spectrumS[set1][2] + (1.0F - f) * spectrumS[set1 + 1][2];
1423 n_color++;
1424 color++;
1425 }
1426
1427 /* offset & reversed full spectrum (r000-r999) */
1428
1429 strcpy(name, "r000");
1430 for(a = 0; a < 1000; a = a + 1) {
1431 set1 = (int) (a / A_DIV);
1432 /* sprintf(color->Name,"r%03d",a); */
1433 name[3] = (a % 10) + '0';
1434 name[2] = ((a % 100) / 10) + '0';
1435 name[1] = ((a % 1000) / 100) + '0';
1436 f = 1.0F - (a - (set1 * A_DIV)) / A_DIV;
1437 color->Name = reg_name(I->Idx, n_color, name);
1438 color->Color[0] = f * spectrumR[set1][0] + (1.0F - f) * spectrumR[set1 + 1][0];
1439 color->Color[1] = f * spectrumR[set1][1] + (1.0F - f) * spectrumR[set1 + 1][1];
1440 color->Color[2] = f * spectrumR[set1][2] + (1.0F - f) * spectrumR[set1 + 1][2];
1441 n_color++;
1442 color++;
1443 }
1444
1445 /* complementary spectra (c000-c999) */
1446
1447 strcpy(name, "c000");
1448 for(a = 0; a < 1000; a = a + 1) {
1449 set1 = (int) (a / A_DIV);
1450 /* sprintf(color->Name,"c%03d",a); */
1451 name[3] = (a % 10) + '0';
1452 name[2] = ((a % 100) / 10) + '0';
1453 name[1] = ((a % 1000) / 100) + '0';
1454 f = 1.0F - (a - (set1 * A_DIV)) / A_DIV;
1455 color->Name = reg_name(I->Idx, n_color, name);
1456 color->Color[0] = f * spectrumC[set1][0] + (1.0F - f) * spectrumC[set1 + 1][0];
1457 color->Color[1] = f * spectrumC[set1][1] + (1.0F - f) * spectrumC[set1 + 1][1];
1458 color->Color[2] = f * spectrumC[set1][2] + (1.0F - f) * spectrumC[set1 + 1][2];
1459 n_color++;
1460 color++;
1461 }
1462
1463 #define W_DIV 41.666666667F
1464
1465 /* complementary spectra separated by white (w000-w999) */
1466
1467 strcpy(name, "w000");
1468 for(a = 0; a < 1000; a = a + 1) {
1469 set1 = (int) (a / W_DIV);
1470 /* sprintf(color->Name,"w%03d",a); */
1471 name[3] = (a % 10) + '0';
1472 name[2] = ((a % 100) / 10) + '0';
1473 name[1] = ((a % 1000) / 100) + '0';
1474 f = 1.0F - (a - (set1 * W_DIV)) / W_DIV;
1475 color->Name = reg_name(I->Idx, n_color, name);
1476 color->Color[0] = f * spectrumW[set1][0] + (1.0F - f) * spectrumW[set1 + 1][0];
1477 color->Color[1] = f * spectrumW[set1][1] + (1.0F - f) * spectrumW[set1 + 1][1];
1478 color->Color[2] = f * spectrumW[set1][2] + (1.0F - f) * spectrumW[set1 + 1][2];
1479 n_color++;
1480 color++;
1481 }
1482
1483 color->Name = reg_name(I->Idx, n_color, "density");
1484 color->Color[0] = 0.1F;
1485 color->Color[1] = 0.1F;
1486 color->Color[2] = 0.6F;
1487 n_color++;
1488 color++;
1489
1490 strcpy(name, "gray00"); /* american */
1491 for(a = 0; a < 100; a = a + 1) {
1492 name[5] = (a % 10) + '0';
1493 name[4] = ((a % 100) / 10) + '0';
1494 /* sprintf(color->Name,"gray%02d",a); */
1495 color->Name = reg_name(I->Idx, n_color, name);
1496 color->Color[0] = a / 99.0F;
1497 color->Color[1] = a / 99.0F;
1498 color->Color[2] = a / 99.0F;
1499 n_color++;
1500 color++;
1501 }
1502
1503 /* original full spectrum, with extra blue and red at the ends (o000-o999) */
1504
1505 #define B_DIV 35.7143F
1506
1507 strcpy(name, "o000");
1508 for(a = 0; a < 1000; a = a + 1) {
1509 set1 = (int) (a / B_DIV);
1510 name[3] = (a % 10) + '0';
1511 name[2] = ((a % 100) / 10) + '0';
1512 name[1] = ((a % 1000) / 100) + '0';
1513 /* sprintf(color->Name,"o%03d",a); */
1514 f = 1.0F - (a - (set1 * B_DIV)) / B_DIV;
1515 color->Name = reg_name(I->Idx, n_color, name);
1516 color->Color[0] = f * spectrumO[set1][0] + (1.0F - f) * spectrumO[set1 + 1][0];
1517 color->Color[1] = f * spectrumO[set1][1] + (1.0F - f) * spectrumO[set1 + 1][1];
1518 color->Color[2] = f * spectrumO[set1][2] + (1.0F - f) * spectrumO[set1 + 1][2];
1519 n_color++;
1520 color++;
1521 }
1522
1523 color->Name = reg_name(I->Idx, n_color, "paleyellow");
1524 color->Color[0] = 1.0F;
1525 color->Color[1] = 1.0F;
1526 color->Color[2] = 0.5F;
1527 n_color++;
1528 color++;
1529
1530 color->Name = reg_name(I->Idx, n_color, "aquamarine");
1531 color->Color[0] = 0.5F;
1532 color->Color[1] = 1.0F;
1533 color->Color[2] = 1.0F;
1534 n_color++;
1535 color++;
1536
1537 color->Name = reg_name(I->Idx, n_color, "deepsalmon");
1538 color->Color[0] = 1.0F;
1539 color->Color[1] = 0.5F;
1540 color->Color[2] = 0.5F;
1541 n_color++;
1542 color++;
1543
1544 color->Name = reg_name(I->Idx, n_color, "palegreen");
1545 color->Color[0] = 0.65F;
1546 color->Color[1] = 0.9F;
1547 color->Color[2] = 0.65F;
1548 n_color++;
1549 color++;
1550
1551 color->Name = reg_name(I->Idx, n_color, "deepolive");
1552 color->Color[0] = 0.6F;
1553 color->Color[1] = 0.6F;
1554 color->Color[2] = 0.1F;
1555 n_color++;
1556 color++;
1557
1558 color->Name = reg_name(I->Idx, n_color, "deeppurple");
1559 color->Color[0] = 0.6F;
1560 color->Color[1] = 0.1F;
1561 color->Color[2] = 0.6F;
1562 n_color++;
1563 color++;
1564
1565 color->Name = reg_name(I->Idx, n_color, "deepteal");
1566 color->Color[0] = 0.1F;
1567 color->Color[1] = 0.6F;
1568 color->Color[2] = 0.6F;
1569 n_color++;
1570 color++;
1571
1572 color->Name = reg_name(I->Idx, n_color, "lightblue");
1573 color->Color[0] = 0.75F;
1574 color->Color[1] = 0.75;
1575 color->Color[2] = 1.0F;
1576 n_color++;
1577 color++;
1578
1579 color->Name = reg_name(I->Idx, n_color, "lightorange");
1580 color->Color[0] = 1.0F;
1581 color->Color[1] = 0.8F;
1582 color->Color[2] = 0.5F;
1583 n_color++;
1584 color++;
1585
1586 color->Name = reg_name(I->Idx, n_color, "palecyan");
1587 color->Color[0] = 0.8F;
1588 color->Color[1] = 1.0F;
1589 color->Color[2] = 1.0F;
1590 n_color++;
1591 color++;
1592
1593 color->Name = reg_name(I->Idx, n_color, "lightteal");
1594 color->Color[0] = 0.4F;
1595 color->Color[1] = 0.7F;
1596 color->Color[2] = 0.7F;
1597 n_color++;
1598 color++;
1599
1600 color->Name = reg_name(I->Idx, n_color, "splitpea");
1601 color->Color[0] = 0.52F;
1602 color->Color[1] = 0.75F;
1603 color->Color[2] = 0.00F;
1604 n_color++;
1605 color++;
1606
1607 color->Name = reg_name(I->Idx, n_color, "raspberry");
1608 color->Color[0] = 0.70F;
1609 color->Color[1] = 0.30F;
1610 color->Color[2] = 0.40F;
1611 n_color++;
1612 color++;
1613
1614 color->Name = reg_name(I->Idx, n_color, "sand");
1615 color->Color[0] = 0.72F;
1616 color->Color[1] = 0.55F;
1617 color->Color[2] = 0.30F;
1618 n_color++;
1619 color++;
1620
1621 color->Name = reg_name(I->Idx, n_color, "smudge");
1622 color->Color[0] = 0.55F;
1623 color->Color[1] = 0.70F;
1624 color->Color[2] = 0.40F;
1625 n_color++;
1626 color++;
1627
1628 color->Name = reg_name(I->Idx, n_color, "violetpurple");
1629 color->Color[0] = 0.55F;
1630 color->Color[1] = 0.25F;
1631 color->Color[2] = 0.60F;
1632 n_color++;
1633 color++;
1634
1635 color->Name = reg_name(I->Idx, n_color, "dirtyviolet");
1636 color->Color[0] = 0.70F;
1637 color->Color[1] = 0.50F;
1638 color->Color[2] = 0.50F;
1639 n_color++;
1640 color++;
1641
1642 color->Name = reg_name(I->Idx, n_color, "deepsalmon");
1643 color->Color[0] = 1.00F;
1644 color->Color[1] = 0.42F;
1645 color->Color[2] = 0.42F;
1646 n_color++;
1647 color++;
1648
1649 color->Name = reg_name(I->Idx, n_color, "lightpink");
1650 color->Color[0] = 1.00F;
1651 color->Color[1] = 0.75F;
1652 color->Color[2] = 0.87F;
1653 n_color++;
1654 color++;
1655
1656 color->Name = reg_name(I->Idx, n_color, "greencyan");
1657 color->Color[0] = 0.25F;
1658 color->Color[1] = 1.00F;
1659 color->Color[2] = 0.75F;
1660 n_color++;
1661 color++;
1662
1663 color->Name = reg_name(I->Idx, n_color, "limon");
1664 color->Color[0] = 0.75F;
1665 color->Color[1] = 1.00F;
1666 color->Color[2] = 0.25F;
1667 n_color++;
1668 color++;
1669
1670 color->Name = reg_name(I->Idx, n_color, "skyblue");
1671 color->Color[0] = 0.20F;
1672 color->Color[1] = 0.50F;
1673 color->Color[2] = 0.80F;
1674 n_color++;
1675 color++;
1676
1677 color->Name = reg_name(I->Idx, n_color, "bluewhite");
1678 color->Color[0] = 0.85F;
1679 color->Color[1] = 0.85F;
1680 color->Color[2] = 1.00F;
1681 n_color++;
1682 color++;
1683
1684 color->Name = reg_name(I->Idx, n_color, "warmpink");
1685 color->Color[0] = 0.85F;
1686 color->Color[1] = 0.20F;
1687 color->Color[2] = 0.50F;
1688 n_color++;
1689 color++;
1690
1691 color->Name = reg_name(I->Idx, n_color, "darksalmon");
1692 color->Color[0] = 0.73F;
1693 color->Color[1] = 0.55F;
1694 color->Color[2] = 0.52F;
1695 n_color++;
1696 color++;
1697
1698 color->Name = reg_name(I->Idx, n_color, "helium");
1699 color->Color[0] = 0.850980392F;
1700 color->Color[1] = 1.000000000F;
1701 color->Color[2] = 1.000000000F;
1702 n_color++;
1703 color++;
1704
1705 color->Name = reg_name(I->Idx, n_color, "lithium");
1706 color->Color[0] = 0.800000000F;
1707 color->Color[1] = 0.501960784F;
1708 color->Color[2] = 1.000000000F;
1709 n_color++;
1710 color++;
1711
1712 color->Name = reg_name(I->Idx, n_color, "beryllium");
1713 color->Color[0] = 0.760784314F;
1714 color->Color[1] = 1.000000000F;
1715 color->Color[2] = 0.000000000F;
1716 n_color++;
1717 color++;
1718
1719 color->Name = reg_name(I->Idx, n_color, "boron");
1720 color->Color[0] = 1.000000000F;
1721 color->Color[1] = 0.709803922F;
1722 color->Color[2] = 0.709803922F;
1723 n_color++;
1724 color++;
1725
1726 color->Name = reg_name(I->Idx, n_color, "fluorine");
1727 color->Color[0] = 0.701960784F;
1728 color->Color[1] = 1.000000000F;
1729 color->Color[2] = 1.000000000F;
1730 n_color++;
1731 color++;
1732
1733 color->Name = reg_name(I->Idx, n_color, "neon");
1734 color->Color[0] = 0.701960784F;
1735 color->Color[1] = 0.890196078F;
1736 color->Color[2] = 0.960784314F;
1737 n_color++;
1738 color++;
1739
1740 color->Name = reg_name(I->Idx, n_color, "sodium");
1741 color->Color[0] = 0.670588235F;
1742 color->Color[1] = 0.360784314F;
1743 color->Color[2] = 0.949019608F;
1744 n_color++;
1745 color++;
1746
1747 color->Name = reg_name(I->Idx, n_color, "magnesium");
1748 color->Color[0] = 0.541176471F;
1749 color->Color[1] = 1.000000000F;
1750 color->Color[2] = 0.000000000F;
1751 n_color++;
1752 color++;
1753
1754 color->Name = reg_name(I->Idx, n_color, "aluminum");
1755 color->Color[0] = 0.749019608F;
1756 color->Color[1] = 0.650980392F;
1757 color->Color[2] = 0.650980392F;
1758 n_color++;
1759 color++;
1760
1761 color->Name = reg_name(I->Idx, n_color, "silicon");
1762 color->Color[0] = 0.941176471F;
1763 color->Color[1] = 0.784313725F;
1764 color->Color[2] = 0.627450980F;
1765 n_color++;
1766 color++;
1767
1768 color->Name = reg_name(I->Idx, n_color, "phosphorus");
1769 color->Color[0] = 1.000000000F;
1770 color->Color[1] = 0.501960784F;
1771 color->Color[2] = 0.000000000F;
1772 n_color++;
1773 color++;
1774
1775 color->Name = reg_name(I->Idx, n_color, "chlorine");
1776 color->Color[0] = 0.121568627F;
1777 color->Color[1] = 0.941176471F;
1778 color->Color[2] = 0.121568627F;
1779 n_color++;
1780 color++;
1781
1782 color->Name = reg_name(I->Idx, n_color, "argon");
1783 color->Color[0] = 0.501960784F;
1784 color->Color[1] = 0.819607843F;
1785 color->Color[2] = 0.890196078F;
1786 n_color++;
1787 color++;
1788
1789 color->Name = reg_name(I->Idx, n_color, "potassium");
1790 color->Color[0] = 0.560784314F;
1791 color->Color[1] = 0.250980392F;
1792 color->Color[2] = 0.831372549F;
1793 n_color++;
1794 color++;
1795
1796 color->Name = reg_name(I->Idx, n_color, "calcium");
1797 color->Color[0] = 0.239215686F;
1798 color->Color[1] = 1.000000000F;
1799 color->Color[2] = 0.000000000F;
1800 n_color++;
1801 color++;
1802
1803 color->Name = reg_name(I->Idx, n_color, "scandium");
1804 color->Color[0] = 0.901960784F;
1805 color->Color[1] = 0.901960784F;
1806 color->Color[2] = 0.901960784F;
1807 n_color++;
1808 color++;
1809
1810 color->Name = reg_name(I->Idx, n_color, "titanium");
1811 color->Color[0] = 0.749019608F;
1812 color->Color[1] = 0.760784314F;
1813 color->Color[2] = 0.780392157F;
1814 n_color++;
1815 color++;
1816
1817 color->Name = reg_name(I->Idx, n_color, "vanadium");
1818 color->Color[0] = 0.650980392F;
1819 color->Color[1] = 0.650980392F;
1820 color->Color[2] = 0.670588235F;
1821 n_color++;
1822 color++;
1823
1824 color->Name = reg_name(I->Idx, n_color, "chromium");
1825 color->Color[0] = 0.541176471F;
1826 color->Color[1] = 0.600000000F;
1827 color->Color[2] = 0.780392157F;
1828 n_color++;
1829 color++;
1830
1831 color->Name = reg_name(I->Idx, n_color, "manganese");
1832 color->Color[0] = 0.611764706F;
1833 color->Color[1] = 0.478431373F;
1834 color->Color[2] = 0.780392157F;
1835 n_color++;
1836 color++;
1837
1838 color->Name = reg_name(I->Idx, n_color, "iron");
1839 color->Color[0] = 0.878431373F;
1840 color->Color[1] = 0.400000000F;
1841 color->Color[2] = 0.200000000F;
1842 n_color++;
1843 color++;
1844
1845 color->Name = reg_name(I->Idx, n_color, "cobalt");
1846 color->Color[0] = 0.941176471F;
1847 color->Color[1] = 0.564705882F;
1848 color->Color[2] = 0.627450980F;
1849 n_color++;
1850 color++;
1851
1852 color->Name = reg_name(I->Idx, n_color, "nickel");
1853 color->Color[0] = 0.313725490F;
1854 color->Color[1] = 0.815686275F;
1855 color->Color[2] = 0.313725490F;
1856 n_color++;
1857 color++;
1858
1859 color->Name = reg_name(I->Idx, n_color, "copper");
1860 color->Color[0] = 0.784313725F;
1861 color->Color[1] = 0.501960784F;
1862 color->Color[2] = 0.200000000F;
1863 n_color++;
1864 color++;
1865
1866 color->Name = reg_name(I->Idx, n_color, "zinc");
1867 color->Color[0] = 0.490196078F;
1868 color->Color[1] = 0.501960784F;
1869 color->Color[2] = 0.690196078F;
1870 n_color++;
1871 color++;
1872
1873 color->Name = reg_name(I->Idx, n_color, "gallium");
1874 color->Color[0] = 0.760784314F;
1875 color->Color[1] = 0.560784314F;
1876 color->Color[2] = 0.560784314F;
1877 n_color++;
1878 color++;
1879
1880 color->Name = reg_name(I->Idx, n_color, "germanium");
1881 color->Color[0] = 0.400000000F;
1882 color->Color[1] = 0.560784314F;
1883 color->Color[2] = 0.560784314F;
1884 n_color++;
1885 color++;
1886
1887 color->Name = reg_name(I->Idx, n_color, "arsenic");
1888 color->Color[0] = 0.741176471F;
1889 color->Color[1] = 0.501960784F;
1890 color->Color[2] = 0.890196078F;
1891 n_color++;
1892 color++;
1893
1894 color->Name = reg_name(I->Idx, n_color, "selenium");
1895 color->Color[0] = 1.000000000F;
1896 color->Color[1] = 0.631372549F;
1897 color->Color[2] = 0.000000000F;
1898 n_color++;
1899 color++;
1900
1901 color->Name = reg_name(I->Idx, n_color, "bromine");
1902 color->Color[0] = 0.650980392F;
1903 color->Color[1] = 0.160784314F;
1904 color->Color[2] = 0.160784314F;
1905 n_color++;
1906 color++;
1907
1908 color->Name = reg_name(I->Idx, n_color, "krypton");
1909 color->Color[0] = 0.360784314F;
1910 color->Color[1] = 0.721568627F;
1911 color->Color[2] = 0.819607843F;
1912 n_color++;
1913 color++;
1914
1915 color->Name = reg_name(I->Idx, n_color, "rubidium");
1916 color->Color[0] = 0.439215686F;
1917 color->Color[1] = 0.180392157F;
1918 color->Color[2] = 0.690196078F;
1919 n_color++;
1920 color++;
1921
1922 color->Name = reg_name(I->Idx, n_color, "strontium");
1923 color->Color[0] = 0.000000000F;
1924 color->Color[1] = 1.000000000F;
1925 color->Color[2] = 0.000000000F;
1926 n_color++;
1927 color++;
1928
1929 color->Name = reg_name(I->Idx, n_color, "yttrium");
1930 color->Color[0] = 0.580392157F;
1931 color->Color[1] = 1.000000000F;
1932 color->Color[2] = 1.000000000F;
1933 n_color++;
1934 color++;
1935
1936 color->Name = reg_name(I->Idx, n_color, "zirconium");
1937 color->Color[0] = 0.580392157F;
1938 color->Color[1] = 0.878431373F;
1939 color->Color[2] = 0.878431373F;
1940 n_color++;
1941 color++;
1942
1943 color->Name = reg_name(I->Idx, n_color, "niobium");
1944 color->Color[0] = 0.450980392F;
1945 color->Color[1] = 0.760784314F;
1946 color->Color[2] = 0.788235294F;
1947 n_color++;
1948 color++;
1949
1950 color->Name = reg_name(I->Idx, n_color, "molybdenum");
1951 color->Color[0] = 0.329411765F;
1952 color->Color[1] = 0.709803922F;
1953 color->Color[2] = 0.709803922F;
1954 n_color++;
1955 color++;
1956
1957 color->Name = reg_name(I->Idx, n_color, "technetium");
1958 color->Color[0] = 0.231372549F;
1959 color->Color[1] = 0.619607843F;
1960 color->Color[2] = 0.619607843F;
1961 n_color++;
1962 color++;
1963
1964 color->Name = reg_name(I->Idx, n_color, "ruthenium");
1965 color->Color[0] = 0.141176471F;
1966 color->Color[1] = 0.560784314F;
1967 color->Color[2] = 0.560784314F;
1968 n_color++;
1969 color++;
1970
1971 color->Name = reg_name(I->Idx, n_color, "rhodium");
1972 color->Color[0] = 0.039215686F;
1973 color->Color[1] = 0.490196078F;
1974 color->Color[2] = 0.549019608F;
1975 n_color++;
1976 color++;
1977
1978 color->Name = reg_name(I->Idx, n_color, "palladium");
1979 color->Color[0] = 0.000000000F;
1980 color->Color[1] = 0.411764706F;
1981 color->Color[2] = 0.521568627F;
1982 n_color++;
1983 color++;
1984
1985 color->Name = reg_name(I->Idx, n_color, "silver");
1986 color->Color[0] = 0.752941176F;
1987 color->Color[1] = 0.752941176F;
1988 color->Color[2] = 0.752941176F;
1989 n_color++;
1990 color++;
1991
1992 color->Name = reg_name(I->Idx, n_color, "cadmium");
1993 color->Color[0] = 1.000000000F;
1994 color->Color[1] = 0.850980392F;
1995 color->Color[2] = 0.560784314F;
1996 n_color++;
1997 color++;
1998
1999 color->Name = reg_name(I->Idx, n_color, "indium");
2000 color->Color[0] = 0.650980392F;
2001 color->Color[1] = 0.458823529F;
2002 color->Color[2] = 0.450980392F;
2003 n_color++;
2004 color++;
2005
2006 color->Name = reg_name(I->Idx, n_color, "tin");
2007 color->Color[0] = 0.400000000F;
2008 color->Color[1] = 0.501960784F;
2009 color->Color[2] = 0.501960784F;
2010 n_color++;
2011 color++;
2012
2013 color->Name = reg_name(I->Idx, n_color, "antimony");
2014 color->Color[0] = 0.619607843F;
2015 color->Color[1] = 0.388235294F;
2016 color->Color[2] = 0.709803922F;
2017 n_color++;
2018 color++;
2019
2020 color->Name = reg_name(I->Idx, n_color, "tellurium");
2021 color->Color[0] = 0.831372549F;
2022 color->Color[1] = 0.478431373F;
2023 color->Color[2] = 0.000000000F;
2024 n_color++;
2025 color++;
2026
2027 color->Name = reg_name(I->Idx, n_color, "iodine");
2028 color->Color[0] = 0.580392157F;
2029 color->Color[1] = 0.000000000F;
2030 color->Color[2] = 0.580392157F;
2031 n_color++;
2032 color++;
2033
2034 color->Name = reg_name(I->Idx, n_color, "xenon");
2035 color->Color[0] = 0.258823529F;
2036 color->Color[1] = 0.619607843F;
2037 color->Color[2] = 0.690196078F;
2038 n_color++;
2039 color++;
2040
2041 color->Name = reg_name(I->Idx, n_color, "cesium");
2042 color->Color[0] = 0.341176471F;
2043 color->Color[1] = 0.090196078F;
2044 color->Color[2] = 0.560784314F;
2045 n_color++;
2046 color++;
2047
2048 color->Name = reg_name(I->Idx, n_color, "barium");
2049 color->Color[0] = 0.000000000F;
2050 color->Color[1] = 0.788235294F;
2051 color->Color[2] = 0.000000000F;
2052 n_color++;
2053 color++;
2054
2055 color->Name = reg_name(I->Idx, n_color, "lanthanum");
2056 color->Color[0] = 0.439215686F;
2057 color->Color[1] = 0.831372549F;
2058 color->Color[2] = 1.000000000F;
2059 n_color++;
2060 color++;
2061
2062 color->Name = reg_name(I->Idx, n_color, "cerium");
2063 color->Color[0] = 1.000000000F;
2064 color->Color[1] = 1.000000000F;
2065 color->Color[2] = 0.780392157F;
2066 n_color++;
2067 color++;
2068
2069 color->Name = reg_name(I->Idx, n_color, "praseodymium");
2070 color->Color[0] = 0.850980392F;
2071 color->Color[1] = 1.000000000F;
2072 color->Color[2] = 0.780392157F;
2073 n_color++;
2074 color++;
2075
2076 color->Name = reg_name(I->Idx, n_color, "neodymium");
2077 color->Color[0] = 0.780392157F;
2078 color->Color[1] = 1.000000000F;
2079 color->Color[2] = 0.780392157F;
2080 n_color++;
2081 color++;
2082
2083 color->Name = reg_name(I->Idx, n_color, "promethium");
2084 color->Color[0] = 0.639215686F;
2085 color->Color[1] = 1.000000000F;
2086 color->Color[2] = 0.780392157F;
2087 n_color++;
2088 color++;
2089
2090 color->Name = reg_name(I->Idx, n_color, "samarium");
2091 color->Color[0] = 0.560784314F;
2092 color->Color[1] = 1.000000000F;
2093 color->Color[2] = 0.780392157F;
2094 n_color++;
2095 color++;
2096
2097 color->Name = reg_name(I->Idx, n_color, "europium");
2098 color->Color[0] = 0.380392157F;
2099 color->Color[1] = 1.000000000F;
2100 color->Color[2] = 0.780392157F;
2101 n_color++;
2102 color++;
2103
2104 color->Name = reg_name(I->Idx, n_color, "gadolinium");
2105 color->Color[0] = 0.270588235F;
2106 color->Color[1] = 1.000000000F;
2107 color->Color[2] = 0.780392157F;
2108 n_color++;
2109 color++;
2110
2111 color->Name = reg_name(I->Idx, n_color, "terbium");
2112 color->Color[0] = 0.188235294F;
2113 color->Color[1] = 1.000000000F;
2114 color->Color[2] = 0.780392157F;
2115 n_color++;
2116 color++;
2117
2118 color->Name = reg_name(I->Idx, n_color, "dysprosium");
2119 color->Color[0] = 0.121568627F;
2120 color->Color[1] = 1.000000000F;
2121 color->Color[2] = 0.780392157F;
2122 n_color++;
2123 color++;
2124
2125 color->Name = reg_name(I->Idx, n_color, "holmium");
2126 color->Color[0] = 0.000000000F;
2127 color->Color[1] = 1.000000000F;
2128 color->Color[2] = 0.611764706F;
2129 n_color++;
2130 color++;
2131
2132 color->Name = reg_name(I->Idx, n_color, "erbium");
2133 color->Color[0] = 0.000000000F;
2134 color->Color[1] = 0.901960784F;
2135 color->Color[2] = 0.458823529F;
2136 n_color++;
2137 color++;
2138
2139 color->Name = reg_name(I->Idx, n_color, "thulium");
2140 color->Color[0] = 0.000000000F;
2141 color->Color[1] = 0.831372549F;
2142 color->Color[2] = 0.321568627F;
2143 n_color++;
2144 color++;
2145
2146 color->Name = reg_name(I->Idx, n_color, "ytterbium");
2147 color->Color[0] = 0.000000000F;
2148 color->Color[1] = 0.749019608F;
2149 color->Color[2] = 0.219607843F;
2150 n_color++;
2151 color++;
2152
2153 color->Name = reg_name(I->Idx, n_color, "lutetium");
2154 color->Color[0] = 0.000000000F;
2155 color->Color[1] = 0.670588235F;
2156 color->Color[2] = 0.141176471F;
2157 n_color++;
2158 color++;
2159
2160 color->Name = reg_name(I->Idx, n_color, "hafnium");
2161 color->Color[0] = 0.301960784F;
2162 color->Color[1] = 0.760784314F;
2163 color->Color[2] = 1.000000000F;
2164 n_color++;
2165 color++;
2166
2167 color->Name = reg_name(I->Idx, n_color, "tantalum");
2168 color->Color[0] = 0.301960784F;
2169 color->Color[1] = 0.650980392F;
2170 color->Color[2] = 1.000000000F;
2171 n_color++;
2172 color++;
2173
2174 color->Name = reg_name(I->Idx, n_color, "tungsten");
2175 color->Color[0] = 0.129411765F;
2176 color->Color[1] = 0.580392157F;
2177 color->Color[2] = 0.839215686F;
2178 n_color++;
2179 color++;
2180
2181 color->Name = reg_name(I->Idx, n_color, "rhenium");
2182 color->Color[0] = 0.149019608F;
2183 color->Color[1] = 0.490196078F;
2184 color->Color[2] = 0.670588235F;
2185 n_color++;
2186 color++;
2187
2188 color->Name = reg_name(I->Idx, n_color, "osmium");
2189 color->Color[0] = 0.149019608F;
2190 color->Color[1] = 0.400000000F;
2191 color->Color[2] = 0.588235294F;
2192 n_color++;
2193 color++;
2194
2195 color->Name = reg_name(I->Idx, n_color, "iridium");
2196 color->Color[0] = 0.090196078F;
2197 color->Color[1] = 0.329411765F;
2198 color->Color[2] = 0.529411765F;
2199 n_color++;
2200 color++;
2201
2202 color->Name = reg_name(I->Idx, n_color, "platinum");
2203 color->Color[0] = 0.815686275F;
2204 color->Color[1] = 0.815686275F;
2205 color->Color[2] = 0.878431373F;
2206 n_color++;
2207 color++;
2208
2209 color->Name = reg_name(I->Idx, n_color, "gold");
2210 color->Color[0] = 1.000000000F;
2211 color->Color[1] = 0.819607843F;
2212 color->Color[2] = 0.137254902F;
2213 n_color++;
2214 color++;
2215
2216 color->Name = reg_name(I->Idx, n_color, "mercury");
2217 color->Color[0] = 0.721568627F;
2218 color->Color[1] = 0.721568627F;
2219 color->Color[2] = 0.815686275F;
2220 n_color++;
2221 color++;
2222
2223 color->Name = reg_name(I->Idx, n_color, "thallium");
2224 color->Color[0] = 0.650980392F;
2225 color->Color[1] = 0.329411765F;
2226 color->Color[2] = 0.301960784F;
2227 n_color++;
2228 color++;
2229
2230 color->Name = reg_name(I->Idx, n_color, "lead");
2231 color->Color[0] = 0.341176471F;
2232 color->Color[1] = 0.349019608F;
2233 color->Color[2] = 0.380392157F;
2234 n_color++;
2235 color++;
2236
2237 color->Name = reg_name(I->Idx, n_color, "bismuth");
2238 color->Color[0] = 0.619607843F;
2239 color->Color[1] = 0.309803922F;
2240 color->Color[2] = 0.709803922F;
2241 n_color++;
2242 color++;
2243
2244 color->Name = reg_name(I->Idx, n_color, "polonium");
2245 color->Color[0] = 0.670588235F;
2246 color->Color[1] = 0.360784314F;
2247 color->Color[2] = 0.000000000F;
2248 n_color++;
2249 color++;
2250
2251 color->Name = reg_name(I->Idx, n_color, "astatine");
2252 color->Color[0] = 0.458823529F;
2253 color->Color[1] = 0.309803922F;
2254 color->Color[2] = 0.270588235F;
2255 n_color++;
2256 color++;
2257
2258 color->Name = reg_name(I->Idx, n_color, "radon");
2259 color->Color[0] = 0.258823529F;
2260 color->Color[1] = 0.509803922F;
2261 color->Color[2] = 0.588235294F;
2262 n_color++;
2263 color++;
2264
2265 color->Name = reg_name(I->Idx, n_color, "francium");
2266 color->Color[0] = 0.258823529F;
2267 color->Color[1] = 0.000000000F;
2268 color->Color[2] = 0.400000000F;
2269 n_color++;
2270 color++;
2271
2272 color->Name = reg_name(I->Idx, n_color, "radium");
2273 color->Color[0] = 0.000000000F;
2274 color->Color[1] = 0.490196078F;
2275 color->Color[2] = 0.000000000F;
2276 n_color++;
2277 color++;
2278
2279 color->Name = reg_name(I->Idx, n_color, "actinium");
2280 color->Color[0] = 0.439215686F;
2281 color->Color[1] = 0.670588235F;
2282 color->Color[2] = 0.980392157F;
2283 n_color++;
2284 color++;
2285
2286 color->Name = reg_name(I->Idx, n_color, "thorium");
2287 color->Color[0] = 0.000000000F;
2288 color->Color[1] = 0.729411765F;
2289 color->Color[2] = 1.000000000F;
2290 n_color++;
2291 color++;
2292
2293 color->Name = reg_name(I->Idx, n_color, "protactinium");
2294 color->Color[0] = 0.000000000F;
2295 color->Color[1] = 0.631372549F;
2296 color->Color[2] = 1.000000000F;
2297 n_color++;
2298 color++;
2299
2300 color->Name = reg_name(I->Idx, n_color, "uranium");
2301 color->Color[0] = 0.000000000F;
2302 color->Color[1] = 0.560784314F;
2303 color->Color[2] = 1.000000000F;
2304 n_color++;
2305 color++;
2306
2307 color->Name = reg_name(I->Idx, n_color, "neptunium");
2308 color->Color[0] = 0.000000000F;
2309 color->Color[1] = 0.501960784F;
2310 color->Color[2] = 1.000000000F;
2311 n_color++;
2312 color++;
2313
2314 color->Name = reg_name(I->Idx, n_color, "plutonium");
2315 color->Color[0] = 0.000000000F;
2316 color->Color[1] = 0.419607843F;
2317 color->Color[2] = 1.000000000F;
2318 n_color++;
2319 color++;
2320
2321 color->Name = reg_name(I->Idx, n_color, "americium");
2322 color->Color[0] = 0.329411765F;
2323 color->Color[1] = 0.360784314F;
2324 color->Color[2] = 0.949019608F;
2325 n_color++;
2326 color++;
2327
2328 color->Name = reg_name(I->Idx, n_color, "curium");
2329 color->Color[0] = 0.470588235F;
2330 color->Color[1] = 0.360784314F;
2331 color->Color[2] = 0.890196078F;
2332 n_color++;
2333 color++;
2334
2335 color->Name = reg_name(I->Idx, n_color, "berkelium");
2336 color->Color[0] = 0.541176471F;
2337 color->Color[1] = 0.309803922F;
2338 color->Color[2] = 0.890196078F;
2339 n_color++;
2340 color++;
2341
2342 color->Name = reg_name(I->Idx, n_color, "californium");
2343 color->Color[0] = 0.631372549F;
2344 color->Color[1] = 0.211764706F;
2345 color->Color[2] = 0.831372549F;
2346 n_color++;
2347 color++;
2348
2349 color->Name = reg_name(I->Idx, n_color, "einsteinium");
2350 color->Color[0] = 0.701960784F;
2351 color->Color[1] = 0.121568627F;
2352 color->Color[2] = 0.831372549F;
2353 n_color++;
2354 color++;
2355
2356 color->Name = reg_name(I->Idx, n_color, "fermium");
2357 color->Color[0] = 0.701960784F;
2358 color->Color[1] = 0.121568627F;
2359 color->Color[2] = 0.729411765F;
2360 n_color++;
2361 color++;
2362
2363 color->Name = reg_name(I->Idx, n_color, "mendelevium");
2364 color->Color[0] = 0.701960784F;
2365 color->Color[1] = 0.050980392F;
2366 color->Color[2] = 0.650980392F;
2367 n_color++;
2368 color++;
2369
2370 color->Name = reg_name(I->Idx, n_color, "nobelium");
2371 color->Color[0] = 0.741176471F;
2372 color->Color[1] = 0.050980392F;
2373 color->Color[2] = 0.529411765F;
2374 n_color++;
2375 color++;
2376
2377 color->Name = reg_name(I->Idx, n_color, "lawrencium");
2378 color->Color[0] = 0.780392157F;
2379 color->Color[1] = 0.000000000F;
2380 color->Color[2] = 0.400000000F;
2381 n_color++;
2382 color++;
2383
2384 color->Name = reg_name(I->Idx, n_color, "rutherfordium");
2385 color->Color[0] = 0.800000000F;
2386 color->Color[1] = 0.000000000F;
2387 color->Color[2] = 0.349019608F;
2388 n_color++;
2389 color++;
2390
2391 color->Name = reg_name(I->Idx, n_color, "dubnium");
2392 color->Color[0] = 0.819607843F;
2393 color->Color[1] = 0.000000000F;
2394 color->Color[2] = 0.309803922F;
2395 n_color++;
2396 color++;
2397
2398 color->Name = reg_name(I->Idx, n_color, "seaborgium");
2399 color->Color[0] = 0.850980392F;
2400 color->Color[1] = 0.000000000F;
2401 color->Color[2] = 0.270588235F;
2402 n_color++;
2403 color++;
2404
2405 color->Name = reg_name(I->Idx, n_color, "bohrium");
2406 color->Color[0] = 0.878431373F;
2407 color->Color[1] = 0.000000000F;
2408 color->Color[2] = 0.219607843F;
2409 n_color++;
2410 color++;
2411
2412 color->Name = reg_name(I->Idx, n_color, "hassium");
2413 color->Color[0] = 0.901960784F;
2414 color->Color[1] = 0.000000000F;
2415 color->Color[2] = 0.180392157F;
2416 n_color++;
2417 color++;
2418
2419 color->Name = reg_name(I->Idx, n_color, "meitnerium");
2420 color->Color[0] = 0.921568627F;
2421 color->Color[1] = 0.000000000F;
2422 color->Color[2] = 0.149019608F;
2423 n_color++;
2424 color++;
2425
2426 color->Name = reg_name(I->Idx, n_color, "deuterium");
2427 color->Color[0] = 0.9F;
2428 color->Color[1] = 0.9F;
2429 color->Color[2] = 0.9F;
2430 n_color++;
2431 color++;
2432
2433 color->Name = reg_name(I->Idx, n_color, "lonepair");
2434 color->Color[0] = 0.5F;
2435 color->Color[1] = 0.5F;
2436 color->Color[2] = 0.5F;
2437 n_color++;
2438 color++;
2439
2440 color->Name = reg_name(I->Idx, n_color, "pseudoatom");
2441 color->Color[0] = 0.9F;
2442 color->Color[1] = 0.9F;
2443 color->Color[2] = 0.9F;
2444 n_color++;
2445 color++;
2446
2447 color = I->Color;
2448 for(a = 0; a < n_color; a++) {
2449 /* mark all current colors non-custom so that they don't get saved in session files */
2450 color[a].Custom = false;
2451 }
2452
2453 I->NColor = n_color;
2454 I->NExt = 0;
2455 }
2456
ColorTableLoad(PyMOLGlobals * G,const char * fname,float gamma,int quiet)2457 int ColorTableLoad(PyMOLGlobals * G, const char *fname, float gamma, int quiet)
2458 {
2459 CColor *I = G->Color;
2460 int ok = true;
2461
2462 I->Gamma = gamma;
2463 if(!fname[0]) {
2464 ColorUpdateFromLut(G, -1);
2465 } else {
2466 int width = 512, height = 512;
2467 if(!strcmp(fname, "rgb")) {
2468 if(!I->ColorTable.empty()) {
2469 I->ColorTable.clear();
2470 PRINTFB(G, FB_Color, FB_Actions)
2471 " Color: purged table; restoring RGB colors.\n" ENDFB(G);
2472 }
2473 ColorUpdateFromLut(G, -1);
2474 } else if(!strcmp(fname, "greyscale")) {
2475
2476 int x, y;
2477 unsigned int r = 0, g = 0, b = 0;
2478 unsigned int *pixel, mask, *p;
2479 unsigned int rc;
2480
2481 if(I->BigEndian)
2482 mask = 0x000000FF;
2483 else
2484 mask = 0xFF000000;
2485
2486 I->ColorTable.resize(512 * 512);
2487
2488 p = I->ColorTable.data();
2489 for(x = 0; x < width; x++)
2490 for(y = 0; y < height; y++)
2491 *(p++) = mask;
2492
2493 for(y = 0; y < height; y++)
2494 for(x = 0; x < width; x++) {
2495 rc = (r + g + b)/3;
2496
2497 pixel = I->ColorTable.data() + ((width) * y) + x;
2498 if(I->BigEndian) {
2499 *(pixel) = mask | (rc << 24) | (rc << 16) | (rc << 8);
2500 } else {
2501 *(pixel) = mask | (rc << 16) | (rc << 8) | rc;
2502 }
2503 b = b + 4;
2504 if(!(0xFF & b)) {
2505 b = 0;
2506 g = g + 4;
2507 if(!(0xFF & g)) {
2508 g = 0;
2509 r = r + 4;
2510 }
2511 }
2512 }
2513
2514 if(!quiet) {
2515 PRINTFB(G, FB_Color, FB_Actions)
2516 " Color: defined table '%s'.\n", fname ENDFB(G);
2517 }
2518
2519 ColorUpdateFromLut(G, -1);
2520 ExecutiveInvalidateRep(G, cKeywordAll, cRepAll, cRepInvColor);
2521 SceneChanged(G);
2522
2523
2524 } else if(!strcmp(fname, "pymol")) {
2525
2526 int x, y;
2527 unsigned int r = 0, g = 0, b = 0;
2528 unsigned int *pixel, mask, *p;
2529 unsigned int rc, bc, gc;
2530 unsigned int gf, bf, rf;
2531
2532 float green_max = 0.75F;
2533 float red_max = 0.95F;
2534 float blue_max = 0.97F;
2535
2536 float min_factor = 0.15F;
2537
2538 red_max = SettingGetGlobal_f(G, cSetting_pymol_space_max_red);
2539 green_max = SettingGetGlobal_f(G, cSetting_pymol_space_max_green);
2540 blue_max = SettingGetGlobal_f(G, cSetting_pymol_space_max_blue);
2541 min_factor = SettingGetGlobal_f(G, cSetting_pymol_space_min_factor);
2542
2543 if(I->BigEndian)
2544 mask = 0x000000FF;
2545 else
2546 mask = 0xFF000000;
2547
2548 I->ColorTable.resize(512 * 512);
2549
2550 p = I->ColorTable.data();
2551 for(x = 0; x < width; x++)
2552 for(y = 0; y < height; y++)
2553 *(p++) = mask;
2554
2555 for(y = 0; y < height; y++)
2556 for(x = 0; x < width; x++) {
2557 rc = r;
2558 gc = g;
2559 bc = b;
2560
2561 if((r >= g) && (r >= b)) {
2562 if(rc > 255 * red_max) {
2563 rc = (unsigned int) (red_max * 255);
2564 bc = bc * rc / r;
2565 gc = gc * rc / r;
2566 }
2567 } else if((g >= b) && (g >= r)) {
2568 if(gc > 255 * green_max) {
2569 gc = (unsigned int) (green_max * 255);
2570 bc = bc * gc / g;
2571 rc = rc * gc / g;
2572 }
2573 } else if((b >= g) && (b >= r)) {
2574 if(bc > 255 * blue_max) {
2575 bc = (unsigned int) (blue_max * 255);
2576 gc = gc * bc / b;
2577 rc = rc * bc / b;
2578 }
2579 }
2580
2581 rf = (int) (min_factor * rc + 0.49999F);
2582 gf = (int) (min_factor * gc + 0.49999F);
2583 bf = (int) (min_factor * bc + 0.49999F);
2584
2585 if(rc < gf)
2586 rc = (int) gf;
2587 if(bc < gf)
2588 bc = (int) gf;
2589
2590 if(rc < bf)
2591 rc = (int) bf;
2592 if(gc < bf)
2593 gc = (int) bf;
2594
2595 if(gc < rf)
2596 gc = (int) rf;
2597 if(bc < rf)
2598 bc = (int) rf;
2599
2600 if(rc > 255)
2601 rc = 255;
2602 if(bc > 255)
2603 bc = 255;
2604 if(gc > 255)
2605 gc = 255;
2606
2607 pixel = I->ColorTable.data() + ((width) * y) + x;
2608 if(I->BigEndian) {
2609 *(pixel) = mask | (rc << 24) | (gc << 16) | (bc << 8);
2610 } else {
2611 *(pixel) = mask | (bc << 16) | (gc << 8) | rc;
2612 }
2613 b = b + 4;
2614 if(!(0xFF & b)) {
2615 b = 0;
2616 g = g + 4;
2617 if(!(0xFF & g)) {
2618 g = 0;
2619 r = r + 4;
2620 }
2621 }
2622 }
2623
2624 if(!quiet) {
2625 PRINTFB(G, FB_Color, FB_Actions)
2626 " Color: defined table '%s'.\n", fname ENDFB(G);
2627 }
2628
2629 ColorUpdateFromLut(G, -1);
2630 ExecutiveInvalidateRep(G, cKeywordAll, cRepAll, cRepInvColor);
2631 SceneChanged(G);
2632
2633 } else {
2634 if(strlen(fname)) {
2635
2636 auto image = MyPNGRead(fname);
2637 if(image) {
2638 std::tie(width, height) = image->getSize();
2639 if((width == 512) && (height == 512)) {
2640 auto imageSize = width * height;
2641 I->ColorTable.resize(imageSize);
2642 std::copy(image->pixels(), image->pixels() + imageSize, I->ColorTable.data());
2643
2644 if(!quiet) {
2645 PRINTFB(G, FB_Color, FB_Actions)
2646 " Color: loaded table '%s'.\n", fname ENDFB(G);
2647 }
2648
2649 ColorUpdateFromLut(G, -1);
2650
2651 } else {
2652 PRINTFB(G, FB_Color, FB_Errors)
2653 " ColorTableLoad-Error: invalid dimensions w x h = %d x %d; should be 512 x 512.\n",
2654 width, height ENDFB(G);
2655
2656 ok = false;
2657 }
2658 } else {
2659 PRINTFB(G, FB_Color, FB_Errors)
2660 " ColorTableLoad-Error: unable to load '%s'.\n", fname ENDFB(G);
2661 ok = false;
2662 }
2663 } else {
2664 PRINTFB(G, FB_Color, FB_Actions)
2665 " Color: purged table; colors unchanged.\n" ENDFB(G);
2666 I->ColorTable.clear();
2667 }
2668 }
2669 }
2670 if(ok) {
2671 ExecutiveInvalidateRep(G, cKeywordAll, cRepAll, cRepInvColor);
2672 SceneChanged(G);
2673 }
2674 return (ok);
2675 }
2676
lookup_color(CColor * I,const float * in,float * out,int big_endian)2677 static void lookup_color(CColor * I, const float *in, float *out, int big_endian)
2678 {
2679 const float _1 = 1.0F;
2680 unsigned int *table = I->ColorTable.data();
2681 if(table) {
2682 unsigned int r, g, b, rr, gr, br;
2683 unsigned int ra, ga, ba;
2684 unsigned int rc[2][2][2], gc[2][2][2], bc[2][2][2];
2685 unsigned int *entry;
2686 int x, y, z;
2687 float fr, fg, fb, frm1x, fgm1, fbm1, rct, gct, bct;
2688 const float _2 = 2.0F, _0 = 0.0F, _05 = 0.5F, _04999 = 0.4999F;
2689 const float inv255 = 1.0F / 255.0F;
2690
2691 r = ((int) (255 * in[0] + _05)) & 0xFF;
2692 g = ((int) (255 * in[1] + _05)) & 0xFF;
2693 b = ((int) (255 * in[2] + _05)) & 0xFF;
2694
2695 rr = r & 0x3;
2696 gr = g & 0x3;
2697 br = b & 0x3;
2698
2699 r = (r >> 2);
2700 g = (g >> 2);
2701 b = (b >> 2);
2702
2703 /* now for a crude little trilinear */
2704
2705 for(x = 0; x < 2; x++) {
2706 ra = r + x;
2707 if(ra > 63)
2708 ra = 63;
2709 for(y = 0; y < 2; y++) {
2710 ga = g + y;
2711 if(ga > 63)
2712 ga = 63;
2713 for(z = 0; z < 2; z++) {
2714 ba = b + z;
2715 if(ba > 63)
2716 ba = 63;
2717
2718 entry = table + (ra << 12) + (ga << 6) + ba;
2719
2720 if(big_endian) {
2721 rc[x][y][z] = 0xFF & ((*entry) >> 24);
2722 gc[x][y][z] = 0xFF & ((*entry) >> 16);
2723 bc[x][y][z] = 0xFF & ((*entry) >> 8);
2724 } else {
2725 rc[x][y][z] = 0xFF & ((*entry));
2726 gc[x][y][z] = 0xFF & ((*entry) >> 8);
2727 bc[x][y][z] = 0xFF & ((*entry) >> 16);
2728 }
2729 }
2730 }
2731 }
2732
2733 frm1x = rr / 4.0F;
2734 fgm1 = gr / 4.0F;
2735 fbm1 = br / 4.0F;
2736
2737 fr = 1.0F - frm1x;
2738 fg = 1.0F - fgm1;
2739 fb = 1.0F - fbm1;
2740
2741 rct = _04999 +
2742 (fr * fg * fb * rc[0][0][0]) +
2743 (frm1x * fg * fb * rc[1][0][0]) +
2744 (fr * fgm1 * fb * rc[0][1][0]) +
2745 (fr * fg * fbm1 * rc[0][0][1]) +
2746 (frm1x * fgm1 * fb * rc[1][1][0]) +
2747 (fr * fgm1 * fbm1 * rc[0][1][1]) +
2748 (frm1x * fg * fbm1 * rc[1][0][1]) + (frm1x * fgm1 * fbm1 * rc[1][1][1]);
2749
2750 gct = _04999 +
2751 (fr * fg * fb * gc[0][0][0]) +
2752 (frm1x * fg * fb * gc[1][0][0]) +
2753 (fr * fgm1 * fb * gc[0][1][0]) +
2754 (fr * fg * fbm1 * gc[0][0][1]) +
2755 (frm1x * fgm1 * fb * gc[1][1][0]) +
2756 (fr * fgm1 * fbm1 * gc[0][1][1]) +
2757 (frm1x * fg * fbm1 * gc[1][0][1]) + (frm1x * fgm1 * fbm1 * gc[1][1][1]);
2758
2759 bct = _04999 +
2760 (fr * fg * fb * bc[0][0][0]) +
2761 (frm1x * fg * fb * bc[1][0][0]) +
2762 (fr * fgm1 * fb * bc[0][1][0]) +
2763 (fr * fg * fbm1 * bc[0][0][1]) +
2764 (frm1x * fgm1 * fb * bc[1][1][0]) +
2765 (fr * fgm1 * fbm1 * bc[0][1][1]) +
2766 (frm1x * fg * fbm1 * bc[1][0][1]) + (frm1x * fgm1 * fbm1 * bc[1][1][1]);
2767
2768 if(r >= 63)
2769 rct += rr;
2770 if(g >= 63)
2771 gct += gr;
2772 if(b >= 63)
2773 bct += br;
2774
2775 if(rct <= _2)
2776 rct = _0; /* make sure black is black */
2777 if(gct <= _2)
2778 gct = _0;
2779 if(bct <= _2)
2780 bct = _0;
2781
2782 out[0] = rct * inv255;
2783 out[1] = gct * inv255;
2784 out[2] = bct * inv255;
2785 } else {
2786 out[0] = in[0];
2787 out[1] = in[1];
2788 out[2] = in[2];
2789 }
2790
2791 if((I->Gamma != 1.0F) && (I->Gamma > R_SMALL4)) {
2792 float inv_gamma = 1.0F / I->Gamma;
2793 float inp = (out[0] + out[1] + out[2]) * (1 / 3.0F);
2794 if(inp >= R_SMALL4) {
2795 float sig = (float) (pow(inp, inv_gamma)) / inp;
2796 out[0] *= sig;
2797 out[1] *= sig;
2798 out[2] *= sig;
2799 }
2800 }
2801
2802 if(out[0] > _1)
2803 out[0] = _1;
2804 if(out[1] > _1)
2805 out[1] = _1;
2806 if(out[2] > _1)
2807 out[2] = _1;
2808
2809 }
2810
2811
2812 /*========================================================================*/
ColorUpdateFromLut(PyMOLGlobals * G,int index)2813 void ColorUpdateFromLut(PyMOLGlobals * G, int index)
2814 {
2815 int i;
2816 int once = false;
2817 CColor *I = G->Color;
2818 float *color, *new_color;
2819
2820 I->LUTActive = (!I->ColorTable.empty() || (I->Gamma != 1.0F));
2821
2822 i = index;
2823 if(index >= 0) {
2824 once = true;
2825 }
2826 for(i = 0; i < I->NColor; i++) {
2827 if(!once)
2828 index = i;
2829
2830 if(index < I->NColor) {
2831 if(!I->LUTActive) {
2832 I->Color[index].LutColorFlag = false;
2833 } else if(!I->Color[index].Fixed) {
2834 color = I->Color[index].Color;
2835 new_color = I->Color[index].LutColor;
2836 lookup_color(I, color, new_color, I->BigEndian);
2837
2838 PRINTFD(G, FB_Color)
2839 "%5.3f %5.3f %5.3f -> %5.3f %5.3f %5.3f\n",
2840 color[0], color[1], color[2], new_color[0], new_color[1], new_color[2]
2841 ENDFD;
2842
2843 I->Color[index].LutColorFlag = true;
2844 }
2845 }
2846
2847 if(once)
2848 break;
2849 }
2850 }
2851
2852
2853 /*========================================================================*/
ColorLookupColor(PyMOLGlobals * G,float * color)2854 int ColorLookupColor(PyMOLGlobals * G, float *color)
2855 {
2856 CColor *I = G->Color;
2857 if(I->LUTActive) {
2858 lookup_color(I, color, color, I->BigEndian);
2859 return true;
2860 } else {
2861 return false;
2862 }
2863 }
2864
2865
2866 /*========================================================================*/
ColorInit(PyMOLGlobals * G)2867 int ColorInit(PyMOLGlobals * G)
2868 {
2869 CColor *I = NULL;
2870
2871 if ((G->Color = new CColor())) {
2872 I = G->Color;
2873 unsigned int test;
2874 unsigned char *testPtr;
2875
2876 test = 0xFF000000;
2877 testPtr = (unsigned char *) &test;
2878 I->BigEndian = (*testPtr) & 0x01;
2879
2880 I->Color = VLACalloc(ColorRec, 5500);
2881 I->Ext = VLACalloc(ExtRec, 2);
2882
2883 ColorReset(G); /* will alloc I->Idx and I->Lex */
2884 return 1;
2885 } else {
2886 return 0;
2887 }
2888 }
2889
ColorUpdateFront(PyMOLGlobals * G,const float * back)2890 void ColorUpdateFront(PyMOLGlobals * G, const float *back)
2891 {
2892 CColor *I = G->Color;
2893 copy3f(back, I->Back);
2894 I->Front[0] = 1.0F - back[0];
2895 I->Front[1] = 1.0F - back[1];
2896 I->Front[2] = 1.0F - back[2];
2897 if(diff3f(I->Front, back) < 0.5F)
2898 zero3f(I->Front);
2899 }
2900
ColorUpdateFrontFromSettings(PyMOLGlobals * G)2901 void ColorUpdateFrontFromSettings(PyMOLGlobals * G){
2902 int bg_gradient = SettingGet_b(G, NULL, NULL, cSetting_bg_gradient);
2903 const char * bg_image_filename = SettingGet_s(G, NULL, NULL, cSetting_bg_image_filename);
2904 short bg_image = bg_image_filename && bg_image_filename[0];
2905
2906 if (!bg_gradient){
2907 if (!bg_image && !OrthoBackgroundDataIsSet(*G->Ortho)){
2908 const float *v = ColorGet(G, SettingGet_color(G, NULL, NULL, cSetting_bg_rgb));
2909 ColorUpdateFront(G, v);
2910 } else {
2911 float v[] = { 0.f, 0.f, 0.f };
2912 ColorUpdateFront(G, v);
2913 }
2914 } else {
2915 float vv[3];
2916 const float *v = ColorGet(G, SettingGet_color(G, NULL, NULL, cSetting_bg_rgb_bottom));
2917 const float *vb = ColorGet(G, SettingGet_color(G, NULL, NULL, cSetting_bg_rgb_top));
2918 average3f(v, vb, vv);
2919 ColorUpdateFront(G, vv);
2920 }
2921 }
2922
2923
2924 /*========================================================================*/
ColorGetSpecial(PyMOLGlobals * G,int index)2925 const float *ColorGetSpecial(PyMOLGlobals * G, int index)
2926 {
2927 if(index >= 0)
2928 return ColorGet(G, index);
2929 else {
2930 CColor *I = G->Color;
2931 I->RGBColor[0] = (float) index;
2932 I->RGBColor[1] = -1.0F;
2933 I->RGBColor[2] = -1.0F;
2934 return I->RGBColor;
2935 }
2936 }
2937
ColorGet(PyMOLGlobals * G,int index)2938 const float *ColorGet(PyMOLGlobals * G, int index)
2939 {
2940 CColor *I = G->Color;
2941 const float *ptr;
2942 if((index >= 0) && (index < I->NColor)) {
2943 if(I->Color[index].LutColorFlag && SettingGetGlobal_b(G, cSetting_clamp_colors))
2944 ptr = I->Color[index].LutColor;
2945 else
2946 ptr = I->Color[index].Color;
2947 return (ptr);
2948 } else if((index & cColor_TRGB_Mask) == cColor_TRGB_Bits) { /* a 24-bit RGB color */
2949 I->RGBColor[0] = ((index & 0x00FF0000) >> 16) / 255.0F;
2950 I->RGBColor[1] = ((index & 0x0000FF00) >> 8) / 255.0F;
2951 I->RGBColor[2] = ((index & 0x000000FF)) / 255.0F;
2952 if(I->LUTActive)
2953 lookup_color(I, I->RGBColor, I->RGBColor, I->BigEndian);
2954 return I->RGBColor;
2955 } else if(index == cColorFront) {
2956 return I->Front;
2957 } else if(index == cColorBack) {
2958 return I->Back;
2959 } else {
2960 /* invalid color id, then simply return white */
2961 return (I->Color[0].Color);
2962 }
2963 }
2964
ColorGetRaw(PyMOLGlobals * G,int index)2965 const float *ColorGetRaw(PyMOLGlobals * G, int index)
2966 {
2967 CColor *I = G->Color;
2968 const float *ptr;
2969 if((index >= 0) && (index < I->NColor)) {
2970 ptr = I->Color[index].Color;
2971 return (ptr);
2972 } else if((index & cColor_TRGB_Mask) == cColor_TRGB_Bits) { /* a 24-bit RGB color */
2973 I->RGBColor[0] = ((index & 0x00FF0000) >> 16) / 255.0F;
2974 I->RGBColor[1] = ((index & 0x0000FF00) >> 8) / 255.0F;
2975 I->RGBColor[2] = ((index & 0x000000FF)) / 255.0F;
2976 return I->RGBColor;
2977 } else {
2978 /* invalid color id, then simply return white */
2979 return (I->Color[0].Color);
2980 }
2981 }
2982
ColorGetEncoded(PyMOLGlobals * G,int index,float * color)2983 int ColorGetEncoded(PyMOLGlobals * G, int index, float *color)
2984 {
2985 CColor *I = G->Color;
2986 float *ptr;
2987 if((index >= 0) && (index < I->NColor)) {
2988 if(I->Color[index].LutColorFlag && SettingGetGlobal_b(G, cSetting_clamp_colors))
2989 ptr = I->Color[index].LutColor;
2990 else
2991 ptr = I->Color[index].Color;
2992 copy3f(ptr, color);
2993 } else if((index & cColor_TRGB_Mask) == cColor_TRGB_Bits) { /* a 24-bit RGB color */
2994 float rgb_color[3];
2995 rgb_color[0] = ((index & 0x00FF0000) >> 16) / 255.0F;
2996 rgb_color[1] = ((index & 0x0000FF00) >> 8) / 255.0F;
2997 rgb_color[2] = ((index & 0x000000FF)) / 255.0F;
2998 if(I->LUTActive)
2999 lookup_color(I, rgb_color, rgb_color, I->BigEndian);
3000 copy3f(rgb_color, color);
3001 } else if(index <= cColorExtCutoff) {
3002 color[0] = (float) index;
3003 color[1] = 0.0F;
3004 color[2] = 0.0F;
3005 } else if(index == cColorFront) {
3006 copy3f(I->Front, color);
3007 } else if(index == cColorBack) {
3008 copy3f(I->Back, color);
3009 } else {
3010 color[0] = 1.0F;
3011 color[1] = 1.0F;
3012 color[2] = 1.0F;
3013 /* invalid color id, then simply return white */
3014 return 0;
3015 }
3016 return 1;
3017 }
3018
Color3fToInt(PyMOLGlobals * G,const float * rgb)3019 int Color3fToInt(PyMOLGlobals * G, const float *rgb){
3020 unsigned int rc, gc, bc;
3021 rc = pymol_roundf(rgb[0] * 255.);
3022 gc = pymol_roundf(rgb[1] * 255.);
3023 bc = pymol_roundf(rgb[2] * 255.);
3024 return ( ( cColor_TRGB_Bits & 0xFF000000) |
3025 ( ( rc << 16 ) & 0x00FF0000) |
3026 ( ( gc << 8 ) & 0x0000FF00) |
3027 ( ( bc & 0x000000FF ) ) );
3028 }
3029