Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

open-axiom repository from github

24005 views
1
/*
2
Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
3
All rights reserved.
4
Copyright (C) 2007-2010, Gabriel Dos Reis.
5
All rights reserved.
6
7
Redistribution and use in source and binary forms, with or without
8
modification, are permitted provided that the following conditions are
9
met:
10
11
- Redistributions of source code must retain the above copyright
12
notice, this list of conditions and the following disclaimer.
13
14
- Redistributions in binary form must reproduce the above copyright
15
notice, this list of conditions and the following disclaimer in
16
the documentation and/or other materials provided with the
17
distribution.
18
19
- Neither the name of The Numerical ALgorithms Group Ltd. nor the
20
names of its contributors may be used to endorse or promote products
21
derived from this software without specific prior written permission.
22
23
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
24
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
26
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
27
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
*/
35
36
#include "openaxiom-c-macros.h"
37
#include "spadcolors.h"
38
39
#include <X11/Xlib.h>
40
#include <stdio.h>
41
#include <stdlib.h>
42
#include <math.h>
43
44
#include "spadcolors.h"
45
#include "util.H1"
46
47
#if 0
48
int colors[100];
49
#endif
50
51
static unsigned long pixels[smoothConst+1];
52
53
54
/*
55
* make sure you define a global variable like int *spadColors; in the main
56
* program
57
*/
58
59
/*
60
* code taken from Foley and Van Dam "Fundamentals of Interactive Computer
61
* Graphics"
62
*/
63
64
65
66
RGB
67
HSVtoRGB(HSV hsv)
68
{
69
RGB rgb;
70
float h, f, p, q, t;
71
int i;
72
73
rgb.r = 0.0;
74
rgb.g = 0.0;
75
rgb.b = 0.0;
76
if (hsv.s == 0.0) {
77
rgb.r = rgb.g = rgb.b = hsv.v;
78
return (rgb);
79
}
80
else {
81
if (hsv.h == 360.0) {
82
hsv.h = 0.0;
83
}
84
h = hsv.h / 60;
85
i = floor(h);
86
f = h - i;
87
p = hsv.v * (1 - hsv.s);
88
q = hsv.v * (1 - (hsv.s * f));
89
t = hsv.v * (1 - (hsv.s * (1 - f)));
90
switch (i) {
91
case 0:
92
rgb.r = hsv.v;
93
rgb.g = t;
94
rgb.b = p;
95
break;
96
case 1:
97
rgb.r = q;
98
rgb.g = hsv.v;
99
rgb.b = p;
100
break;
101
case 2:
102
rgb.r = p;
103
rgb.g = hsv.v;
104
rgb.b = t;
105
break;
106
case 3:
107
rgb.r = p;
108
rgb.g = q;
109
rgb.b = hsv.v;
110
break;
111
case 4:
112
rgb.r = t;
113
rgb.g = p;
114
rgb.b = hsv.v;
115
break;
116
case 5:
117
rgb.r = hsv.v;
118
rgb.g = p;
119
rgb.b = q;
120
break;
121
}
122
return (rgb);
123
}
124
}
125
126
float
127
value(float n1, float n2, float hue)
128
{
129
float v;
130
131
if (hue > 360.0)
132
hue -= 360.0;
133
if (hue < 0.0)
134
hue += 360.0;
135
if (hue < 60.0) {
136
v = n1 + (n2 - n1) * hue / 60.0;
137
}
138
else {
139
if (hue < 180.0)
140
v = n2;
141
else {
142
if (hue < 240.0)
143
v = n1 + (n2 - n1) * (240.0 - hue) / 60.0;
144
else
145
v = n1;
146
}
147
}
148
return (v);
149
}
150
151
152
153
RGB
154
HLStoRGB(HLS hls)
155
{
156
RGB rgb;
157
float m1, m2;
158
159
if (hls.l <= 0.5) {
160
m2 = hls.l * (1.0 + hls.s);
161
}
162
else {
163
m2 = hls.l + hls.s - hls.l * hls.s;
164
}
165
m1 = 2.0 * hls.l - m2;
166
rgb.r = value(m1, m2, hls.h + 120.0);
167
rgb.g = value(m1, m2, hls.h);
168
rgb.b = value(m1, m2, hls.h - 120.0);
169
170
return (rgb);
171
}
172
173
174
/******************************************************
175
* int makeColors(dsply,scrn,colorMap,total_Shades) *
176
* *
177
* This routine tries to allocate an adequate color *
178
* map to be used by all the OpenAxiom applications *
179
* that are to be run under X Windows that use *
180
* colors that may be user-definable (e.g. viewports, *
181
* HyperTeX, etc). All these application should call *
182
* this routine and then access the colors with the *
183
* the returned color map. *
184
* For example, the following creates the map and *
185
* then sets the foreground color for a GC: *
186
* *
187
* i = makeColors(d,s,&cmap,&spadColors,&ts); *
188
* XSetForegroundColor(d,gc,spadColors[3]); *
189
* *
190
* where *
191
* spadColors is of type (unsigned long *) *
192
* i (the return value) is the total number of colors *
193
* allocated. *
194
* ts is the total number of shades for each hue *
195
* *
196
* KF 6/14/90 (modification) *
197
* makeColors creates color table once only. *
198
* hiya is of type static. *
199
******************************************************/
200
201
int
202
makeColors(Display *dsply, int scrn, Colormap *colorMap,
203
unsigned long **colorIndex, int *total_Shades)
204
{
205
206
int h, s;
207
static unsigned long *hiya; /* keep colortable around for next time */
208
HSV hsv;
209
RGB rgb;
210
XColor color;
211
int okay = yes; /* is true (1) so long as XAllocColor is
212
* working ok. if 0, then we ran out of room
213
* on the color table. */
214
int colorNum;
215
216
/* shade5 definition */
217
218
static float saturations[5] = {0.90, 0.80, 0.74, 0.50, 0.18};
219
static float values[5] = {0.38, 0.58, 0.75, 0.88, 0.94};
220
221
/* static float values[5] = {0.34, 0.52, 0.80, 0.88, 0.94}; */
222
223
/* fprintf(stderr,"makeColors called\n");*/
224
225
/* printf("making new colors....\n"); */
226
*total_Shades = totalShadesConst;
227
228
/* space for color table */
229
hiya = (unsigned long *) saymem("spadcolors30.c", totalHuesConst * (*total_Shades) + 2, sizeof(unsigned long));
230
*colorIndex = hiya;
231
232
for (h = 0, colorNum = 0; okay && h < 60; h += (hueStep - 6)) {
233
for (s = 0; okay && s < *total_Shades; s++) {
234
hsv.h = h;
235
hsv.s = saturations[s];
236
hsv.v = values[s];
237
rgb = HSVtoRGB(hsv);
238
color.red = rgb.r *((1<<16)-1);
239
color.green = rgb.g *((1<<16)-1);
240
color.blue = rgb.b *((1<<16)-1);
241
color.flags = DoRed | DoGreen | DoBlue;
242
/*
243
fprintf(stderr,"%f\t%f\t%f\n",rgb.r,rgb.g,rgb.b);
244
fprintf(stderr,"%d\t%d\t%d\n",color.red,color.green,color.blue);
245
*/
246
if ((okay = XAllocColor(dsply, *colorMap, &color)))
247
hiya[colorNum++] = color.pixel; /* hiya points to table */
248
} /* for s */
249
} /* for h */
250
for (h = 60; okay && h < 180; h += 20) {
251
for (s = 0; okay && s < *total_Shades; s++) {
252
hsv.h = h;
253
hsv.s = saturations[s];
254
hsv.v = values[s];
255
rgb = HSVtoRGB(hsv);
256
257
color.red = rgb.r *((1<<16)-1);
258
color.green = rgb.g *((1<<16)-1);
259
color.blue = rgb.b *((1<<16)-1);
260
color.flags = DoRed | DoGreen | DoBlue;
261
/*
262
fprintf(stderr,"%f\t%f\t%f\n",rgb.r,rgb.g,rgb.b);
263
fprintf(stderr,"%d\t%d\t%d\n",color.red,color.green,color.blue);
264
*/
265
266
if ((okay = XAllocColor(dsply, *colorMap, &color)))
267
hiya[colorNum++] = color.pixel;
268
}
269
}
270
271
for (h = 180; okay && h <= 300; h += hueStep) {
272
for (s = 0; okay && s < *total_Shades; s++) {
273
hsv.h = h;
274
hsv.s = saturations[s];
275
hsv.v = values[s];
276
rgb = HSVtoRGB(hsv);
277
278
color.red = rgb.r *((1<<16)-1);
279
color.green = rgb.g *((1<<16)-1);
280
color.blue = rgb.b *((1<<16)-1);
281
color.flags = DoRed | DoGreen | DoBlue;
282
/*
283
fprintf(stderr,"%f\t%f\t%f\n",rgb.r,rgb.g,rgb.b);
284
fprintf(stderr,"%d\t%d\t%d\n",color.red,color.green,color.blue);
285
*/
286
if ((okay = XAllocColor(dsply, *colorMap, &color)))
287
hiya[colorNum++] = color.pixel;
288
}
289
}
290
291
hiya[colorNum++] = BlackPixel(dsply, scrn);
292
hiya[colorNum++] = WhitePixel(dsply, scrn);
293
294
if (colorNum < (totalShadesConst * totalHuesConst + 2)) {
295
free(*colorIndex);
296
fprintf(stderr,
297
" > Warning: cannot allocate all the necessary colors - switching to monochrome mode\n");
298
*colorIndex = (unsigned long *) saymem("while allocating the colormap for OpenAxiom ", 2, sizeof(unsigned long));
299
(*colorIndex)[0] = BlackPixel(dsply, scrn);
300
(*colorIndex)[1] = WhitePixel(dsply, scrn);
301
return (-1);
302
}
303
304
return (colorNum);
305
}
306
307
#ifdef OLD
308
/***********************************************************************
309
KF 6/14/90
310
INPUT: display dsply, screen scrn
311
OUTPUT: a pointer to the permutation color vector (permIndex)
312
PURPOSE: when called for the first time, this procedure creates a
313
permutation vector of the color table spadColor. It
314
returns the pointer to this vector for subsequent calls.
315
316
***********************************************************************/
317
318
int
319
makePermVector(Display *dsply, int scrn, unsigned long **permIndex)
320
{
321
static int firstTime = yes;
322
unsigned long *spadColorsToo;
323
static unsigned long *pIndex;
324
Colormap cmap;
325
int num_colors;
326
int i, ts;
327
328
if (firstTime) {
329
330
/* initialization */
331
332
cmap = DefaultColormap(dsply, scrn); /* what are other cmaps?? */
333
pIndex = (unsigned long *) saymem("makePermVector", Colorcells, sizeof(unsigned long));
334
335
/* get spadColors table */
336
337
if ((num_colors = makeColors(dsply, scrn, &cmap, &spadColorsToo, &ts)) < 0) {
338
printf("num_colors < 0!!\n");
339
exit(-1);
340
}
341
342
/* initialize unused slots in permutation vector */
343
344
for (i = 0; i < spadColorsToo[0]; i++)
345
pIndex[i] = 0;
346
for (i = num_colors; i < Colorcells; i++)
347
pIndex[i] = 0;
348
349
/* make permutation vector */
350
351
for (i = 0; i < num_colors; i++)
352
pIndex[spadColorsToo[i]] = i;
353
354
firstTime = no;
355
}
356
357
*permIndex = pIndex;
358
return (Colorcells);
359
}
360
361
#endif
362
363
/******************************************************
364
* int makeNewColorMap(dsply,colorMap,smoothHue) *
365
* *
366
* This routine tries to allocate an adequate color *
367
* map to be used by the OpenAxiom smooth shading *
368
* application that is to be run under X Windows. *
369
* The colors are allocated from available space in *
370
* the colorMap and returned in the array pixels. *
371
* The size of the array is determined by smoothConst *
372
* which is the number of shades desired. The colors *
373
* returned are variations in lightness of the hue *
374
* smoothHue indicated on the control panel Colormap. *
375
* *
376
* If smoothConst colors can be allocated the value *
377
* 1 is returned, otherwise returns 0 *
378
* *
379
******************************************************/
380
381
382
int
383
makeNewColorMap(Display *dsply, Colormap colorMap, int smoothHue)
384
385
{
386
387
int count, i;
388
float lightness;
389
RGB rgb;
390
XColor xcolor;
391
HLS hls;
392
393
count = 0;
394
for (i = 0; i < (smoothConst + 1); i++) { /* i = 0 .. smoothConst */
395
lightness = (float) (i) / (float) (smoothConst); /* lightnes = 0.0 .. 1.0 */
396
hls.h = (float) smoothHue;
397
hls.l = lightness;
398
hls.s = saturation;
399
rgb = HLStoRGB(hls);
400
401
xcolor.red = rgb.r *((1<<16)-1);
402
xcolor.green = rgb.g *((1<<16)-1);
403
xcolor.blue = rgb.b *((1<<16)-1);
404
xcolor.flags = DoRed | DoGreen | DoBlue;
405
/*
406
fprintf(stderr,"%f\t%f\t%f\n",rgb.r,rgb.g,rgb.b);
407
fprintf(stderr,"%d\t%d\t%d\n",xcolor.red,xcolor.green,xcolor.blue);
408
*/
409
if (XAllocColor(dsply, colorMap, &xcolor)) {
410
pixels[count] = xcolor.pixel;
411
count++;
412
}
413
}
414
/* count says how many succeeded */
415
if (count != (smoothConst+1) ) {
416
417
/* we have failed to get all of them - free the ones we got */
418
419
FreePixels(dsply,colorMap,count);
420
return (0);
421
}
422
return (1);
423
}
424
425
426
427
/******************************************************
428
* unsigned long XPixelColor(num) *
429
* *
430
* XPixelColor is a straight forward function that *
431
* merely returns the XColor value desired within *
432
* the pixels array. For smooth shading, given an *
433
* intensity from 0..1, scaling by the number of *
434
* values in the array will return the location in *
435
* pixels[] of the desired color for that intensity. *
436
* *
437
******************************************************/
438
439
unsigned long
440
XPixelColor(int num)
441
{
442
if (num < 0)
443
num = 0;
444
return (pixels[num]);
445
}
446
447
448
/******************************************************
449
* FreePixels(dsply,colorMap,num) *
450
* *
451
* FreePixels is a call to XFreeColors which frees *
452
* previously allocated colors for the indicated *
453
* colorMap. If it cannot free the number of colors *
454
* given by num a BadAccess error will crash the *
455
* viewport process. This should ONLY be used if *
456
* it can be guaranteed that there will be num colors *
457
* to free in colorMap. return 0 == success *
458
* *
459
******************************************************/
460
461
462
void
463
FreePixels(Display *dsply, Colormap colorMap, int num)
464
{
465
466
XFreeColors(dsply, colorMap, pixels, num, 0);
467
}
468
469
470
471
/******************************************************
472
* int AllocCells(dsply,colorMap,smoothHue) *
473
* *
474
* Use either makeNewColormap() OR AllocCells(). *
475
* This routine tries to allocate an adequate color *
476
* map to be used by the OpenAxiom smooth shading *
477
* application that is to be run under X Windows. *
478
* The colors are allocated from available space in *
479
* the colorMap and returned in the array pixels. *
480
* The size of the array is determined by smoothConst *
481
* which is the number of shades desired. The colors *
482
* returned are variations in lightness of the hue *
483
* smoothHue indicated on the control panel Colormap. *
484
* *
485
* It is different from makeNewColormap() in that *
486
* the cells are read/write, and if it cannot alloc *
487
* all the colors desired it doesn't allocate any. *
488
* *
489
******************************************************/
490
491
492
int
493
AllocCells(Display *dsply, Colormap colorMap, int smoothHue)
494
{
495
unsigned long plane_masks[1];
496
int i, count;
497
float lightness;
498
RGB rgb;
499
XColor xcolor;
500
HLS hls;
501
502
count = 0;
503
for (i = 0; i < (smoothConst + 1); i++) {
504
lightness = (float) (i) / (float) (smoothConst);
505
hls.h = (float) smoothHue;
506
hls.l = lightness;
507
hls.s = saturation;
508
rgb = HLStoRGB(hls);
509
xcolor.red = rgb.r *((1<<16)-1);
510
xcolor.green = rgb.g *((1<<16)-1);
511
xcolor.blue = rgb.b *((1<<16)-1);
512
xcolor.flags = DoRed | DoGreen | DoBlue;
513
/*
514
fprintf(stderr,"%f\t%f\t%f\n",rgb.r,rgb.g,rgb.b);
515
fprintf(stderr,"%d\t%d\t%d\n",xcolor.red,xcolor.green,xcolor.blue);
516
*/
517
if (XAllocColor(dsply, colorMap, &xcolor)) {
518
pixels[count] = xcolor.pixel;
519
count++;
520
}
521
}
522
/* count says how many succeeded */
523
if (count != (smoothConst+1) ) {
524
/* we have failed to get all of them - free the ones we got */
525
FreePixels(dsply,colorMap,count);
526
return (0);
527
}
528
if (XAllocColorCells(dsply, colorMap, False,
529
plane_masks, 0, pixels, smoothConst + 1)) {
530
return (smoothConst + 1);
531
}
532
else {
533
return (0);
534
}
535
}
536
537