This is hplotX11.c in view mode; [Download] [Up]
/* * hippoplotX.c -- Graphics code for producing pure X displays. * * * Author : Tony Johnson * Created On : 8 Feb 1992 * Last Modified By: Tony Johnson * Last Modified On: 8 Feb 1992 * Update Count : * Status : Revision 1 * * Copyright (C) 1991 The Board of Trustees of The Leland Stanford * Junior University. All Rights Reserved. * * $Id: hplotX11.c,v 5.0 1993/08/17 21:56:10 rensing Exp $ */ #include "hplotX11.h" #include <stdio.h> #include <string.h> #include <math.h> GLOB_QUAL const char hippoplotX11_c_rcsid[] = "$Id: hplotX11.c,v 5.0 1993/08/17 21:56:10 rensing Exp $"; GLOB_QUAL const char hippoplotX11_h_rcsid[] = HIPPOPLOTX11_H_RCSID; #define FontName\ "-Adobe-New Century Schoolbook-Bold-R-Normal--*-*-*-*-*-*-*-*" #define MAXFONTS 30 #define MAXCACHE 20 #define min(A,B) ((A>B) ? B : A) /* These are for passing info from Histo class: */ static Display *h_display; static Drawable h_drawable; static GC h_gc; static Font h_font[MAXFONTS]; static XFontStruct *h_fontStruct; static int h_nFonts; static char **h_fontNames; static int h_depth; static int h_color; static Screen *h_screen; static init = 0; /* All scaling info: */ static struct { float x; float y; int xMarg; int yMarg; float xOrig; float yOrig; } Scale, Convert; /* The Data-coords limits: */ static struct { float xmin; float xmax; float ymin; float ymax; } Limit; static void drawStipple2D_X11(int nXBins, int nYBins, float minBin, float maxBin, float bins[]); static void ColorError(); static int XScale(float x) { return (x - Scale.xOrig)*Scale.x + Scale.xMarg; } static int YScale(float y) { return Scale.yMarg - (y - Scale.yOrig)*Scale.y; } static int XConvert(float x) { return (x - Convert.xOrig)*Convert.x + Convert.xMarg; } static int YConvert(float y) { return Convert.yMarg - (y - Convert.yOrig)*Convert.y; } void initPlot_X11(Display *disp, Screen *screen, Drawable drawable, GC gc) { h_display = disp; h_drawable = drawable; h_gc = gc; h_screen = screen; if (!init) { int i; init = 1; h_fontNames = XListFontsWithInfo(disp,FontName,MAXFONTS, &h_nFonts,&h_fontStruct); for (i=0; i<h_nFonts; i++) h_font[i] = 0; } /* Are we in color? */ h_color = (DefaultVisualOfScreen(h_screen)->class == PseudoColor); } static void ColorError() { static Reported = 0; if (Reported++) return; printf("\nXHippo: Unable to allocate required colormap entries\n"); } void setHistoCoords_X11(rectangle *draw, rectangle *margin, rectangle *data) { unsigned int width, height, border; int x,y; Window root; /* Get overall width and height from window. */ XGetGeometry(h_display,h_drawable,&root,&x,&y,&width, &height,&border,&h_depth); /* Remember margin is in points; data is in data coords. */ Convert.x = width/draw->size.width; Convert.y = height/draw->size.height; Convert.xMarg = 0; Convert.yMarg = height; Convert.xOrig = draw->origin.x; Convert.yOrig = draw->origin.y; Scale.x = (Convert.x * margin->size.width)/(data->size.width); Scale.y = (Convert.y * margin->size.height)/(data->size.height); Scale.xMarg = XConvert(margin->origin.x); Scale.yMarg = YConvert(margin->origin.y); Scale.xOrig = data->origin.x; Scale.yOrig = data->origin.y; Limit.xmin = data->origin.x; Limit.xmax = data->size.width + data->origin.x; Limit.ymin = data->origin.y; Limit.ymax = data->size.height + data->origin.y; #ifdef DEBUG printf ("setupX: X scale = %f, Y scale = %f\n", Scale.x, Scale.y); #endif } /* Put the message text at the indicated x-y position (Note, x and y * are in points): */ void drawText_X11(char *message, float x, float y, float fontHeight, float angle, char xalign, char yalign) { int xx = XConvert(x); int yy = YConvert(y); int width, dir, ascent, descent; int length = strlen(message); int i, n, size; double sinA = sin(angle), cosA = cos(angle); XCharStruct overall; /* Decide which font to use */ int fontSize = min(Convert.x , Convert.y) * fontHeight; size = 0; for (i=0; i<h_nFonts; i++) { int h = h_fontStruct[i].ascent + h_fontStruct[i].descent; if (h <= fontSize && h > size) { size = h; n = i; } } if (size == 0) { size = 99999; for (i=0; i<h_nFonts; i++) { int h = h_fontStruct[i].ascent + h_fontStruct[i].descent; if (h < size) { size = h; n = i; } } } if (h_font[n] == 0) { h_fontStruct[n] = *XLoadQueryFont(h_display,h_fontNames[n]); h_font[n] = h_fontStruct[n].fid; } #ifdef DEBUG printf("fontHeight,Convert.x,Convert.y,angle,font %f,%f,%f,%f\n%s", fontHeight,Convert.x,Convert.y,angle,h_fontNames[n]); #endif XSetFont(h_display,h_gc,h_font[n]); XTextExtents(&h_fontStruct[n],message,length,&dir, &ascent,&descent,&overall); width = overall.width; ascent = overall.ascent; descent = overall.descent; switch (xalign) { case 'C': case 'c': xx -= cosA*width/2 + sinA*(ascent - descent)/2; break; case 'R': case 'r': xx -= cosA*width + sinA*ascent; break; case 'L': case 'l': default: xx += sinA*ascent; break; } switch (yalign) { case 'C': case 'c': yy += cosA*(ascent - descent)/2 - sinA*width/2; break; case 'T': case 't': yy += cosA*ascent - sinA*width; break; case 'B': case 'b': default: yy -= cosA*descent; break; } if (angle!=0) /* * There is no good way to deal with angled text prior to X11R5. * The following is an inelegant work around. This can probably * be done better with X11R5. This code is currently set up to rotate * by a fixed 90 degress (ie angle is ignored). */ { int height = ascent + descent; int i; static struct { char *text; Pixmap map; } cache[MAXCACHE]; static int Ncache = 0; for (i=0; i<Ncache; i++) { if (strcmp(cache[i].text,message) == 0) break; } if (i<Ncache) { XCopyArea(h_display,cache[i].map,h_drawable, h_gc,0,0,height,width,xx,yy); } else { int i,j; XImage *image, *rimage; XGCValues values; GC gc_temp = XCreateGC(h_display,h_drawable,0,&values); Pixmap New = XCreatePixmap(h_display,h_drawable, width,height,h_depth); Pixmap Rot = XCreatePixmap(h_display,h_drawable, height,width,h_depth); XGetGCValues(h_display,h_gc,GCBackground,&values); values.foreground = values.background; XChangeGC(h_display,gc_temp,GCForeground,&values); XFillRectangle(h_display,New,gc_temp,0,0,width,height); XFreeGC(h_display,gc_temp); XDrawString(h_display,New,h_gc,0,ascent,message,length); image = XGetImage(h_display,New,0,0,width,height, AllPlanes,XYPixmap); rimage = XGetImage(h_display,Rot,0,0,height,width, AllPlanes,XYPixmap); for (i=0; i<width; i++) for (j=0; j<height; j++) XPutPixel(rimage,j,width-i-1,XGetPixel(image,i,j)); XPutImage(h_display,Rot,h_gc,rimage,0,0,0,0,height,width); XCopyArea(h_display,Rot,h_drawable,h_gc,0,0,height,width,xx,yy); XFreePixmap(h_display,New); XDestroyImage(image); XDestroyImage(rimage); if (Ncache == MAXCACHE) { XFreePixmap(h_display,cache[0].map); free(cache[0].text); for (i=1; i<MAXCACHE; i++) cache[i-1] = cache[i]; Ncache--; } cache[Ncache].map = Rot; cache[Ncache].text = strcpy(malloc(length+1),message); Ncache++; } } else { XDrawString(h_display,h_drawable,h_gc,xx,yy,message,length); } } void drawMag_X11(float x, float y, int mag, float fontsize) /* x and y are in device coords (points). */ { char buffer[12]; sprintf(buffer,"%d",mag); drawText_X11("x10",x,y,fontsize,0,'r','c'); drawText_X11(buffer,x,y,fontsize,0,'l','b'); } void drawXTicks_X11(float *x, int nt, float tickwidth, int side) { XSegment *segs = (XSegment *) malloc(nt*sizeof(XSegment)); XSegment *ns = segs; int i; short y1, y2; if (side == 0) { y1 = YScale(Limit.ymin); y2 = y1 - Convert.y * tickwidth; } else { y1 = YScale(Limit.ymax) + 1; y2 = y1 + Convert.y * tickwidth; } for (i = 0; i < nt; i++) { ns->x1 = XScale(*x++); ns->x2 = ns->x1; ns->y1 = y1; ns->y2 = y2; ns++; } XSetLineAttributes(h_display,h_gc,0,LineSolid,CapButt,JoinMiter); XDrawSegments(h_display,h_drawable,h_gc,segs,nt); free(segs); } void drawYTicks_X11(float* y, int nt, float tickwidth, int side) { XSegment *segs = (XSegment *) malloc(nt*sizeof(XSegment)); XSegment *ns = segs; int i; short x1, x2; if (side == 0) { x1 = XScale(Limit.xmin) + 1; x2 = x1 + Convert.x * tickwidth; } else { x1 = XScale(Limit.xmax); x2 = x1 - Convert.x * tickwidth; } for (i = 0; i < nt; i++) { ns->y1 = YScale(*y++); ns->y2 = ns->y1; ns->x1 = x1; ns->x2 = x2; ns++; } XSetLineAttributes(h_display,h_gc,0,LineSolid,CapButt,JoinMiter); XDrawSegments(h_display,h_drawable,h_gc,segs,nt); free(segs); } void drawRect_X11(float x, float y, float width, float height) /* all args are in window coords */ { XDrawRectangle(h_display, h_drawable, h_gc, XConvert(x), YConvert(y), XConvert(width), XConvert(height)); #ifdef DEBUG printf("drawRect_X11: rect at (%d, %d) size (%d, %d)\n", XConvert(x), YConvert(y), XConvert(width),YConvert(height)); #endif } void drawFilledRect_X11(float x, float y, float width, float height, float grey) /* all args are in window coords */ { int xx = XConvert(x); int yy = YConvert(y); int ww = Convert.x * width; int hh = Convert.y * height; int color = 256*grey; XSetForeground(h_display, h_gc, color); XFillRectangle(h_display, h_drawable, h_gc, xx, yy, ww, hh); #ifdef DEBUG printf("drawFilledRect_X11: rect at (%d, %d) size (%d, %d) color (%d)\n", xx, yy, ww, hh, color); #endif } void shade_X11(float xlow, float xhigh, float ylow, float yhigh ) /* all args are in data coords */ { int xx = XConvert(xlow); int yy = YConvert(yhigh); int ww = XConvert(xhigh) - xx; int hh = YConvert(ylow) - yy; Pixmap Stipple; static char data[] = {0x02, 0x01}; Stipple = XCreatePixmapFromBitmapData(h_display,h_drawable,data,2,2,0,1,1); XSetStipple(h_display, h_gc, Stipple); XSetFillStyle(h_display,h_gc,FillStippled); XFillRectangle(h_display, h_drawable, h_gc, xx, yy, ww, hh); XSetFillStyle(h_display,h_gc,FillSolid); XFreePixmap(h_display,Stipple); #ifdef DEBUG printf("drawFilledRect_X11: rect at (%f, %f) to (%f, %f)\n", xlow, ylow, xhigh,yhigh); #endif } void drawLine_X11(float *xy, int nxy, linestyle_t ls) { XPoint *points = (XPoint *) malloc(nxy*sizeof(XPoint)); XPoint *np = points; int i; for (i = 0; i < nxy; i++) { np->x = XScale(*xy++); np->y = YScale(*xy++); np++; } switch (ls) { char dashlist[4]; case SOLID: default: XSetLineAttributes(h_display,h_gc,0,LineSolid,CapButt,JoinMiter); break; case DASH: dashlist[0] = 4; dashlist[1] = 4; XSetDashes(h_display,h_gc,0,dashlist,2); XSetLineAttributes(h_display,h_gc,0,LineOnOffDash,CapButt,JoinMiter); break; case DOT: dashlist[0] = 1; dashlist[1] = 2; XSetDashes(h_display,h_gc,0,dashlist,2); XSetLineAttributes(h_display,h_gc,0,LineOnOffDash,CapButt,JoinMiter); break; case DOTDASH: dashlist[0] = 4; dashlist[1] = 2; dashlist[2] = 1; dashlist[3] = 2; XSetDashes(h_display,h_gc,0,dashlist,4); XSetLineAttributes(h_display,h_gc,0,LineOnOffDash,CapButt,JoinMiter); break; } XDrawLines(h_display,h_drawable,h_gc,points,nxy,CoordModeOrigin); free(points); } void drawPoints_X11(float xy[], int nxy, int symbol, float symbolsize) { XRectangle *recs, *r; XSegment *segs, *s; int i; short simsize = min(Convert.x , Convert.y) * symbolsize/2; short width = 4, height = 4, halfwidth=2, halfheight=2; if (simsize<1) simsize=1; halfwidth = simsize; halfheight = simsize; width = simsize*2; height = simsize*2; switch (symbol) { case SQUARE: case SOLIDSQUARE: default: recs = (XRectangle *) malloc(nxy*sizeof(XRectangle)); r = recs; for (i=0; i<nxy; i++) { r->x = XScale(*xy++) - halfwidth; r->y = YScale(*xy++) - halfheight; r->width = width; r->height = height; r++; } if (symbol == SOLIDSQUARE) XFillRectangles(h_display,h_drawable, h_gc,recs,nxy); else XDrawRectangles(h_display,h_drawable, h_gc,recs,nxy); free(recs); break; case PLUS: case TIMES: segs = (XSegment *) malloc(nxy*sizeof(XSegment)*2); s = segs; if (symbol==TIMES) for (i=0; i<nxy; i++) { short x = XScale(*xy++); short y = YScale(*xy++); s->x1 = x-halfwidth; s->x2 = x+halfwidth; s->y1 = y-halfheight; s->y2 = y+halfheight; s++; s->x1 = x-halfwidth; s->x2 = x+halfwidth; s->y1 = y+halfheight; s->y2 = y-halfheight; s++; } else for (i=0; i<nxy; i++) { short x = XScale(*xy++); short y = YScale(*xy++); s->x1 = x-halfwidth; s->x2 = x+halfwidth; s->y1 = y; s->y2 = y; s++; s->x1 = x; s->x2 = x; s->y1 = y-halfheight; s->y2 = y+halfheight; s++; } XSetLineAttributes(h_display,h_gc,0,LineSolid,CapButt,JoinMiter); XDrawSegments(h_display,h_drawable,h_gc,segs,nxy*2); free(segs); } } void drawXError_X11(float xy[], float errs[], int npts) { XSegment *segs = (XSegment *) malloc(3*npts*sizeof(XSegment)); XSegment *ns = segs; int i; short halfwidth = 2; for (i = 0; i < npts; i++) { short y, xhi, xlo; xy++; /* ignore x value */ y = YScale(*xy++); xhi = XScale(*errs++); xlo = XScale(*errs++); ns->y1 = y; ns->y2 = y; ns->x1 = xlo; ns->x2 = xhi; ns++; ns->y1 = y+halfwidth; ns->y2 = y-halfwidth; ns->x1 = xlo; ns->x2 = xlo; ns++; ns->y1 = y+halfwidth; ns->y2 = y-halfwidth; ns->x1 = xhi; ns->x2 = xhi; ns++; } XSetLineAttributes(h_display,h_gc,0,LineSolid,CapButt,JoinMiter); XDrawSegments(h_display,h_drawable,h_gc,segs,3*npts); free(segs); } void drawYError_X11(float xy[], float errs[], int npts) { XSegment *segs = (XSegment *) malloc(3*npts*sizeof(XSegment)); XSegment *ns = segs; int i; short halfwidth = 2; for (i = 0; i < npts; i++) { short x, yhi, ylo; x = XScale(*xy++); xy++; /* ignore y value */ yhi = YScale(*errs++); ylo = YScale(*errs++); ns->x1 = x; ns->x2 = x; ns->y1 = ylo; ns->y2 = yhi; ns++; ns->x1 = x+halfwidth; ns->x2 = x-halfwidth; ns->y1 = ylo; ns->y2 = ylo; ns++; ns->x1 = x+halfwidth; ns->x2 = x-halfwidth; ns->y1 = yhi; ns->y2 = yhi; ns++; } XSetLineAttributes(h_display,h_gc,0,LineSolid,CapButt,JoinMiter); XDrawSegments(h_display,h_drawable,h_gc,segs,3*npts); free(segs); } static void drawStipple2D_X11(int nXBins, int nYBins, float minBin, float maxBin, float bins[]) { float xBinWidth = (Limit.xmax - Limit.xmin)/nXBins; float yBinWidth = (Limit.ymax - Limit.ymin)/nYBins; float x = Limit.xmin; float y = Limit.ymin; float scale = 15.0 / (maxBin - minBin); int i,j; int xx = XScale(Limit.xmin); int yy = YScale(Limit.ymin); int ww, hh; unsigned long mask = GCForeground | GCBackground | GCFillStyle | GCStipple; XGCValues values; Pixmap Stipple[16]; GC temp_gc[16]; static char data[16][4] = { {0x0f, 0x0f, 0x0f, 0x0f}, {0x0f, 0x0e, 0x0f, 0x0f}, {0x0f, 0x0e, 0x07, 0x0f}, {0x0d, 0x0e, 0x07, 0x0f}, {0x0d, 0x0e, 0x07, 0x0b}, {0x0d, 0x0e, 0x05, 0x0b}, {0x05, 0x0e, 0x05, 0x0b}, {0x05, 0x0a, 0x05, 0x0b}, {0x05, 0x0a, 0x05, 0x0a}, {0x05, 0x0a, 0x01, 0x0a}, {0x01, 0x0a, 0x01, 0x0a}, {0x01, 0x0a, 0x00, 0x0a}, {0x00, 0x0a, 0x00, 0x0a}, {0x00, 0x02, 0x00, 0x0a}, {0x00, 0x02, 0x00, 0x08}, {0x00, 0x02, 0x00, 0x00}}; for (i=0; i<16; i++) Stipple[i] = XCreatePixmapFromBitmapData(h_display,h_drawable, data[i],4,4,0,1,1); values.foreground = BlackPixelOfScreen(h_screen); values.background = WhitePixelOfScreen(h_screen); values.fill_style = FillOpaqueStippled; for (i=0; i<16; i++) { values.stipple = Stipple[i]; temp_gc[i] = XCreateGC(h_display,h_drawable,mask,&values); } XFillRectangle(h_display,h_drawable,temp_gc[0],xx,YScale(Limit.ymax), (XScale(Limit.xmax)-xx),(yy-YScale(Limit.ymax))); for (i=0; i<nXBins; i++) { x += xBinWidth; ww = XScale(x) - xx; for (j=0; j<nYBins; j++) { int ss = scale * (*bins++ - minBin); y += yBinWidth; hh = yy - YScale(y); yy -= hh; if (ss!=0) XFillRectangle(h_display,h_drawable,temp_gc[ss],xx,yy,ww,hh); } xx += ww; yy = YScale(Limit.ymin); y = Limit.ymin; } for (i=0; i<16; i++) { XFreePixmap(h_display,Stipple[i]); XFreeGC(h_display,temp_gc[i]); } } void drawColor2D_X11(int nXBins, int nYBins, float minBin, float maxBin, float bins[], int fullColor) { float xBinWidth = (Limit.xmax - Limit.xmin)/nXBins; float yBinWidth = (Limit.ymax - Limit.ymin)/nYBins; float x = Limit.xmin; float y = Limit.ymin; float scale = 90.0 / (maxBin - minBin); int i,j; int xx = XScale(Limit.xmin); int yy = YScale(Limit.ymin); int ww, hh; static int GotColorMap = 0; static int GotGreyMap = 0; Colormap Map; static XColor Color[91]; static XColor Grey[91]; XColor *ColorsUsed; GC temp_gc; static struct { int red; int green; int blue; } rainbow[10] ={{0 , 0, 0}, /* black */ {33422, 15728, 553}, /* brown */ {23912, 14548, 33947}, /* violet */ {15217, 17377, 41142}, /* indigo */ { 0, 0, 55049}, /* blue */ { 0, 50078, 199}, /* green */ {62193, 60816, 0}, /* yellow */ {65535, 28180, 1310}, /* orange */ {65535, 1310, 0}, /* red */ {65535, 65535, 65535}}; /* white */ if (!h_color) { drawStipple2D_X11(nXBins,nYBins,minBin,maxBin,bins); return; } temp_gc = XCreateGC(h_display,h_drawable,NULL,0); if (fullColor != 0 && GotColorMap++ == 0) { int i, j, k=0; Map = DefaultColormapOfScreen(h_screen); for (i=0; i<9; i++) { for (j=0; j<10; j++) { Color[k].red = rainbow[i].red*(10-j)/10 + rainbow[i+1].red*j/10; Color[k].blue = rainbow[i].blue*(10-j)/10 + rainbow[i+1].blue*j/10; Color[k].green = rainbow[i].green*(10-j)/10 + rainbow[i+1].green*j/10; if (!XAllocColor(h_display,Map,&Color[k])) ColorError(); k++; } } Color[k].red = rainbow[9].red; Color[k].blue = rainbow[9].blue; Color[k].green = rainbow[9].green; if (!XAllocColor(h_display,Map,&Color[k])) ColorError(); } else if (fullColor == 0 && GotGreyMap++ ==0) { int i; Map = DefaultColormapOfScreen(h_screen); for (i=0; i<=90; i++) { int color = 65535-i*65535/90; Grey[i].red = color; Grey[i].blue = color; Grey[i].green = color; if (!XAllocColor(h_display,Map,&Grey[i])) ColorError(); } } if (fullColor == 0) ColorsUsed = Grey; else ColorsUsed = Color; XSetForeground(h_display,temp_gc,ColorsUsed[0].pixel); XFillRectangle(h_display,h_drawable,temp_gc,xx,YScale(Limit.ymax), (XScale(Limit.xmax)-xx),(yy-YScale(Limit.ymax))); for (i=0; i<nXBins; i++) { x += xBinWidth; ww = XScale(x) - xx; for (j=0; j<nYBins; j++) { int color = scale * (*bins++ - minBin); y += yBinWidth; hh = yy - YScale(y); yy -= hh; if (color==0) continue; XSetForeground(h_display,temp_gc,ColorsUsed[color].pixel); XFillRectangle(h_display,h_drawable,temp_gc,xx,yy,ww,hh); } xx += ww; yy = YScale(Limit.ymin); y = Limit.ymin; } XFreeGC(h_display,temp_gc); } void drawLego2D_X11(display disp) { float angle = 45; /* degrees */ float sin45 = 1./sqrt(2.); float cos45 = sin45; float xBinWidth = (Limit.xmax - Limit.xmin)/disp->bins.xAxis.nBins; float yBinWidth = cos45*(Limit.ymax - Limit.ymin)/disp->bins.yAxis.nBins; float x = Limit.xmax; float y = Limit.ymax; float scale = (YScale(Limit.ymax) - YScale(Limit.ymin)) * ( 1 - cos45 ) / (disp->bins.binMax - disp->bins.binMin); int i,j; int xx = XScale(Limit.xmax); int yy = YScale(Limit.ymax); int ww, hh, oo, xxx, yyy; XPoint points[5]; static XColor bright, medium, dark; static int GotColors = 0; static Pixmap Medium; static int GotPixmap = 0; GC bright_gc, medium_gc, dark_gc; bright_gc = XCreateGC(h_display,h_drawable,0,NULL); medium_gc = XCreateGC(h_display,h_drawable,0,NULL); dark_gc = XCreateGC(h_display,h_drawable,0,NULL); if (h_color && GotColors++ == 0) { Colormap Map = DefaultColormapOfScreen(h_screen); bright.red = 55000; bright.blue = 55000; bright.green = 55000; if (!XAllocColor(h_display,Map,&bright)) ColorError(); medium.red = 35000; medium.blue = 35000; medium.green = 35000; if (!XAllocColor(h_display,Map,&medium)) ColorError(); dark.red = 10000; dark.blue = 10000; dark.green = 10000; if (!XAllocColor(h_display,Map,&dark)) ColorError(); } else if (!h_color && GotPixmap++ == 0) { static char medium_data[] = {0x02, 0x01}; Medium = XCreatePixmapFromBitmapData(h_display,h_drawable, medium_data,2,2,0,1,1); } if (h_color) { XSetForeground(h_display,medium_gc,medium.pixel); XSetForeground(h_display,bright_gc,bright.pixel); XSetForeground(h_display,dark_gc ,dark.pixel); } else { XSetFillStyle(h_display,medium_gc,FillOpaqueStippled); XSetStipple(h_display,medium_gc,Medium); XSetForeground(h_display,bright_gc,WhitePixelOfScreen(h_screen)); XSetForeground(h_display,medium_gc,WhitePixelOfScreen(h_screen)); XSetForeground(h_display,dark_gc ,BlackPixelOfScreen(h_screen)); XSetBackground(h_display,medium_gc,BlackPixelOfScreen(h_screen)); } points[0].x = xx - (YScale(Limit.ymin) - YScale(Limit.ymax))*cos45; points[0].y = yy + (YScale(Limit.ymin) - YScale(Limit.ymax))*(1-sin45); points[1].x = XScale(Limit.xmin) - (YScale(Limit.ymin) - YScale(Limit.ymax))*cos45; points[1].y = yy + (YScale(Limit.ymin) - YScale(Limit.ymax))*(1-sin45); points[2].x = XScale(Limit.xmin); points[2].y = YScale(Limit.ymin); points[3].x = xx; points[3].y = YScale(Limit.ymin); points[4].x = xx - (YScale(Limit.ymin) - YScale(Limit.ymax))*cos45; points[4].y = yy + (YScale(Limit.ymin) - YScale(Limit.ymax))*(1-sin45); XFillPolygon(h_display,h_drawable,medium_gc,points,5, Convex,CoordModeOrigin); xxx = -(YScale(Limit.ymin) - YScale(Limit.ymax))*cos45; yyy = (YScale(Limit.ymin) - YScale(Limit.ymax))*(1-sin45); for (j=0; j<disp->bins.yAxis.nBins; j++) { y -= yBinWidth; hh = cos45*(YScale(y) - yy); oo = sin45*(yy - YScale(y)); yy += hh; disp->bins.data += disp->bins.xAxis.nBins*disp->bins.yAxis.nBins - 1; for (i=0; i<disp->bins.xAxis.nBins; i++) { int size = scale * (*disp->bins.data - disp->bins.binMin); disp->bins.data -= disp->bins.yAxis.nBins; x -= xBinWidth; ww = xx - XScale(x); xx -= ww; if (size == 0) continue; points[0].x = xx + xxx; points[0].y = yy + yyy + size; points[1].x = xx + xxx + ww; points[1].y = yy + yyy + size; points[2].x = xx + xxx + ww + oo; points[2].y = yy + yyy - hh + size; points[3].x = xx + xxx + oo; points[3].y = yy + yyy - hh + size; points[4].x = xx + xxx; points[4].y = yy + yyy + size; XFillPolygon(h_display,h_drawable,medium_gc,points,5, Convex,CoordModeOrigin); points[0].x = xx + xxx; points[0].y = yy + yyy; points[1].x = xx + xxx; points[1].y = yy + yyy + size; points[2].x = xx + xxx + oo; points[2].y = yy + yyy - hh + size; points[3].x = xx + xxx + oo; points[3].y = yy + yyy - hh; points[4].x = xx + xxx; points[4].y = yy + yyy; XFillPolygon(h_display,h_drawable,bright_gc,points,5, Convex,CoordModeOrigin); points[0].x = xx + xxx; points[0].y = yy + yyy; points[1].x = xx + xxx + ww; points[1].y = yy + yyy; points[2].x = xx + xxx + ww; points[2].y = yy + yyy + size; points[3].x = xx + xxx; points[3].y = yy + yyy + size; points[4].x = xx + xxx; points[4].y = yy + yyy; XFillPolygon(h_display,h_drawable,dark_gc,points,5, Convex,CoordModeOrigin); } xxx -= oo; xx = XScale(Limit.xmax); x = Limit.xmax; } XFreeGC(h_display,bright_gc); XFreeGC(h_display,dark_gc); XFreeGC(h_display,medium_gc); } void drawScatter3D_X11(display disp, float *coords, int nCoords) { }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.