#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include "openaxiom-c-macros.h"
#include "spadcolors.h"
#include "XSpadFill.h"
#include "XShade.h"
#include "XDither.h"
extern unsigned long *spadColors;
static GC stippleGC, solidGC;
Colormap cmap;
int SpadFillInit = 0;
long white, black;
int max_spad_shades;
extern Display *dsply;
extern int totalHues;
extern int totalDithered;
extern int totalSolid;
extern int totalShades;
extern int totalColors;
extern int maxGreyShade;
int
XInitSpadFill(Display *dsply, int scr, Colormap * mapOfColors, int * hues,
int *solid, int * dithered, int * shades)
{
XColor BlackColor, WhiteColor;
XColor retColor;
int maxSolid;
SpadFillInit = 1;
stippleGC = XCreateGC(dsply, RootWindow(dsply, scr), 0, NULL);
solidGC = XCreateGC(dsply, RootWindow(dsply, scr), 0, NULL);
XSetArcMode(dsply, solidGC, ArcPieSlice);
XSetArcMode(dsply, stippleGC, ArcPieSlice);
cmap = DefaultColormap(dsply, scr);
*mapOfColors = cmap;
XAllocNamedColor(dsply, cmap, "Black", &BlackColor, &retColor);
XAllocNamedColor(dsply, cmap, "White", &WhiteColor, &retColor);
black = BlackColor.pixel;
white = WhiteColor.pixel;
if (DisplayPlanes(dsply, scr) < 8) {
*dithered = totalDithered = maxGreyShade = XInitShades(dsply, scr);
spadColors = (unsigned long *) malloc(2 * sizeof(unsigned long));
spadColors[0] = BlackColor.pixel;
spadColors[1] = WhiteColor.pixel;
*hues = totalHues = 1;
*solid = totalSolid = 2;
*shades = totalColors = totalShades = totalDithered;
return (totalColors);
}
*dithered = totalDithered =
XInitDither(dsply, scr, stippleGC, black, white);
if ((maxSolid = makeColors(dsply, scr, &cmap, &spadColors, &totalSolid)) > 0) {
*solid = totalSolid + 2;
*hues = totalHues = maxSolid / totalSolid;
*shades = totalShades = (totalSolid + 1) * (totalDithered - 1) + 1;
totalColors = totalHues * totalShades;
return (totalColors);
}
else {
*dithered = totalDithered = maxGreyShade = XInitShades(dsply, scr);
spadColors = (unsigned long *) malloc(2 * sizeof(unsigned long));
spadColors[0] = BlackColor.pixel;
spadColors[1] = WhiteColor.pixel;
*hues = totalHues = 1;
*solid = totalSolid = 2;
*shades = totalColors = totalShades = totalDithered;
return (totalColors);
}
}
void
XSpadFillSetArcMode(Display *dsply, int mode)
{
XSetArcMode(dsply, solidGC, mode);
XSetArcMode(dsply, stippleGC, mode);
}
GC
SpadFillGC(Display *dsply,int hue, int theshade, const char* fill_routine)
{
int dither;
int color;
if (!SpadFillInit) {
fprintf(stderr, "Tried to use SpadFillGC before calling XInitSpadFill\n");
exit(0);
}
if (theshade >= totalShades) {
fprintf(stderr, "Shade %d out of range\n",theshade);
exit(-1);
}
if (hue >= totalHues) {
fprintf(stderr, "Error Hue %d is out of range\n",hue);
exit(-1);
}
dither = ((theshade) % (totalDithered - 1));
if (dither != 0) {
XChangeDither(dsply, stippleGC, dither);
if (theshade < totalDithered) {
color = totalSolid * hue;
XSetForeground(dsply, stippleGC, black);
XSetBackground(dsply, stippleGC, spadColors[color]);
}
else if (theshade > (totalShades - totalDithered)) {
color = ((theshade) / (totalDithered - 1)) + totalSolid * hue - 1;
XSetForeground(dsply, stippleGC, spadColors[color]);
XSetBackground(dsply, stippleGC, white);
}
else {
color = ((theshade) / (totalDithered - 1)) + totalSolid * hue - 1;
XSetForeground(dsply, stippleGC, spadColors[color]);
XSetBackground(dsply, stippleGC, spadColors[color + 1]);
}
return (stippleGC);
}
else {
if (theshade == 0)
XSetForeground(dsply, solidGC, black);
else if (theshade == (totalShades - 1))
XSetForeground(dsply, solidGC, white);
else {
color = ((theshade) / (totalDithered - 1)) + totalSolid * hue - 1;
XSetForeground(dsply, solidGC, spadColors[color]);
}
return (solidGC);
}
}
unsigned long
XSolidColor(int hue, int theshade)
{
if (hue >= totalHues)
return -1;
if (theshade >= totalSolid)
return -1;
return (spadColors[hue * (totalSolid) + theshade]);
}
void
XSpadFillRectangle(Display *dsply, Drawable drawable, int x, int y,
unsigned int width, unsigned int height,
int hue, int theshade)
{
XFillRectangle(dsply, drawable,
SpadFillGC(dsply, hue, theshade, "XSpadFillRectangle"),
x, y, width, height);
}
void
XSpadFillRectangles(Display *dsply, Drawable drawable,
XRectangle * rectangles, int nrectangles,
int hue, int theshade)
{
XFillRectangles(dsply, drawable,
SpadFillGC(dsply, hue, theshade, "XSpadFillRectangle"),
rectangles, nrectangles);
}
void
XSpadFillPolygon(Display *dsply, Drawable drawable, XPoint * points,
int npoints, int shape, int mode, int hue, int theshade)
{
XFillPolygon(dsply, drawable,
SpadFillGC(dsply, hue, theshade, "XSpadFillRectangle"),
points, npoints, shape, mode);
}
void
XSpadFillArc(Display *dsply, Drawable drawable, int x, int y,
unsigned int width, unsigned int height,
int angle1, int angle2, int hue, int theshade)
{
XFillArc(dsply, drawable,
SpadFillGC(dsply, hue, theshade, "XSpadFillRectangle"),
x, y, width, height, angle1, angle2);
}
void
XSpadFillArcs(Display *dsply, Drawable drawable,XArc *arcs, int narcs,
int hue, int theshade)
{
XFillArcs(dsply, drawable,
SpadFillGC(dsply, hue, theshade, "XSpadFillArcs"),
arcs, narcs);
}