CairoPlot.cpp

Go to the documentation of this file.
00001 //CairoPlot.cpp
00002 
00003 /*************************************************************/
00004 //
00005 // GreyLabWindow
00006 //
00007 // Cairo data plotting routines for the GreyLabWindow class
00008 //
00009 //-------------------------------------------------------------
00010 //
00011 // v 1.9 - 2008/03/10 - Changes to allow export of all linescans
00012 // v 1.8 - 2007/12/13 - More z-axis plotting options
00013 // v 1.7 - 2007/12/07 - Relabelled some widgets
00014 // v 1.6 - 2007/11/30 - Diagonal tick for trace legend
00015 // v 1.5 - 2007/05/31 - Linescan fixes
00016 // v 1.4 - 2007/04/04 - Improvements to plot outputs
00017 // v 1.3 - 2007/03/31 - Changes to turning gradient related bits off
00018 // v 1.2 - 2007/03/23 - Changes to linescan offsets
00019 // v 1.1 - 2007/03/14 - Fixed some positioning and dimensions
00020 // v 1.0 - 2007/02/17 - Initial release
00021 //
00022 // See LICENSE.txt for distribution and usage restrictions
00023 // Copyright (c) 2007-2007 Simon Chorley
00024 // www.mylaboratory.co.uk - greylab@mylaboratory.co.uk
00025 //
00026 /*************************************************************/
00027 
00028 ///Cairo data plotting routines
00029 /**
00030  * Provides Cairo vector graph drawing routines for GreyLab
00031  * @file CairoPlot.cpp
00032  * @version 1.9 - 2008/03/10
00033  */
00034 
00035 
00036 #include "GreyLab.h"
00037 
00038 
00039 #include <cairo.h>
00040 #include <cairo-pdf.h>
00041 #include <cairo-ps.h>
00042 #include <cairo-svg.h>
00043 
00044 
00045 ///Redraws colourscale image
00046 /**
00047  * Redraws the vector colourscale graph image. All parameters are unused.
00048  */
00049 long GreyLabWindow::cmdGSVectorRedraw(FXObject*, FXSelector, void*)
00050 {
00051         int i, j;
00052         int xPel, yPel;
00053         double xp, yp;
00054 
00055         if (gsinfo.validdata != true) return(1);
00056 
00057         
00058 //Setup the Cairo surface for the image data
00059         cairo_surface_t *cairois = cairo_image_surface_create(CAIRO_FORMAT_RGB24, gsinfo.xpixels, gsinfo.ypixels);
00060         cairo_t *cairoi = cairo_create(cairois);
00061 //    cairo_scale(cairo, gsinfo.xpixels, gsinfo.ypixels);
00062         cairo_set_source_rgba(cairoi, 1.0, 1.0, 1.0, 1.0);
00063         cairo_paint(cairoi);
00064 
00065 //Create pdfimage to calculate metrics
00066         cairo_surface_t *cairovs;
00067         if (gsinfo.vectorop == _gsinfo::PDF)
00068                 cairovs = cairo_pdf_surface_create(translateString(gspathTextfield->getText()).text(), gsinfo.xpixels, gsinfo.ypixels);
00069         else if (gsinfo.vectorop == _gsinfo::PS)
00070                 cairovs = cairo_ps_surface_create(translateString(gspathTextfield->getText()).text(), gsinfo.xpixels, gsinfo.ypixels);
00071         else //_gsinfo::svg
00072                 cairovs = cairo_svg_surface_create(translateString(gspathTextfield->getText()).text(), gsinfo.xpixels, gsinfo.ypixels);
00073         cairo_t *cairov = cairo_create(cairovs);
00074         graphfont.initCairoMeasurements(cairov);
00075         const float fh = graphfont.cairofontheight;
00076         const float nfh = graphfont.caironumfontheight;
00077 
00078 
00079         float gamma = FXFloatVal(gsgammaTextfield->getText());
00080 
00081         //Generate colours
00082         FXColor colours[COLOURRES];
00083         zgradGradient->gradient(colours, COLOURRES);
00084         FXColor col;
00085         FXColor lowcol = lcolColourwell->getRGBA();
00086         FXColor hicol = hcolColourwell->getRGBA();
00087         FXColor nocol = nodataColourwell->getRGBA();
00088         unsigned char lc[3], hc[3], nc[3];
00089         lc[0] = (unsigned char)FXREDVAL(lowcol);
00090         lc[1] = (unsigned char)FXGREENVAL(lowcol);
00091         lc[2] = (unsigned char)FXBLUEVAL(lowcol);
00092         hc[0] = (unsigned char)FXREDVAL(hicol);
00093         hc[1] = (unsigned char)FXGREENVAL(hicol);
00094         hc[2] = (unsigned char)FXBLUEVAL(hicol);
00095         nc[0] = (unsigned char)FXREDVAL(nocol);
00096         nc[1] = (unsigned char)FXGREENVAL(nocol);
00097         nc[2] = (unsigned char)FXBLUEVAL(nocol);
00098 
00099         float lz = FXFloatVal(gszminTextfield->getText());
00100         float hz = FXFloatVal(gszmaxTextfield->getText());
00101 
00102         //colour data points
00103         double zdelta = FXDoubleVal(gscontourspaceTextfield->getText());
00104         unsigned char *byteimage = new unsigned char[gsinfo.xpixels*gsinfo.ypixels*3];
00105         if ((gscontourCheckbutton->getCheck() == true) && (zdelta != 0.0))
00106         {
00107                 if ((hz-lz)/zdelta > 100.0)
00108                         if (FXMessageBox::question(this, FX::MBOX_YES_NO, "Countour spacing!", ("Really plot ~"+FXStringVal((hz-lz)/zdelta)+" contours?").text()) != MBOX_CLICKED_YES)
00109                                 gscontourCheckbutton->setCheck(false);
00110         }
00111         if ((gscontourCheckbutton->getCheck() == true) && (zdelta != 0.0))
00112         {
00113 /*              unsigned char *byteimage = new unsigned char[gsinfo.xpixels*gsinfo.ypixels*3];
00114                 bool altcontour = gscontouraltCheckbutton->getCheck();
00115                 for (yPel = 0; yPel < gsinfo.ypixels; ++yPel)
00116                 {
00117                         for (xPel = 0; xPel < gsinfo.xpixels; ++xPel)
00118                         {
00119                                 byteimage[0+3*(xPel+gsinfo.xpixels*yPel)] = 255;
00120                                 byteimage[1+3*(xPel+gsinfo.xpixels*yPel)] = 255;
00121                                 byteimage[2+3*(xPel+gsinfo.xpixels*yPel)] = 255;
00122                         }
00123                 }
00124                 yp = zdelta*(int)(lz/zdelta)-zdelta;
00125                 for (i = 0; i < 2+(int)((hz-lz)/zdelta); ++i)
00126                 {
00127                         if ((yp >= lz) && (yp <= hz))
00128                         {
00129                                 for (yPel = 0; yPel < gsinfo.ypixels-1; ++yPel)
00130                                 {
00131                                         for (xPel = 0; xPel < gsinfo.xpixels-1; ++xPel)
00132                                         {
00133                                                 if (((gsdata[xPel+gsinfo.xpixels*yPel].data <= yp) && (gsdata[xPel+1+gsinfo.xpixels*yPel].data > yp))
00134                                                         || ((gsdata[xPel+gsinfo.xpixels*yPel].data > yp) && (gsdata[xPel+1+gsinfo.xpixels*yPel].data <= yp)))
00135                                                 {
00136                                                         if (altcontour == false)
00137                                                         {
00138                                                                 col = colours[(int)(clamp(pow((yp-lz)/(hz-lz), gamma))*COLOURRES)];
00139                                                                 byteimage[0+3*(xPel+gsinfo.xpixels*yPel)] = (unsigned char)FXREDVAL(col);
00140                                                                 byteimage[1+3*(xPel+gsinfo.xpixels*yPel)] = (unsigned char)FXGREENVAL(col);
00141                                                                 byteimage[2+3*(xPel+gsinfo.xpixels*yPel)] = (unsigned char)FXBLUEVAL(col);
00142                                                         }
00143                                                         else
00144                                                         {
00145                                                                 byteimage[0+3*(xPel+gsinfo.xpixels*yPel)] = (unsigned char)0;
00146                                                                 byteimage[1+3*(xPel+gsinfo.xpixels*yPel)] = (unsigned char)0;
00147                                                                 byteimage[2+3*(xPel+gsinfo.xpixels*yPel)] = (unsigned char)0;
00148                                                         }
00149                                                 }
00150                                                 else if (((gsdata[xPel+gsinfo.xpixels*yPel].data <= yp) && (gsdata[xPel+gsinfo.xpixels*(yPel+1)].data > yp))
00151                                                         || ((gsdata[xPel+gsinfo.xpixels*yPel].data > yp) && (gsdata[xPel+gsinfo.xpixels*(yPel+1)].data <= yp)))
00152                                                 {
00153                                                         if (altcontour == false)
00154                                                         {
00155                                                                 col = colours[(int)(clamp(pow((yp-lz)/(hz-lz), gamma))*COLOURRES)];
00156                                                                 byteimage[0+3*(xPel+gsinfo.xpixels*yPel)] = (unsigned char)FXREDVAL(col);
00157                                                                 byteimage[1+3*(xPel+gsinfo.xpixels*yPel)] = (unsigned char)FXGREENVAL(col);
00158                                                                 byteimage[2+3*(xPel+gsinfo.xpixels*yPel)] = (unsigned char)FXBLUEVAL(col);
00159                                                         }
00160                                                         else
00161                                                         {
00162                                                                 byteimage[0+3*(xPel+gsinfo.xpixels*yPel)] = (unsigned char)0;
00163                                                                 byteimage[1+3*(xPel+gsinfo.xpixels*yPel)] = (unsigned char)0;
00164                                                                 byteimage[2+3*(xPel+gsinfo.xpixels*yPel)] = (unsigned char)0;
00165                                                         }
00166                                                 }
00167                                         }
00168                                 }
00169                         }
00170                         yp += zdelta;
00171                 }
00172                 for (yPel = 1; yPel < gsinfo.ypixels-1; ++yPel)
00173                 {
00174                         for (xPel = 1; xPel < gsinfo.xpixels-1; ++xPel)
00175                         {
00176                                 unsigned char c[3];
00177                                 c[0] = byteimage[0+3*(xPel+gsinfo.xpixels*yPel)];
00178                                 c[1] = byteimage[1+3*(xPel+gsinfo.xpixels*yPel)];
00179                                 c[2] = byteimage[2+3*(xPel+gsinfo.xpixels*yPel)];
00180                                 if ((c[0] != 255) || (c[1] != 255) || (c[2] != 255))
00181                                 {
00182                                         int c1 = 0;
00183                                         int c2 = 0;
00184                                         if ((byteimage[0+3*(xPel+1+gsinfo.xpixels*yPel)] != c[0]) || (byteimage[1+3*(xPel+1+gsinfo.xpixels*yPel)] != c[1]) || (byteimage[2+3*(xPel+1+gsinfo.xpixels*yPel)] != c[2]))
00185                                                 ++c1;
00186                                         if ((byteimage[0+3*(xPel-1+gsinfo.xpixels*yPel)] != c[0]) || (byteimage[1+3*(xPel-1+gsinfo.xpixels*yPel)] != c[1]) || (byteimage[2+3*(xPel-1+gsinfo.xpixels*yPel)] != c[2]))
00187                                                 ++c1;
00188                                         if ((byteimage[0+3*(xPel+gsinfo.xpixels*(yPel+1))] != c[0]) || (byteimage[1+3*(xPel+gsinfo.xpixels*(yPel+1))] != c[1]) || (byteimage[2+3*(xPel+gsinfo.xpixels*(yPel+1))] != c[2]))
00189                                                 ++c2;
00190                                         if ((byteimage[0+3*(xPel+gsinfo.xpixels*(yPel-1))] != c[0]) || (byteimage[1+3*(xPel+gsinfo.xpixels*(yPel-1))] != c[1]) || (byteimage[2+3*(xPel+gsinfo.xpixels*(yPel-1))] != c[2]))
00191                                                 ++c2;
00192                                         if ((c1 == 1) && (c2 == 1))
00193                                         {
00194                                                 byteimage[0+3*(xPel+gsinfo.xpixels*yPel)] += 3*(255-byteimage[0+3*(xPel+gsinfo.xpixels*yPel)])/4;
00195                                                 byteimage[1+3*(xPel+gsinfo.xpixels*yPel)] += 3*(255-byteimage[1+3*(xPel+gsinfo.xpixels*yPel)])/4;
00196                                                 byteimage[2+3*(xPel+gsinfo.xpixels*yPel)] += 3*(255-byteimage[2+3*(xPel+gsinfo.xpixels*yPel)])/4;
00197                                         }
00198                                 }
00199                         }
00200                 }
00201                 if (altcontour == true)
00202                 {
00203                         for (yPel = 0; yPel < gsinfo.ypixels; ++yPel)
00204                         {
00205                                 for (xPel = 0; xPel < gsinfo.xpixels; ++xPel)
00206                                 {
00207 #ifdef LINUX64
00208                                         if ((gsdata[xPel+gsinfo.xpixels*yPel].n == 0) || (isfinite(gsdata[xPel+gsinfo.xpixels*yPel].data) == 0))
00209 #else
00210                                         if (gsdata[xPel+gsinfo.xpixels*yPel].n == 0)
00211 #endif
00212                                         {
00213                                                 byteimage[0+3*(xPel+gsinfo.xpixels*yPel)] = (byteimage[0+3*(xPel+gsinfo.xpixels*yPel)]*nc[0])/255;
00214                                                 byteimage[1+3*(xPel+gsinfo.xpixels*yPel)] = (byteimage[1+3*(xPel+gsinfo.xpixels*yPel)]*nc[1])/255;
00215                                                 byteimage[2+3*(xPel+gsinfo.xpixels*yPel)] = (byteimage[2+3*(xPel+gsinfo.xpixels*yPel)]*nc[2])/255;
00216                                         }
00217                                         else if (gsdata[xPel+gsinfo.xpixels*yPel].data <= lz)
00218                                         {
00219                                                 byteimage[0+3*(xPel+gsinfo.xpixels*yPel)] = (byteimage[0+3*(xPel+gsinfo.xpixels*yPel)]*lc[0])/255;
00220                                                 byteimage[1+3*(xPel+gsinfo.xpixels*yPel)] = (byteimage[1+3*(xPel+gsinfo.xpixels*yPel)]*lc[1])/255;
00221                                                 byteimage[2+3*(xPel+gsinfo.xpixels*yPel)] = (byteimage[2+3*(xPel+gsinfo.xpixels*yPel)]*lc[2])/255;
00222                                         }
00223                                         else if (gsdata[xPel+gsinfo.xpixels*yPel].data >= hz)
00224                                         {
00225                                                 byteimage[0+3*(xPel+gsinfo.xpixels*yPel)] = (byteimage[0+3*(xPel+gsinfo.xpixels*yPel)]*hc[0])/255;
00226                                                 byteimage[1+3*(xPel+gsinfo.xpixels*yPel)] = (byteimage[1+3*(xPel+gsinfo.xpixels*yPel)]*hc[1])/255;
00227                                                 byteimage[2+3*(xPel+gsinfo.xpixels*yPel)] = (byteimage[2+3*(xPel+gsinfo.xpixels*yPel)]*hc[2])/255;
00228                                         }
00229                                         else
00230                                         {
00231                                                 col = colours[(int)(clamp(pow((gsdata[xPel+gsinfo.xpixels*yPel].data-lz)/(hz-lz), gamma))*COLOURRES)];
00232                                                 byteimage[0+3*(xPel+gsinfo.xpixels*yPel)] = (byteimage[0+3*(xPel+gsinfo.xpixels*yPel)]*(unsigned char)FXREDVAL(col))/255;
00233                                                 byteimage[1+3*(xPel+gsinfo.xpixels*yPel)] = (byteimage[1+3*(xPel+gsinfo.xpixels*yPel)]*(unsigned char)FXGREENVAL(col))/255;
00234                                                 byteimage[2+3*(xPel+gsinfo.xpixels*yPel)] = (byteimage[2+3*(xPel+gsinfo.xpixels*yPel)]*(unsigned char)FXBLUEVAL(col))/255;
00235                                         }
00236                                 }
00237                         }
00238                 }*/
00239                 unsigned char *cmap = new unsigned char[gsinfo.xpixels*gsinfo.ypixels*2];
00240                 memset(cmap, 0, gsinfo.xpixels*gsinfo.ypixels*2);
00241                 FXColor contourcol = gscontourcolColourwell->getRGBA();
00242                 bool altcontour = gscontouraltCheckbutton->getCheck();
00243                 //Fill in the contours
00244                 yp = zdelta*(int)(lz/zdelta)-zdelta;
00245                 for (i = 0; i < 2+(int)((hz-lz)/zdelta); ++i)
00246                 {
00247                         if ((yp >= lz) && (yp <= hz))
00248                         {
00249                                 for (yPel = 0; yPel < gsinfo.ypixels-1; ++yPel)
00250                                 {
00251                                         for (xPel = 0; xPel < gsinfo.xpixels-1; ++xPel)
00252                                         {
00253                                                 if (gsdata[xPel+gsinfo.xpixels*yPel].n > 0)
00254                                                 {
00255                                                         if (((gsdata[xPel+gsinfo.xpixels*yPel].data <= yp) && (gsdata[xPel+1+gsinfo.xpixels*yPel].data > yp))
00256                                                                 || ((gsdata[xPel+gsinfo.xpixels*yPel].data > yp) && (gsdata[xPel+1+gsinfo.xpixels*yPel].data <= yp)))
00257                                                         {
00258                                                                 cmap[0+2*(xPel+gsinfo.xpixels*yPel)] = 255;
00259                                                                 cmap[1+2*(xPel+gsinfo.xpixels*yPel)] = 1;
00260                                                         }
00261                                                         else if (((gsdata[xPel+gsinfo.xpixels*yPel].data <= yp) && (gsdata[xPel+gsinfo.xpixels*(yPel+1)].data > yp))
00262                                                                 || ((gsdata[xPel+gsinfo.xpixels*yPel].data > yp) && (gsdata[xPel+gsinfo.xpixels*(yPel+1)].data <= yp)))
00263                                                         {
00264                                                                 cmap[0+2*(xPel+gsinfo.xpixels*yPel)] = 255;
00265                                                                 cmap[1+2*(xPel+gsinfo.xpixels*yPel)] = 1;
00266                                                         }
00267                                                 }
00268                                         }
00269                                 }
00270                         }
00271                         yp += zdelta;
00272                 }
00273                 //Antialias corners
00274                 for (yPel = 1; yPel < gsinfo.ypixels-1; ++yPel)
00275                 {
00276                         for (xPel = 1; xPel < gsinfo.xpixels-1; ++xPel)
00277                         {
00278                                 if (cmap[1+2*(xPel+gsinfo.xpixels*yPel)] == 1)
00279                                 {
00280                                         int c1 = 0;
00281                                         int c2 = 0;
00282                                         if (cmap[1+2*(xPel+1+gsinfo.xpixels*yPel)] == 1)
00283                                                 ++c1;
00284                                         if (cmap[1+2*(xPel-1+gsinfo.xpixels*yPel)] == 1)
00285                                                 ++c1;
00286                                         if (cmap[1+2*(xPel+gsinfo.xpixels*(yPel+1))] == 1)
00287                                                 ++c2;
00288                                         if (cmap[1+2*(xPel+gsinfo.xpixels*(yPel-1))] == 1)
00289                                                 ++c2;
00290                                         if ((c1 == 1) && (c2 == 1))
00291                                                 cmap[0+2*(xPel+gsinfo.xpixels*yPel)] = 255/3;
00292                                 }
00293                         }
00294                 }
00295                 //Fill in data
00296                 if (altcontour == true)
00297                 {
00298                         for (yPel = 0; yPel < gsinfo.ypixels; ++yPel)
00299                         {
00300                                 for (xPel = 0; xPel < gsinfo.xpixels; ++xPel)
00301                                 {
00302 #ifdef LINUX64
00303                                         if ((gsdata[xPel+gsinfo.xpixels*yPel].n == 0) || (isfinite(gsdata[xPel+gsinfo.xpixels*yPel].data) == 0))
00304 #else
00305                                         if (gsdata[xPel+gsinfo.xpixels*yPel].n == 0)
00306 #endif
00307                                         {
00308                                                 byteimage[0+3*(xPel+gsinfo.xpixels*yPel)] = nc[0];
00309                                                 byteimage[1+3*(xPel+gsinfo.xpixels*yPel)] = nc[1];
00310                                                 byteimage[2+3*(xPel+gsinfo.xpixels*yPel)] = nc[2];
00311                                         }
00312                                         else if (gsdata[xPel+gsinfo.xpixels*yPel].data <= lz)
00313                                         {
00314                                                 byteimage[0+3*(xPel+gsinfo.xpixels*yPel)] = lc[0];
00315                                                 byteimage[1+3*(xPel+gsinfo.xpixels*yPel)] = lc[1];
00316                                                 byteimage[2+3*(xPel+gsinfo.xpixels*yPel)] = lc[2];
00317                                         }
00318                                         else if (gsdata[xPel+gsinfo.xpixels*yPel].data >= hz)
00319                                         {
00320                                                 byteimage[0+3*(xPel+gsinfo.xpixels*yPel)] = hc[0];
00321                                                 byteimage[1+3*(xPel+gsinfo.xpixels*yPel)] = hc[1];
00322                                                 byteimage[2+3*(xPel+gsinfo.xpixels*yPel)] = hc[2];
00323                                         }
00324                                         else
00325                                         {
00326                                                 float a = (float)(FXALPHAVAL(contourcol)*cmap[0+2*(xPel+gsinfo.xpixels*yPel)])/(255.0*255.0);
00327                                                 col = colours[(int)(clamp(pow((gsdata[xPel+gsinfo.xpixels*yPel].data-lz)/(hz-lz), gamma))*COLOURRES)];
00328                                                 if (cmap[1+2*(xPel+gsinfo.xpixels*yPel)] > 0)
00329                                                 {
00330                                                         byteimage[0+3*(xPel+gsinfo.xpixels*yPel)] = a*FXREDVAL(contourcol)+(1.0-a)*FXREDVAL(col);
00331                                                         byteimage[1+3*(xPel+gsinfo.xpixels*yPel)] = a*FXGREENVAL(contourcol)+(1.0-a)*FXGREENVAL(col);
00332                                                         byteimage[2+3*(xPel+gsinfo.xpixels*yPel)] = a*FXBLUEVAL(contourcol)+(1.0-a)*FXBLUEVAL(col);
00333                                                 }
00334                                                 else
00335                                                 {
00336                                                         byteimage[0+3*(xPel+gsinfo.xpixels*yPel)] = FXREDVAL(col);
00337                                                         byteimage[1+3*(xPel+gsinfo.xpixels*yPel)] = FXGREENVAL(col);
00338                                                         byteimage[2+3*(xPel+gsinfo.xpixels*yPel)] = FXBLUEVAL(col);
00339                                                 }
00340                                         }
00341                                 }
00342                         }
00343                 }
00344                 else
00345                 {
00346                         for (yPel = 0; yPel < gsinfo.ypixels; ++yPel)
00347                         {
00348                                 for (xPel = 0; xPel < gsinfo.xpixels; ++xPel)
00349                                 {
00350 #ifdef LINUX64
00351                                         if ((gsdata[xPel+gsinfo.xpixels*yPel].n == 0) || (isfinite(gsdata[xPel+gsinfo.xpixels*yPel].data) == 0))
00352 #else
00353                                         if (gsdata[xPel+gsinfo.xpixels*yPel].n == 0)
00354 #endif
00355                                         {
00356                                                 byteimage[0+3*(xPel+gsinfo.xpixels*yPel)] = nc[0];
00357                                                 byteimage[1+3*(xPel+gsinfo.xpixels*yPel)] = nc[1];
00358                                                 byteimage[2+3*(xPel+gsinfo.xpixels*yPel)] = nc[2];
00359                                         }
00360                                         else
00361                                         {
00362                                                 if (cmap[1+2*(xPel+gsinfo.xpixels*yPel)] != 0)
00363                                                 {
00364                                                         float a = (float)cmap[0+2*(xPel+gsinfo.xpixels*yPel)]/255.0;
00365                                                         col = colours[(int)(clamp(pow((gsdata[xPel+gsinfo.xpixels*yPel].data-lz)/(hz-lz), gamma))*COLOURRES)];
00366                                                         byteimage[0+3*(xPel+gsinfo.xpixels*yPel)] = a*FXREDVAL(col)+(1.0-a)*FXREDVAL(contourcol);
00367                                                         byteimage[1+3*(xPel+gsinfo.xpixels*yPel)] = a*FXGREENVAL(col)+(1.0-a)*FXGREENVAL(contourcol);
00368                                                         byteimage[2+3*(xPel+gsinfo.xpixels*yPel)] = a*FXBLUEVAL(col)+(1.0-a)*FXBLUEVAL(contourcol);
00369                                                 }
00370                                                 else
00371                                                 {
00372                                                         byteimage[0+3*(xPel+gsinfo.xpixels*yPel)] = (unsigned char)FXREDVAL(contourcol);
00373                                                         byteimage[1+3*(xPel+gsinfo.xpixels*yPel)] = (unsigned char)FXGREENVAL(contourcol);
00374                                                         byteimage[2+3*(xPel+gsinfo.xpixels*yPel)] = (unsigned char)FXBLUEVAL(contourcol);
00375                                                 }
00376                                         }
00377                                 }
00378                         }
00379                 }
00380                 delete[] cmap;
00381                 for (yPel = 0; yPel < gsinfo.ypixels; ++yPel)
00382                 {
00383                         for (xPel = 0; xPel < gsinfo.xpixels; ++xPel)
00384                         {
00385                                 cairo_set_source_rgba(cairoi, (float)byteimage[0+3*(xPel+gsinfo.xpixels*yPel)]/255.0,
00386                                         (float)byteimage[1+3*(xPel+gsinfo.xpixels*yPel)]/255.0, (float)byteimage[2+3*(xPel+gsinfo.xpixels*yPel)]/255.0, 1.0);
00387                                 cairo_rectangle(cairoi, (float)xPel, (float)(yPel), 1.0, 1.0);
00388                                 cairo_fill(cairoi);
00389                         }
00390                 }
00391                 delete[] byteimage;
00392         }
00393         else
00394         {
00395                 for (yPel = 0; yPel < gsinfo.ypixels; ++yPel)
00396                 {
00397                         for (xPel = 0; xPel < gsinfo.xpixels; ++xPel)
00398                         {
00399 #ifdef LINUX64
00400                                 if ((gsdata[xPel+gsinfo.xpixels*yPel].n == 0) || (isfinite(gsdata[xPel+gsinfo.xpixels*yPel].data) == 0))
00401 #else
00402                                 if (gsdata[xPel+gsinfo.xpixels*yPel].n == 0)
00403 #endif
00404                                 {
00405                                         cairo_set_source_rgba(cairoi, (float)nc[0]/255.0, (float)nc[1]/255.0, (float)nc[2]/255.0, 1.0);
00406                                 }
00407                                 else if (gsdata[xPel+gsinfo.xpixels*yPel].data <= lz)
00408                                 {
00409                                         cairo_set_source_rgba(cairoi, (float)lc[0]/255.0, (float)lc[1]/255.0, (float)lc[2]/255.0, 1.0);
00410                                 }
00411                                 else if (gsdata[xPel+gsinfo.xpixels*yPel].data >= hz)
00412                                 {
00413                                         cairo_set_source_rgba(cairoi, (float)hc[0]/255.0, (float)hc[1]/255.0, (float)hc[2]/255.0, 1.0);
00414                                 }
00415                                 else
00416                                 {
00417                                         col = colours[(int)(clamp(pow((gsdata[xPel+gsinfo.xpixels*yPel].data-lz)/(hz-lz), gamma))*COLOURRES)];
00418                                         cairo_set_source_rgba(cairoi, (float)FXREDVAL(col)/255.0, (float)FXGREENVAL(col)/255.0, (float)FXBLUEVAL(col)/255.0, 1.0);
00419                                 }
00420                                 cairo_rectangle(cairoi, (float)xPel, (float)(yPel), 1.0, 1.0);
00421                                 cairo_fill(cairoi);
00422                         }
00423                 }
00424         }
00425 
00426 
00427 //Prepare variables for grid lines
00428         int stride = gsinfo.totalwidth;
00429         double ystart = FXFloatVal(gsyminTextfield->getText().text());
00430         double xstart = FXFloatVal(gsxminTextfield->getText().text());
00431         double xend = FXFloatVal(gsxmaxTextfield->getText().text());
00432         double yend = FXFloatVal(gsymaxTextfield->getText().text());
00433         if (gsymajortickTextfield->getText().length() == 0) gsymajortickTextfield->setText(FXStringVal((yend-ystart)/10.0));
00434         if (gsyminortickTextfield->getText().length() == 0) gsyminortickTextfield->setText(FXStringVal((yend-ystart)/100.0));
00435         if (gsxmajortickTextfield->getText().length() == 0) gsxmajortickTextfield->setText(FXStringVal((xend-xstart)/10.0));
00436         if (gsxminortickTextfield->getText().length() == 0) gsxminortickTextfield->setText(FXStringVal((xend-xstart)/100.0));
00437         double majorstep = fabs(FXFloatVal(gsymajortickTextfield->getText().text()));
00438         if (yend-ystart < 0) majorstep *= -1.0;
00439         double minorstep = fabs(FXFloatVal(gsyminortickTextfield->getText().text()));
00440         if (yend-ystart < 0) minorstep *= -1.0;
00441         double majdelta = (double)gsinfo.ypixels/((yend-ystart)/majorstep);
00442         double mindelta = (double)gsinfo.ypixels/((yend-ystart)/minorstep);
00443         col = gsymajorcolColourwell->getRGBA();
00444         float majrgba[4];
00445         majrgba[0] = (float)FXREDVAL(col)/255.0;
00446         majrgba[1] = (float)FXGREENVAL(col)/255.0;
00447         majrgba[2] = (float)FXBLUEVAL(col)/255.0;
00448         majrgba[3] = (float)FXALPHAVAL(col)/255.0;
00449         col = gsyminorcolColourwell->getRGBA();
00450         float minrgba[4];
00451         minrgba[0] = (float)FXREDVAL(col)/255.0;
00452         minrgba[1] = (float)FXGREENVAL(col)/255.0;
00453         minrgba[2] = (float)FXBLUEVAL(col)/255.0;
00454         minrgba[3] = (float)FXALPHAVAL(col)/255.0;
00455 
00456         //Calculate label dimensions
00457         int labeldims[8];       //yscale, ylabel, x label, z max, zmin, z label, title, subtitle
00458         FXString labels[8];
00459         int copout = 0;
00460         int twidth = 0;
00461 //Get y precision
00462         int tw, prec = 0;
00463         gsinfo.yprecision = 0;
00464         if (yend < ystart)
00465         {
00466                 for (yp = majorstep*(int)(ystart/majorstep); (yp >= yend) && (copout < 100); yp += majorstep)
00467                 {
00468                         if (yp >= yend)
00469                         {
00470                                 prec = graphfont.getPrecision(yp);
00471                                 if (prec > gsinfo.yprecision) gsinfo.yprecision = prec;
00472                         }
00473                         ++copout;
00474                 }
00475         }
00476         else
00477         {
00478                 for (yp = majorstep*(int)(ystart/majorstep); (yp <= yend) && (copout < 100); yp += majorstep)
00479                 {
00480                         if (yp >= ystart)
00481                         {
00482                                 prec = graphfont.getPrecision(yp);
00483                                 if (prec > gsinfo.yprecision) gsinfo.yprecision = prec;
00484                         }
00485                         ++copout;
00486                 }
00487         }
00488 //      std::cerr << "yp: " << majorstep*(int)(ystart/majorstep) << ", mstep: " << majorstep << ", yend: " << yend << ", ystart: " << ystart << '\n';
00489         if (yend < ystart)
00490         {
00491 //              std::cerr << "yend<ystart\n";
00492                 for (yp = majorstep*(int)(ystart/majorstep); (yp >= yend) && (copout < 100); yp += majorstep)
00493                 {
00494                         if (yp >= yend)
00495                         {
00496 //                              std::cerr << yp << '\n';
00497                                 tw = graphfont.getStringDimensions(cairov, yp, gsinfo.yprecision);
00498                                 if (tw > twidth) twidth = tw;
00499                         }
00500                         ++copout;
00501                 }
00502 //              std::cerr << copout << '\n';
00503         }
00504         else
00505         {
00506 //              std::cerr << "yend>ystart\n";
00507                 for (yp = majorstep*(int)(ystart/majorstep); (yp <= yend) && (copout < 100); yp += majorstep)
00508                 {
00509                         if (yp >= ystart)
00510                         {
00511 //                              std::cerr << yp << '\n';
00512                                 tw = graphfont.getStringDimensions(cairov, yp, gsinfo.yprecision);
00513                                 if (tw > twidth) twidth = tw;
00514                         }
00515                         ++copout;
00516                 }
00517 //              std::cerr << copout << '\n';
00518         }
00519 //Get x precision
00520         prec = 0;
00521         gsinfo.xprecision = 0;
00522         majorstep = fabs(FXFloatVal(gsxmajortickTextfield->getText().text()));
00523         if (xend-xstart < 0) majorstep *= -1.0;
00524         minorstep = fabs(FXFloatVal(gsxminortickTextfield->getText().text()));
00525         if (xend-xstart < 0) minorstep *= -1.0;
00526         majdelta = (double)gsinfo.xpixels/((xend-xstart)/majorstep);
00527         mindelta = (double)gsinfo.xpixels/((xend-xstart)/minorstep);
00528         if (xend < xstart)
00529         {
00530                 for (xp = majorstep*(int)(xstart/majorstep); (xp >= xend) && (copout < 100); xp += majorstep)
00531                 {
00532                         if (xp >= xend)
00533                         {
00534                                 prec = graphfont.getPrecision(xp);
00535                                 if (prec > gsinfo.xprecision) gsinfo.xprecision = prec;
00536                         }
00537                         ++copout;
00538                 }
00539         }
00540         else
00541         {
00542                 for (xp = majorstep*(int)(xstart/majorstep); (xp <= xend) && (copout < 100); xp += majorstep)
00543                 {
00544                         if (xp >= xstart)
00545                         {
00546                                 prec = graphfont.getPrecision(xp);
00547                                 if (prec > gsinfo.xprecision) gsinfo.xprecision = prec;
00548                         }
00549                         ++copout;
00550                 }
00551         }
00552         //width of widest x string
00553         int rightborder = 0;
00554         copout = 0;
00555         double xms = FXFloatVal(gsxmajortickTextfield->getText().text());
00556         if (gsinfo.xend < gsinfo.xstart)
00557                 xms *= -1.0;
00558         if (gsinfo.xend < gsinfo.xstart)
00559         {
00560                 for (yp = xms*(int)(gsinfo.xstart/xms); (yp >= gsinfo.xend) && (copout < 100); yp += xms)
00561                 {
00562                         if (yp >= gsinfo.xend)
00563                                 rightborder = graphfont.getStringDimensions(cairov, yp, gsinfo.xprecision)/2;
00564                         ++copout;
00565                 }
00566         }
00567         else
00568         {
00569                 for (yp = xms*(int)(gsinfo.xstart/xms); (yp <= gsinfo.xend) && (copout < 100); yp += xms)
00570                 {
00571                         if (yp >= gsinfo.xstart)
00572                                 rightborder = graphfont.getStringDimensions(cairov, yp, gsinfo.xprecision)/2;
00573                         ++copout;
00574                 }
00575         }
00576 //Get z precision
00577         int zticktextwidth = 0;
00578         zdelta = quantise((hz-lz)/FXIntVal(setautozgridTextfield->getText()));
00579         if (gshidescalezlabelMenucheck->getCheck() == false)
00580         {
00581                 if (gszscaleshowendsMenucheck->getCheck() == true)
00582                 {
00583                         prec = 0;
00584                         gsinfo.zprecision = 0;
00585                         yp = zdelta*(int)(lz/zdelta)-zdelta;
00586                         for (i = 0; i < 100; ++i)
00587                         {
00588                                 if ((yp >= lz) && (yp <= hz))
00589                                 {
00590                                         prec = graphfont.getPrecision(yp);
00591                                         if (prec > gsinfo.zprecision) gsinfo.zprecision = prec;
00592                                 }
00593                                 yp += zdelta;
00594                         }
00595                         yp = zdelta*(int)(lz/zdelta)-zdelta;
00596                         int temp = 0;
00597                         for (i = 0; i < 100; ++i)
00598                         {
00599                                 if ((yp >= lz) && (yp <= hz))
00600                                 {
00601                                         temp = graphfont.getStringDimensions(cairov, yp, gsinfo.zprecision);
00602                                         if (temp > zticktextwidth) zticktextwidth = temp;
00603                                 }
00604                                 yp += zdelta;
00605                         }
00606                         zticktextwidth += (int)(multiplier*graphsets.scaleticktextoffsetlength)/2;
00607                 }
00608                 else
00609                 {
00610                         gsinfo.zprecision = graphfont.getPrecision(FXDoubleVal(gszmaxTextfield->getText()));
00611                         int zprec2 = graphfont.getPrecision(FXDoubleVal(gszminTextfield->getText()));
00612                         if (zprec2 > gsinfo.zprecision) gsinfo.zprecision = zprec2;
00613                 }
00614         }
00615         
00616 //Generate sizes of borders
00617         labeldims[0] = twidth;
00618         labels[1] = translateString(gsylabelTextfield->getText());
00619         labeldims[1] = graphfont.getStringDimensions(cairov, labels[1]);
00620         if (gsylabelrotCheckbutton->getCheck() == false)
00621                 gsinfo.leftlegend = multiplier*graphsets.ticktextoffsetlength+labeldims[0]+labeldims[1]+fh*(0.25+graphsets.labeloffsetfraction);
00622         else
00623                 gsinfo.leftlegend = multiplier*graphsets.ticktextoffsetlength+labeldims[0]+fh*(1.25+graphsets.labeloffsetfraction);
00624         labels[2] = translateString(gsxlabelTextfield->getText());
00625         labeldims[2] = graphfont.getStringDimensions(cairov, labels[2]);
00626         gsinfo.bottomlegend = multiplier*graphsets.ticktextoffsetlength+2+fh*(1.25+graphsets.labeloffsetfraction)+nfh;  //extra 5 just cos it looked wrong
00627 //      gsinfo.bottomlegend = multiplier*BASECHARGAP+2*fh+graphfont.cairobaselineheight*3.0/4.0;
00628         if (gszscaleshowendsMenucheck->getCheck() == true)
00629         {
00630                 labeldims[3] = zticktextwidth;
00631                 labeldims[4] = 0;
00632         }
00633         else
00634         {
00635                 labeldims[3] = graphfont.getStringDimensions(cairov, FXDoubleVal(gszmaxTextfield->getText()), gsinfo.zprecision);
00636                 labeldims[4] = graphfont.getStringDimensions(cairov, FXDoubleVal(gszminTextfield->getText()), gsinfo.zprecision);
00637         }
00638 //      labeldims[3] = graphfont.getStringDimensions(cairov, FXDoubleVal(gszmaxTextfield->getText()));
00639 //      labeldims[4] = graphfont.getStringDimensions(cairov, FXDoubleVal(gszminTextfield->getText()));
00640         labels[5] = translateString(gszlabelTextfield->getText());
00641         labeldims[5] = graphfont.getStringDimensions(cairov, labels[5]);
00642         int labelpart = 0;
00643         int scalepart = 0;
00644         if (gshidegradzlabelMenucheck->getCheck() == false)
00645                 gsinfo.gradwidth = multiplier*graphsets.scalebargap+multiplier*graphsets.scalebarwidth;
00646 //              gsinfo.gradwidth = (int)(multiplier*BASESCALEBAR+multiplier*BASESCALEGAP);
00647         else
00648                 gsinfo.gradwidth = 0;
00649         if (gshidescalezlabelMenucheck->getCheck() == false)
00650                 scalepart = largest(labeldims[3], labeldims[4], 0);
00651         if (gshidelabelzlabelMenucheck->getCheck() == false)
00652                 labelpart = labeldims[5];
00653 /*      if (gszlabelrotMenucheck->getCheck() == false)
00654                 gsinfo.rightlegend = multiplier*graphsets.scaleticktextoffsetlength+largest(scalepart, labelpart, rightborder); //longest z string
00655 //              gsinfo.rightlegend = multiplier*BASECHARGAP+largest(scalepart, labelpart, rightborder); //longest z string
00656         else
00657                 gsinfo.rightlegend = multiplier*graphsets.scaleticktextoffsetlength+largest(scalepart, fh, rightborder);        //longest z string
00658 //              gsinfo.rightlegend = multiplier*BASECHARGAP+largest(scalepart, graphfont.fontheight, rightborder);      //longest z string
00659 //      if (gszlabelrotCheckbutton->getCheck() == false)