00001
00002
00003
00004 #ifndef WIN32 // stupid to prevent compilation in windows
00005
00006 #include "Xdraw.h"
00007 #include "gui/DisplayRep.h"
00008 #include <vector>
00009 #include <cmath>
00010
00011 static int markerSize = 4;
00012 static Colormap cmap;
00013 static XColor color_blue, color_red, color_black, colorrgb;
00014 static int useColor=0;
00015
00016
00017 static std::vector<unsigned> color_table;
00018
00019 int Xdraw::xwin (float x)const { return (int)((x+1.)*currentQuad.dx/2) + currentQuad.x; }
00020 int Xdraw::ywin (float y)const { return (int)((1.-y)*currentQuad.dy/2) + currentQuad.y; }
00021 float Xdraw::xnorm (int x)const { return 2 *(x - currentQuad.x) / (float)currentQuad.dx - 1; }
00022 float Xdraw::ynorm (int y)const { return 1 - 2 *(y - currentQuad.y) / (float)currentQuad.dy; }
00023
00024
00025 Xdraw::Xdraw(int width, int height)
00026 : mydisplay(0)
00027 , mywindow(0)
00028 {
00029
00030
00031 flSingle = 1;
00032 resize (width, height);
00033 }
00034
00035 void Xdraw::setDisplay(Display* d, Window w)
00036 {
00037 mydisplay = d;
00038 mywindow = w;
00039 myscreen = DefaultScreen(d);
00040 if (DisplayPlanes(mydisplay, myscreen) > 1 && !useColor ) {
00041 useColor = 1;
00042 cmap = DefaultColormap(mydisplay, myscreen);
00043 (void)XAllocNamedColor(mydisplay, cmap, "red", &color_red, &colorrgb);
00044 (void)XAllocNamedColor(mydisplay, cmap, "blue",&color_blue, &colorrgb);
00045 (void)XAllocNamedColor(mydisplay, cmap, "black",&color_black, &colorrgb);
00046
00047
00048
00049 int i=0;
00050 do{
00051 XColor color_temp;
00052 DisplayRep::ColorInfo& cinfo = DisplayRep::pallete[i++];
00053 if( cinfo.name == 0 ) break;
00054 (void)XAllocNamedColor(mydisplay, cmap, cinfo.name,
00055 &color_temp, &colorrgb);
00056 color_table.push_back( color_temp.pixel );
00057 }while(1);
00058 }
00059
00060 }
00061
00062 Xdraw::~Xdraw()
00063 {
00064 }
00065
00066
00067 void Xdraw::draw_string(float x, float y, const char *string, int size)
00068 {
00069 move_to(x,y);
00070 draw_string(string,size);
00071 }
00072
00073 void Xdraw::draw_string(const char* string, int )
00074
00075 {
00076 XDrawString (mydisplay, mywindow,
00077 DefaultGC (mydisplay, myscreen),
00078 xwin(lastx), ywin(lasty),
00079 string, strlen (string));
00080 }
00081
00082 void Xdraw::move_to(float x, float y)
00083 {
00084 lastx = x;
00085 lasty = y;
00086 }
00087 static bool inline inside(float x, float y){return fabs(x)<1.01 && fabs(y)<1.01;}
00088
00089
00090 bool Xdraw::clip(float x, float y,
00091 int& ix1, int& iy1, int& ix2, int& iy2)
00092 {
00093 bool b1=inside(x,y), b2=inside(lastx,lasty);
00094 if( b1 && b2) {
00095 ix2 = xwin(x);
00096 iy2 = ywin(y);
00097 ix1 = xwin(lastx);
00098 iy1 = ywin(lasty);
00099 return true;
00100 }
00101
00102 float dx=lastx-x, dy=lasty-y;
00103
00104 float s[]={-1,-1,-1,-1};
00105 int k=0;
00106 if( dx!=0){s[k++]=(1-x)/dx; s[k++] = (-1-x)/dx;}
00107 if( dy!=0){s[k++]=(1-y)/dy; s[k++] = (-1-y)/dy;}
00108
00109 float t[4];
00110 int j=0;
00111 if( b1) t[j++]=0;
00112 if( b2) t[j++]=1;
00113
00114
00115 for( int i=0; i<k; ++i){
00116 if(s[i]>0 && s[i]<1 && inside(x+s[i]*dx,y+s[i]*dy)) t[j++]=s[i];
00117 }
00118 if( j<2 )return false;
00119 ix1 = xwin(x+t[0]*dx);
00120 iy1 = ywin(y+t[0]*dy);
00121 ix2 = xwin(x+t[1]*dx);
00122 iy2 = ywin(y+t[1]*dy);
00123 return true;
00124 }
00125 void Xdraw::line_to(float x, float y)
00126 {
00127 int x1,y1,x2,y2;
00128 if( clip(x,y, x1,y1,x2,y2) )
00129 XDrawLine (mydisplay, mywindow,
00130 DefaultGC (mydisplay, myscreen),
00131 x1, y1,
00132 x2, y2 );
00133 lastx = x;
00134 lasty = y;
00135 }
00136 void Xdraw::fill_polygon(const float* xy, int npoints, Shading pattern)
00137 {
00138
00139 XPoint * points = new XPoint[npoints];
00140
00141 XPoint* pt = points;
00142 for(int i = 0; i<npoints; ++i, ++pt) {
00143 pt->x = xwin(*xy++);
00144 pt->y = ywin(*xy++);
00145 }
00146
00147 XFillPolygon (mydisplay, mywindow, DefaultGC (mydisplay, myscreen),
00148 points, npoints,
00149 Convex,CoordModeOrigin);
00150
00151 delete[] points;
00152
00153 }
00154
00155 void Xdraw::flush()
00156 {
00157
00158 #if 0
00159 XRectangle rectangle[1];
00160 rectangle[0].x = 1;
00161 rectangle[0].y = 1;
00162 rectangle[0].width = screen.dx-2;
00163 rectangle[0].height = screen.dy-2;
00164 XSetClipRectangles(mydisplay,
00165 DefaultGC (mydisplay, myscreen),
00166 0, 0, rectangle, 1, Unsorted);
00167 #endif
00168 XFlush(mydisplay);
00169 }
00170
00171
00172 void Xdraw::draw_marker(float x, float y)
00173 {
00174 int thisx = xwin(x);
00175 int thisy = ywin(y);
00176
00177
00178
00179
00180 XDrawLine (mydisplay, mywindow,
00181 DefaultGC (mydisplay, myscreen),
00182 thisx-markerSize, thisy,
00183 thisx+markerSize, thisy );
00184 XDrawLine (mydisplay, mywindow,
00185 DefaultGC (mydisplay, myscreen),
00186 thisx, thisy-markerSize,
00187 thisx, thisy+markerSize );
00188 XDrawLine (mydisplay, mywindow,
00189 DefaultGC (mydisplay, myscreen),
00190 thisx-markerSize, thisy-markerSize,
00191 thisx+markerSize, thisy+markerSize );
00192 XDrawLine (mydisplay, mywindow,
00193 DefaultGC (mydisplay, myscreen),
00194 thisx-markerSize, thisy+markerSize,
00195 thisx+markerSize, thisy-markerSize );
00196
00197
00198
00199
00200 }
00201
00202 void Xdraw::set_quad (int quadnr, const char * title, int )
00203 {
00204 if (quadnr==0) {
00205 flSingle = 1;
00206 currentQuad = screen;
00207 } else {
00208 flSingle = 0;
00209 currentQuad = quadrant [selected = quadnr-1];
00210 }
00211
00212
00213 XClearArea(mydisplay, mywindow, currentQuad.x, currentQuad.y, currentQuad.dx, currentQuad.dy, False);
00214
00215
00216 XRectangle rectangle[1];
00217 rectangle[0].x = currentQuad.x + 1;
00218 rectangle[0].y = currentQuad.y + 1;
00219 rectangle[0].width = currentQuad.dx - 2;
00220 rectangle[0].height = currentQuad.dy - 2;
00221 XSetClipRectangles(mydisplay, DefaultGC (mydisplay, myscreen),
00222 0, 0, rectangle, 1, Unsorted);
00223
00224
00225 if(title) XDrawString (mydisplay, mywindow,
00226 DefaultGC (mydisplay, myscreen),
00227 xwin(-0.9), ywin(-0.9),
00228 title, strlen (title));
00229
00230 set_defaults();
00231 }
00232
00233
00234 void Xdraw::set_defaults()
00235 {
00236 XSetLineAttributes(mydisplay,
00237 DefaultGC (mydisplay, myscreen),
00238 0,
00239 LineSolid,
00240 CapButt,
00241 JoinMiter);
00242 if (useColor)
00243 XSetForeground(mydisplay, DefaultGC(mydisplay,myscreen),
00244 color_black.pixel);
00245 }
00246
00247
00248 void Xdraw::setXorMode(int on)
00249 {
00250 if (on)
00251 {
00252
00253
00254
00255
00256 XSetFunction (mydisplay, DefaultGC(mydisplay, myscreen),
00257 GXxor);
00258 XSetLineAttributes (mydisplay, DefaultGC(mydisplay, myscreen),
00259 0,
00260 LineSolid,
00261 CapButt,
00262 JoinMiter);
00263 }
00264 else
00265 {
00266
00267
00268
00269
00270 XSetFunction (mydisplay, DefaultGC(mydisplay, myscreen),
00271 GXcopy);
00272 XSetLineAttributes (mydisplay, DefaultGC(mydisplay, myscreen),
00273 0,
00274 LineSolid,
00275 CapButt,
00276 JoinMiter);
00277 }
00278 }
00279
00280
00281 void Xdraw::set_line_style(int style)
00282 {
00283 switch (style ){
00284 case DisplayRep::DOTTED_LINE : style = LineOnOffDash; break;
00285 case DisplayRep::SOLID_LINE :
00286 default: style = LineSolid;
00287
00288 }
00289 XSetLineAttributes(mydisplay,
00290 DefaultGC (mydisplay, myscreen),
00291 0,
00292 style,
00293 CapButt,
00294 JoinMiter);
00295 }
00296
00297
00298
00299 void Xdraw::set_col_index(int index)
00300 {
00301 XSetForeground(mydisplay, DefaultGC(mydisplay,myscreen), color_table[index]);
00302 }
00303
00304 void Xdraw::resize (int xsize, int ysize)
00305 {
00306 if( xsize==0 ) {
00307 XWindowAttributes attribs;
00308 XGetWindowAttributes (mydisplay, mywindow, &attribs);
00309 xsize = attribs.width; ysize = attribs.height;
00310 }
00311
00312 if( xsize < ysize ) ysize=xsize; else xsize=ysize;
00313
00314 screen.x = 0; screen.y = 0; screen.dx = xsize; screen.dy = ysize;
00315 quadrant[0].x = 0; quadrant[0].y = 0; quadrant[0].dx = xsize/2; quadrant[0].dy = ysize/2;
00316 quadrant[1].x = xsize/2+1; quadrant[1].y = 0; quadrant[1].dx = xsize/2; quadrant[1].dy = ysize/2;
00317 quadrant[2].x = 0; quadrant[2].y = ysize/2+1; quadrant[2].dx = xsize/2; quadrant[2].dy = ysize/2;
00318 quadrant[3].x = xsize/2+1; quadrant[3].y = ysize/2+1; quadrant[3].dx = xsize/2; quadrant[3].dy = ysize/2;
00319
00320 if (flSingle) currentQuad = screen;
00321 else currentQuad = quadrant[selected];
00322 }
00323
00324
00325 void Xdraw::drawRect(const Xdraw::Rectangle& selection)
00326 {
00327 move_to( selection.x, selection.y );
00328 line_to( selection.x + selection.dx, selection.y );
00329 line_to( selection.x + selection.dx, selection.y + selection.dy );
00330 line_to( selection.x, selection.y + selection.dy );
00331 line_to( selection.x, selection.y );
00332 }
00333
00334
00335 #endif //NT_MSVCPP
00336