aboutsummaryrefslogtreecommitdiff
path: root/src/lib/spadcolors.c
diff options
context:
space:
mode:
authordos-reis <gdr@axiomatics.org>2007-09-02 21:56:58 +0000
committerdos-reis <gdr@axiomatics.org>2007-09-02 21:56:58 +0000
commit7eb38fea596969878a33f30e36fe33b125f9c4bd (patch)
tree2e4222a4406fb5ed3d69b781f528b9ac08bb9fbc /src/lib/spadcolors.c
parent869512ac1dd0bc9c80182cbef6e01b39540fef7f (diff)
downloadopen-axiom-7eb38fea596969878a33f30e36fe33b125f9c4bd.tar.gz
* XSpadFill.c: New. Replace corresponding pamphlet.
* XSpadFill.c.pamphlet: Remove. * XShade.c: New. Replace corresponding pamphlet. * XShade.c.pamphlet: Remove. * XDither.c: New. Replace corresponding pamphlet. * XDither.c.pamphlet: Remove. * wct.c: New. Replace corresponding pamphlet. * wct.c.pamphlet: Remove. * util.c: New. Replace corresponding pamphlet. * util.c.pamphlet: Remove. * spadcolors.c: New. Replace corresponding pamphlet. * spadcolors.c.pamphlet: Remove. * sockio-c.c: New. Replace corresponding pamphlet. * sockio-c.c.pamphlet: Remove. * prt.c: New. Replace corresponding pamphlet. * prt.c.pamphlet: Remove. * pixmap.c: New. Replace corresponding pamphlet. * pixmap.c.pamphlet: Remove. * openpty.c: New. Replace corresponding pamphlet. * openpty.c.pamphlet: Remove. * hash.c: New. Replace corresponding pamphlet. * hash.c.pamphlet: Remove. * halloc.c: New. Replace corresponding pamphlet. * halloc.c.pamphlet: Remove. * fnct_key.c: New. Replace corresponding pamphlet. * fnct_key.c.pamphlet: Remove. * edin.c: New. Replace corresponding pamphlet. * edin.c.pamphlet: Remove. * bsdsignal.c: New. Replace correponding pamphlet. * bsdsignal.c.pamphlet: Remove. * cursor.c: New. Replace corresponding pamphlet. * cursor.c.pamphlet: Remove. * cfuns-c.c: New. Replace corresponding pamphlet. * cfuns-c.c.pamphlet: Remove.
Diffstat (limited to 'src/lib/spadcolors.c')
-rw-r--r--src/lib/spadcolors.c533
1 files changed, 533 insertions, 0 deletions
diff --git a/src/lib/spadcolors.c b/src/lib/spadcolors.c
new file mode 100644
index 00000000..4cd79e09
--- /dev/null
+++ b/src/lib/spadcolors.c
@@ -0,0 +1,533 @@
+/*
+ Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "axiom-c-macros.h"
+#include "spadcolors.h"
+
+#include <X11/Xlib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "spadcolors.H1"
+#include "util.H1"
+
+#if 0
+int colors[100];
+#endif
+
+static unsigned long pixels[smoothConst+1];
+
+
+/*
+ * make sure you define a global variable like int *spadColors; in the main
+ * program
+ */
+
+/*
+ * code taken from Foley and Van Dam "Fundamentals of Interactive Computer
+ * Graphics"
+ */
+
+
+
+RGB
+HSVtoRGB(HSV hsv)
+{
+ RGB rgb;
+ float h, f, p, q, t;
+ int i;
+
+ rgb.r = 0.0;
+ rgb.g = 0.0;
+ rgb.b = 0.0;
+ if (hsv.s == 0.0) {
+ rgb.r = rgb.g = rgb.b = hsv.v;
+ return (rgb);
+ }
+ else {
+ if (hsv.h == 360.0) {
+ hsv.h = 0.0;
+ }
+ h = hsv.h / 60;
+ i = floor(h);
+ f = h - i;
+ p = hsv.v * (1 - hsv.s);
+ q = hsv.v * (1 - (hsv.s * f));
+ t = hsv.v * (1 - (hsv.s * (1 - f)));
+ switch (i) {
+ case 0:
+ rgb.r = hsv.v;
+ rgb.g = t;
+ rgb.b = p;
+ break;
+ case 1:
+ rgb.r = q;
+ rgb.g = hsv.v;
+ rgb.b = p;
+ break;
+ case 2:
+ rgb.r = p;
+ rgb.g = hsv.v;
+ rgb.b = t;
+ break;
+ case 3:
+ rgb.r = p;
+ rgb.g = q;
+ rgb.b = hsv.v;
+ break;
+ case 4:
+ rgb.r = t;
+ rgb.g = p;
+ rgb.b = hsv.v;
+ break;
+ case 5:
+ rgb.r = hsv.v;
+ rgb.g = p;
+ rgb.b = q;
+ break;
+ }
+ return (rgb);
+ }
+}
+
+float
+value(float n1, float n2, float hue)
+{
+ float v;
+
+ if (hue > 360.0)
+ hue -= 360.0;
+ if (hue < 0.0)
+ hue += 360.0;
+ if (hue < 60.0) {
+ v = n1 + (n2 - n1) * hue / 60.0;
+ }
+ else {
+ if (hue < 180.0)
+ v = n2;
+ else {
+ if (hue < 240.0)
+ v = n1 + (n2 - n1) * (240.0 - hue) / 60.0;
+ else
+ v = n1;
+ }
+ }
+ return (v);
+}
+
+
+
+RGB
+HLStoRGB(HLS hls)
+{
+ RGB rgb;
+ float m1, m2;
+
+ if (hls.l <= 0.5) {
+ m2 = hls.l * (1.0 + hls.s);
+ }
+ else {
+ m2 = hls.l + hls.s - hls.l * hls.s;
+ }
+ m1 = 2.0 * hls.l - m2;
+ rgb.r = value(m1, m2, hls.h + 120.0);
+ rgb.g = value(m1, m2, hls.h);
+ rgb.b = value(m1, m2, hls.h - 120.0);
+
+ return (rgb);
+}
+
+
+/******************************************************
+ * int makeColors(dsply,scrn,colorMap,total_Shades) *
+ * *
+ * This routine tries to allocate an adequate color *
+ * map to be used by all the AXIOM applications *
+ * that are to be run under X Windows that use *
+ * colors that may be user-definable (e.g. viewports, *
+ * HyperTeX, etc). All these application should call *
+ * this routine and then access the colors with the *
+ * the returned color map. *
+ * For example, the following creates the map and *
+ * then sets the foreground color for a GC: *
+ * *
+ * i = makeColors(d,s,&cmap,&spadColors,&ts); *
+ * XSetForegroundColor(d,gc,spadColors[3]); *
+ * *
+ * where *
+ * spadColors is of type (unsigned long *) *
+ * i (the return value) is the total number of colors *
+ * allocated. *
+ * ts is the total number of shades for each hue *
+ * *
+ * KF 6/14/90 (modification) *
+ * makeColors creates color table once only. *
+ * hiya is of type static. *
+ ******************************************************/
+
+int
+makeColors(Display *dsply, int scrn, Colormap *colorMap,
+ unsigned long **colorIndex, int *total_Shades)
+{
+
+ int h, s;
+ static unsigned long *hiya; /* keep colortable around for next time */
+ HSV hsv;
+ RGB rgb;
+ XColor color;
+ int okay = yes; /* is true (1) so long as XAllocColor is
+ * working ok. if 0, then we ran out of room
+ * on the color table. */
+ int colorNum;
+
+ /* shade5 definition */
+
+ static float saturations[5] = {0.90, 0.80, 0.74, 0.50, 0.18};
+ static float values[5] = {0.38, 0.58, 0.75, 0.88, 0.94};
+
+ /* static float values[5] = {0.34, 0.52, 0.80, 0.88, 0.94}; */
+
+ /* fprintf(stderr,"makeColors called\n");*/
+
+ /* printf("making new colors....\n"); */
+ *total_Shades = totalShadesConst;
+
+ /* space for color table */
+ hiya = (unsigned long *) saymem("spadcolors30.c", totalHuesConst * (*total_Shades) + 2, sizeof(unsigned long));
+ *colorIndex = hiya;
+
+ for (h = 0, colorNum = 0; okay && h < 60; h += (hueStep - 6)) {
+ for (s = 0; okay && s < *total_Shades; s++) {
+ hsv.h = h;
+ hsv.s = saturations[s];
+ hsv.v = values[s];
+ rgb = HSVtoRGB(hsv);
+ color.red = rgb.r *((1<<16)-1);
+ color.green = rgb.g *((1<<16)-1);
+ color.blue = rgb.b *((1<<16)-1);
+ color.flags = DoRed | DoGreen | DoBlue;
+ /*
+ fprintf(stderr,"%f\t%f\t%f\n",rgb.r,rgb.g,rgb.b);
+ fprintf(stderr,"%d\t%d\t%d\n",color.red,color.green,color.blue);
+ */
+ if ((okay = XAllocColor(dsply, *colorMap, &color)))
+ hiya[colorNum++] = color.pixel; /* hiya points to table */
+ } /* for s */
+ } /* for h */
+ for (h = 60; okay && h < 180; h += 20) {
+ for (s = 0; okay && s < *total_Shades; s++) {
+ hsv.h = h;
+ hsv.s = saturations[s];
+ hsv.v = values[s];
+ rgb = HSVtoRGB(hsv);
+
+ color.red = rgb.r *((1<<16)-1);
+ color.green = rgb.g *((1<<16)-1);
+ color.blue = rgb.b *((1<<16)-1);
+ color.flags = DoRed | DoGreen | DoBlue;
+ /*
+ fprintf(stderr,"%f\t%f\t%f\n",rgb.r,rgb.g,rgb.b);
+ fprintf(stderr,"%d\t%d\t%d\n",color.red,color.green,color.blue);
+ */
+
+ if ((okay = XAllocColor(dsply, *colorMap, &color)))
+ hiya[colorNum++] = color.pixel;
+ }
+ }
+
+ for (h = 180; okay && h <= 300; h += hueStep) {
+ for (s = 0; okay && s < *total_Shades; s++) {
+ hsv.h = h;
+ hsv.s = saturations[s];
+ hsv.v = values[s];
+ rgb = HSVtoRGB(hsv);
+
+ color.red = rgb.r *((1<<16)-1);
+ color.green = rgb.g *((1<<16)-1);
+ color.blue = rgb.b *((1<<16)-1);
+ color.flags = DoRed | DoGreen | DoBlue;
+ /*
+ fprintf(stderr,"%f\t%f\t%f\n",rgb.r,rgb.g,rgb.b);
+ fprintf(stderr,"%d\t%d\t%d\n",color.red,color.green,color.blue);
+ */
+ if ((okay = XAllocColor(dsply, *colorMap, &color)))
+ hiya[colorNum++] = color.pixel;
+ }
+ }
+
+ hiya[colorNum++] = BlackPixel(dsply, scrn);
+ hiya[colorNum++] = WhitePixel(dsply, scrn);
+
+ if (colorNum < (totalShadesConst * totalHuesConst + 2)) {
+ free(*colorIndex);
+ fprintf(stderr,
+ " > Warning: cannot allocate all the necessary colors - switching to monochrome mode\n");
+ *colorIndex = (unsigned long *) saymem("while allocating the colormap for AXIOM ", 2, sizeof(unsigned long));
+ (*colorIndex)[0] = BlackPixel(dsply, scrn);
+ (*colorIndex)[1] = WhitePixel(dsply, scrn);
+ return (-1);
+ }
+
+ return (colorNum);
+}
+
+#ifdef OLD
+/***********************************************************************
+ KF 6/14/90
+ INPUT: display dsply, screen scrn
+ OUTPUT: a pointer to the permutation color vector (permIndex)
+ PURPOSE: when called for the first time, this procedure creates a
+ permutation vector of the color table spadColor. It
+ returns the pointer to this vector for subsequent calls.
+
+***********************************************************************/
+
+int
+makePermVector(Display *dsply, int scrn, unsigned long **permIndex)
+{
+ static int firstTime = yes;
+ unsigned long *spadColorsToo;
+ static unsigned long *pIndex;
+ Colormap cmap;
+ int num_colors;
+ int i, ts;
+
+ if (firstTime) {
+
+ /* initialization */
+
+ cmap = DefaultColormap(dsply, scrn); /* what are other cmaps?? */
+ pIndex = (unsigned long *) saymem("makePermVector", Colorcells, sizeof(unsigned long));
+
+ /* get spadColors table */
+
+ if ((num_colors = makeColors(dsply, scrn, &cmap, &spadColorsToo, &ts)) < 0) {
+ printf("num_colors < 0!!\n");
+ exit(-1);
+ }
+
+ /* initialize unused slots in permutation vector */
+
+ for (i = 0; i < spadColorsToo[0]; i++)
+ pIndex[i] = 0;
+ for (i = num_colors; i < Colorcells; i++)
+ pIndex[i] = 0;
+
+ /* make permutation vector */
+
+ for (i = 0; i < num_colors; i++)
+ pIndex[spadColorsToo[i]] = i;
+
+ firstTime = no;
+ }
+
+ *permIndex = pIndex;
+ return (Colorcells);
+}
+
+#endif
+
+/******************************************************
+ * int makeNewColorMap(dsply,colorMap,smoothHue) *
+ * *
+ * This routine tries to allocate an adequate color *
+ * map to be used by the AXIOM smooth shading *
+ * application that is to be run under X Windows. *
+ * The colors are allocated from available space in *
+ * the colorMap and returned in the array pixels. *
+ * The size of the array is determined by smoothConst *
+ * which is the number of shades desired. The colors *
+ * returned are variations in lightness of the hue *
+ * smoothHue indicated on the control panel Colormap. *
+ * *
+ * If smoothConst colors can be allocated the value *
+ * 1 is returned, otherwise returns 0 *
+ * *
+ ******************************************************/
+
+
+int
+makeNewColorMap(Display *dsply, Colormap colorMap, int smoothHue)
+
+{
+
+ int count, i;
+ float lightness;
+ RGB rgb;
+ XColor xcolor;
+ HLS hls;
+
+ count = 0;
+ for (i = 0; i < (smoothConst + 1); i++) { /* i = 0 .. smoothConst */
+ lightness = (float) (i) / (float) (smoothConst); /* lightnes = 0.0 .. 1.0 */
+ hls.h = (float) smoothHue;
+ hls.l = lightness;
+ hls.s = saturation;
+ rgb = HLStoRGB(hls);
+
+ xcolor.red = rgb.r *((1<<16)-1);
+ xcolor.green = rgb.g *((1<<16)-1);
+ xcolor.blue = rgb.b *((1<<16)-1);
+ xcolor.flags = DoRed | DoGreen | DoBlue;
+ /*
+ fprintf(stderr,"%f\t%f\t%f\n",rgb.r,rgb.g,rgb.b);
+ fprintf(stderr,"%d\t%d\t%d\n",xcolor.red,xcolor.green,xcolor.blue);
+ */
+ if (XAllocColor(dsply, colorMap, &xcolor)) {
+ pixels[count] = xcolor.pixel;
+ count++;
+ }
+ }
+ /* count says how many succeeded */
+ if (count != (smoothConst+1) ) {
+
+ /* we have failed to get all of them - free the ones we got */
+
+ FreePixels(dsply,colorMap,count);
+ return (0);
+ }
+ return (1);
+}
+
+
+
+/******************************************************
+ * unsigned long XPixelColor(num) *
+ * *
+ * XPixelColor is a straight forward function that *
+ * merely returns the XColor value desired within *
+ * the pixels array. For smooth shading, given an *
+ * intensity from 0..1, scaling by the number of *
+ * values in the array will return the location in *
+ * pixels[] of the desired color for that intensity. *
+ * *
+ ******************************************************/
+
+unsigned long
+XPixelColor(int num)
+{
+ if (num < 0)
+ num = 0;
+ return (pixels[num]);
+}
+
+
+/******************************************************
+ * FreePixels(dsply,colorMap,num) *
+ * *
+ * FreePixels is a call to XFreeColors which frees *
+ * previously allocated colors for the indicated *
+ * colorMap. If it cannot free the number of colors *
+ * given by num a BadAccess error will crash the *
+ * viewport process. This should ONLY be used if *
+ * it can be guaranteed that there will be num colors *
+ * to free in colorMap. return 0 == success *
+ * *
+ ******************************************************/
+
+
+void
+FreePixels(Display *dsply, Colormap colorMap, int num)
+{
+
+ XFreeColors(dsply, colorMap, pixels, num, 0);
+}
+
+
+
+/******************************************************
+ * int AllocCells(dsply,colorMap,smoothHue) *
+ * *
+ * Use either makeNewColormap() OR AllocCells(). *
+ * This routine tries to allocate an adequate color *
+ * map to be used by the AXIOM smooth shading *
+ * application that is to be run under X Windows. *
+ * The colors are allocated from available space in *
+ * the colorMap and returned in the array pixels. *
+ * The size of the array is determined by smoothConst *
+ * which is the number of shades desired. The colors *
+ * returned are variations in lightness of the hue *
+ * smoothHue indicated on the control panel Colormap. *
+ * *
+ * It is different from makeNewColormap() in that *
+ * the cells are read/write, and if it cannot alloc *
+ * all the colors desired it doesn't allocate any. *
+ * *
+ ******************************************************/
+
+
+int
+AllocCells(Display *dsply, Colormap colorMap, int smoothHue)
+{
+ unsigned long plane_masks[1];
+ int i, count;
+ float lightness;
+ RGB rgb;
+ XColor xcolor;
+ HLS hls;
+
+ count = 0;
+ for (i = 0; i < (smoothConst + 1); i++) {
+ lightness = (float) (i) / (float) (smoothConst);
+ hls.h = (float) smoothHue;
+ hls.l = lightness;
+ hls.s = saturation;
+ rgb = HLStoRGB(hls);
+ xcolor.red = rgb.r *((1<<16)-1);
+ xcolor.green = rgb.g *((1<<16)-1);
+ xcolor.blue = rgb.b *((1<<16)-1);
+ xcolor.flags = DoRed | DoGreen | DoBlue;
+ /*
+ fprintf(stderr,"%f\t%f\t%f\n",rgb.r,rgb.g,rgb.b);
+ fprintf(stderr,"%d\t%d\t%d\n",xcolor.red,xcolor.green,xcolor.blue);
+ */
+ if (XAllocColor(dsply, colorMap, &xcolor)) {
+ pixels[count] = xcolor.pixel;
+ count++;
+ }
+ }
+ /* count says how many succeeded */
+ if (count != (smoothConst+1) ) {
+ /* we have failed to get all of them - free the ones we got */
+ FreePixels(dsply,colorMap,count);
+ return (0);
+ }
+ if (XAllocColorCells(dsply, colorMap, False,
+ plane_masks, 0, pixels, smoothConst + 1)) {
+ return (smoothConst + 1);
+ }
+ else {
+ return (0);
+ }
+}