1 /* ************************************************************************* 2 graphicsdevice.hpp - GDL graphical output 3 renamed from: graphics.hpp 4 ------------------- 5 begin : July 22 2002 6 copyright : (C) 2002 by Marc Schellens 7 email : m_schellens@users.sf.net 8 ***************************************************************************/ 9 10 /* ************************************************************************* 11 * * 12 * This program is free software; you can redistribute it and/or modify * 13 * it under the terms of the GNU General Public License as published by * 14 * the Free Software Foundation; either version 2 of the License, or * 15 * (at your option) any later version. * 16 * * 17 ***************************************************************************/ 18 19 /* 20 21 GDL Graphic subsytem: 22 23 GraphicsDevice - base subsystem class 24 DeviceXXX - derived from Graphics, subsystem for device XXX 25 26 27 GDLGStream - base graphic stream class (= windows, printer page) 28 GDLXXXStream - derived from GDLGStream for XXX type of stream 29 30 31 So for each device XXX there is a: 32 DeviceXXX 33 and at least one 34 GDLXXXStream 35 36 Devices are (note that on a given platform not all devices are available): 37 X - X windows (GDLXStream, GDLWXStream) 38 WIN - Windows 39 PS - postscript output 40 SVG - a SVG compliant file. 41 42 */ 43 44 45 #ifndef GRAPHICSDEVICE_HPP_ 46 #define GRAPHICSDEVICE_HPP_ 47 48 #include <vector> 49 50 #include "datatypes.hpp" // DByte 51 #include "dstructgdl.hpp" 52 #include "gdlgstream.hpp" 53 54 #define MAX_WIN 32 //IDL free and widgets start at 32 ... 55 #define MAX_WIN_RESERVE 256 56 57 const UInt max_win = MAX_WIN; 58 const UInt max_win_reserve = MAX_WIN_RESERVE; 59 const UInt ctSize = 256; 60 61 class GDLCT 62 { 63 DByte r[ ctSize]; 64 DByte g[ ctSize]; 65 DByte b[ ctSize]; 66 67 UInt actSize; 68 69 std::string name; 70 71 public: GDLCT(const std::string & n,DByte * r_,DByte * g_,DByte * b_,SizeT nCol=ctSize)72 GDLCT( const std::string& n, DByte* r_, DByte* g_, DByte* b_, SizeT nCol = ctSize): 73 actSize( nCol), name( n) 74 { 75 SizeT i=0; 76 for(;i<nCol;++i) 77 { 78 r[i] = r_[i]; 79 g[i] = g_[i]; 80 b[i] = b_[i]; 81 } 82 for(;i<ctSize;++i) 83 { 84 r[i] = 0; 85 g[i] = 0; 86 b[i] = 0; 87 } 88 } 89 90 // default is greyscale GDLCT()91 GDLCT(): actSize( ctSize), name("DEFAULT") 92 { 93 for( UInt i=0; i<ctSize; i++) 94 { 95 r[i]=g[i]=b[i]=i; 96 } 97 } 98 ~GDLCT()99 ~GDLCT() {} 100 101 bool Get( PLINT r_[], PLINT g_[], PLINT b_[], UInt nCol=ctSize) const; 102 103 bool Get( UInt ix, DByte& r_, DByte& g_, DByte& b_) const; 104 bool Set( UInt ix, DByte r_, DByte g_, DByte b_); // RGB 105 bool SetHLS( UInt ix, DFloat h, DFloat l, DFloat s); 106 bool SetHSV( UInt ix, DFloat h, DFloat s, DFloat v); 107 Name() const108 std::string Name() const { return name;} 109 }; 110 111 class GDLGStream; 112 class GraphicsDevice; 113 typedef std::vector< GraphicsDevice*> DeviceListT; 114 115 class GraphicsDevice 116 { 117 static void InitCT(); // preset CT and actCT 118 119 static GraphicsDevice* actDevice; 120 static DeviceListT deviceList; 121 static GraphicsDevice* actGUIDevice; 122 123 static void DefineDStructDesc(); // modifies structList 124 unsigned char* CopyBuffer; 125 SizeT CopyBufferSize; 126 127 protected: 128 static int wTag, xSTag, ySTag, xVSTag, yVSTag, n_colorsTag; // !D tag indices 129 130 static std::vector<GDLCT> CT; // predefined colortables 131 static GDLCT actCT; // actual used colortable 132 static DByte deviceBckColorR; 133 static DByte deviceBckColorG; 134 static DByte deviceBckColorB; 135 136 std::string name; 137 DStructGDL* dStruct; 138 GetWinSize(DLong & x,DLong & y)139 void GetWinSize( DLong& x, DLong& y) 140 { 141 int tag = dStruct->Desc()->TagIndex( "X_SIZE"); 142 DLongGDL* xSize = static_cast<DLongGDL*>( dStruct->GetTag( tag)); 143 tag = dStruct->Desc()->TagIndex( "Y_SIZE"); 144 DLongGDL* ySize = static_cast<DLongGDL*>( dStruct->GetTag( tag)); 145 x = (*xSize)[0]; 146 y = (*ySize)[0]; 147 } 148 149 150 public: 151 GraphicsDevice(); 152 virtual ~GraphicsDevice(); 153 154 static void Init(); 155 static void DestroyDevices(); 156 static void HandleEvents(); 157 158 static void LoadCT(UInt iCT); SetDeviceBckColor(DByte r,DByte g,DByte b)159 void SetDeviceBckColor(DByte r, DByte g, DByte b) 160 { 161 deviceBckColorR=r; 162 deviceBckColorG=g; 163 deviceBckColorB=b; 164 } BackgroundR()165 DByte BackgroundR() {return deviceBckColorR;} BackgroundG()166 DByte BackgroundG() {return deviceBckColorG;} BackgroundB()167 DByte BackgroundB() {return deviceBckColorB;} 168 GetCT()169 static GDLCT* GetCT() { return &actCT;} GetCT(SizeT ix)170 static GDLCT* GetCT( SizeT ix) { return &CT[ix];} N_CT()171 static SizeT N_CT() { return CT.size();} 172 static void ListDevice(std::ostream& oss=cout); 173 static bool ExistDevice( const std::string& device, int &index); 174 static bool SetDevice( const std::string& devName); 175 DStructGDL* GetDeviceStruct( const std::string& device); GetDevice()176 static GraphicsDevice* GetDevice() { return actDevice;} GetGUIDevice()177 static GraphicsDevice* GetGUIDevice() { return actGUIDevice;} DStruct()178 static DStructGDL* DStruct() { return actDevice->dStruct;} 179 Name()180 const DString Name() { return name;} 181 GetCopyBuffer()182 unsigned char* GetCopyBuffer() {return CopyBuffer;} GetCopyBufferSize()183 SizeT GetCopyBufferSize() {return CopyBufferSize;} SetCopyBuffer(SizeT size)184 unsigned char* SetCopyBuffer(SizeT size) 185 { 186 if (CopyBufferSize != 0) {free (CopyBuffer); CopyBufferSize = 0;} 187 CopyBuffer=(unsigned char*)calloc(size, sizeof(char)); //set to zero 188 CopyBufferSize = size; 189 return CopyBuffer; 190 } 191 192 GetStreamAt(int wIx) const193 virtual GDLGStream* GetStreamAt( int wIx) const { return NULL;} ChangeStreamAt(int wIx,GDLGStream * newStream)194 virtual void ChangeStreamAt(int wIx, GDLGStream* newStream){}; GetStream(bool open=true)195 virtual GDLGStream* GetStream( bool open=true) { return NULL;} WSet(int ix)196 virtual bool WSet( int ix) { return false;} WAddFree()197 virtual int WAddFree() { return false;} 198 199 // for WIDGET_DRAW GUIOpen(int wIx,int xSize,int ySize,void * draw)200 virtual GDLGStream* GUIOpen( int wIx, int xSize, int ySize, void* draw){ return NULL;} 201 202 // for plot windows WOpen(int ix,const std::string & title,int xsize,int ysize,int xpos,int ypos,bool hide)203 virtual bool WOpen( int ix, const std::string& title, 204 int xsize, int ysize, 205 int xpos, int ypos, bool hide) { return false;} WSize(int ix,int * xsize,int * ysize)206 virtual bool WSize( int ix, 207 int* xsize, int* ysize) { return false;} WShow(int ix,bool show,int iconic)208 virtual bool WShow( int ix, bool show, int iconic) { return false;} WState(int ix)209 virtual bool WState( int ix) { return false;} WDelete(int ix)210 virtual bool WDelete( int ix) { return false;} MaxWin()211 virtual int MaxWin() { return 0;} TidyWindowsList(bool d=true)212 virtual void TidyWindowsList(bool d=true){} MaxNonFreeWin()213 virtual int MaxNonFreeWin() { return MaxWin();} ActWin()214 virtual int ActWin() { return -1;} GetNonManagedWidgetActWin(bool doTidy=true)215 virtual int GetNonManagedWidgetActWin(bool doTidy=true) {return -1;} SetActWin(int wIx)216 virtual void SetActWin(int wIx) {} EventHandler()217 virtual void EventHandler() {} DefaultXYSize(DLong * xsize,DLong * ysize)218 virtual void DefaultXYSize(DLong *xsize, DLong *ysize) { 219 *xsize=640, *ysize=480; return;} MaxXYSize(DLong * xsize,DLong * ysize)220 virtual void MaxXYSize(DLong *xsize, DLong *ysize) { 221 *xsize=1200, *ysize=800; return;} GetDecomposed()222 virtual DLong GetDecomposed() { return -1;} GetFontnames()223 virtual BaseGDL* GetFontnames() { ThrowGDLException("DEVICE: Keyword GET_FONTNAMES not allowed for call to: DEVICE" ); return NULL;} GetFontnum()224 virtual DLong GetFontnum() { ThrowGDLException("DEVICE: Keyword GET_FONTNUM not allowed for call to: DEVICE" ); return 0;} SetFont(DString & f)225 virtual bool SetFont(DString &f) {static int warning_sent=1; if (warning_sent) {Warning("SET_FONT not active for this device (FIXME)."); warning_sent=0;} return true;} GetCurrentFont()226 virtual DString GetCurrentFont() {return NULL;} GetGraphicsFunction()227 virtual DLong GetGraphicsFunction() { return -1;} GetPageSize()228 virtual DIntGDL* GetPageSize() { return NULL;} GetPixelDepth()229 virtual DLong GetPixelDepth() { return -1;} SetPixelDepth(DInt depth)230 virtual bool SetPixelDepth(DInt depth) { return false;} GetScreenResolution(char * disp=NULL)231 virtual DDoubleGDL* GetScreenResolution(char* disp=NULL) //fake a basic screen if not implemented: 232 { 233 DDoubleGDL* res; 234 res = new DDoubleGDL(2, BaseGDL::NOZERO); 235 (*res)[0]=1.0; 236 (*res)[1]=1.0; 237 return res; 238 } 239 // virtual DFloatGDL* GetScreenSize(char* disp=NULL) { return NULL;} GetScreenSize(char * disp=NULL)240 virtual DLongGDL* GetScreenSize(char* disp=NULL) //fake a basic screen if not implemented: 241 { 242 DLongGDL* res; 243 res = new DLongGDL(2, BaseGDL::NOZERO); 244 (*res)[0]=640; 245 (*res)[1]=480; 246 return res; 247 } GetVisualDepth()248 virtual DLong GetVisualDepth() { return -1;} GetVisualName()249 virtual DString GetVisualName() { return "";} GetWindowPosition()250 virtual DIntGDL* GetWindowPosition() { return NULL;} GetWriteMask()251 virtual DLong GetWriteMask() { return -1;} WindowState()252 virtual DByteGDL* WindowState() { return NULL;} CloseFile()253 virtual bool CloseFile() { return false;} SetFileName(const std::string & f)254 virtual bool SetFileName( const std::string& f) { return false;} Decomposed(bool value)255 virtual bool Decomposed( bool value) { return false;} SetGraphicsFunction(DLong value)256 virtual bool SetGraphicsFunction( DLong value) { return false;} CursorStandard(int value)257 virtual bool CursorStandard( int value) { return false;} CursorCrosshair(bool standard=false)258 virtual bool CursorCrosshair(bool standard=false) { return false;} CursorImage(char * v,int x=0,int y=0,char * mask=NULL)259 virtual bool CursorImage(char* v, int x=0, int y=0, char* mask=NULL) { return false;} getCursorId()260 virtual int getCursorId() { return -1;} UnsetFocus()261 virtual bool UnsetFocus() { return false;} SetBackingStore(int value)262 virtual bool SetBackingStore(int value) { return false;} getBackingStore()263 virtual int getBackingStore() { return -1;} SetXPageSize(const float xs)264 virtual bool SetXPageSize( const float xs) { return false;} SetYPageSize(const float ys)265 virtual bool SetYPageSize( const float ys) { return false;} SetColor(const long color=0)266 virtual bool SetColor(const long color=0) { return false;} SetScale(const float)267 virtual bool SetScale(const float) { return false;} SetXOffset(const float)268 virtual bool SetXOffset(const float) { return false;} SetYOffset(const float)269 virtual bool SetYOffset(const float) { return false;} SetPortrait()270 virtual bool SetPortrait() { return false;} SetLandscape()271 virtual bool SetLandscape() { return false;} SetEncapsulated(bool val)272 virtual bool SetEncapsulated(bool val) { return false;} SetBPP(const int bpp)273 virtual bool SetBPP(const int bpp) { return false;} Hide()274 virtual bool Hide() { return false;} CopyRegion(DLongGDL * me)275 virtual bool CopyRegion(DLongGDL* me) { return false;} 276 277 // Z buffer device ZBuffering(bool yes)278 virtual bool ZBuffering( bool yes) { return false;} SetResolution(DLong nx,DLong ny)279 virtual bool SetResolution( DLong nx, DLong ny) { return false;} 280 // virtual bool SetCharacterSize( DLong x, DLong y) { return false;} 281 SetCharacterSize(DLong x,DLong y)282 virtual bool SetCharacterSize( DLong x, DLong y) { 283 int tagx = dStruct->Desc()->TagIndex( "X_CH_SIZE"); 284 int tagy = dStruct->Desc()->TagIndex( "Y_CH_SIZE"); 285 DLongGDL* newxch = static_cast<DLongGDL*>( dStruct->GetTag( tagx)); 286 DLongGDL* newych = static_cast<DLongGDL*>( dStruct->GetTag( tagy)); 287 (*newxch)[0]=x; 288 (*newych)[0]=y; 289 290 int tagxppcm = dStruct->Desc()->TagIndex( "X_PX_CM"); 291 int tagyppcm = dStruct->Desc()->TagIndex( "Y_PX_CM"); 292 DFloat xppm = (*static_cast<DFloatGDL*>(dStruct->GetTag(tagxppcm)))[0]*0.1; 293 DFloat yppm = (*static_cast<DFloatGDL*>(dStruct->GetTag(tagyppcm)))[0]*0.1; 294 295 PLFLT newsize=x/xppm; 296 PLFLT newSpacing=y/yppm; 297 GDLGStream* actStream=GetStream(false); 298 if( actStream != NULL) {actStream->setLineSpacing(newSpacing); actStream->RenewPlplotDefaultCharsize(newsize);} 299 return true; 300 } ClearStream(DLong bColor)301 virtual void ClearStream( DLong bColor) 302 { 303 throw GDLException( "Device "+Name()+" does not support ClearStream."); 304 } DoesNotDrawSinglePoints()305 virtual bool DoesNotDrawSinglePoints() {return false;} 306 }; 307 308 309 typedef std::vector< GDLGStream*> WindowListT; 310 311 class GraphicsMultiDevice : public GraphicsDevice { 312 private: 313 public: 314 int decomposed; // false -> use color table 315 int cursorId; //should be 3 by default. 316 long gcFunction; 317 int backingStoreMode; 318 DString fontname; 319 int staticDisplay; 320 getCursorId()321 int getCursorId(){return cursorId;} getGCFunction()322 long getGCFunction(){return gcFunction;} GetBackingStore()323 int GetBackingStore(){return backingStoreMode;} isStatic()324 bool isStatic(){return staticDisplay==1;} 325 326 static int actWin; 327 static WindowListT winList; 328 static std::vector<long> oList; 329 static int oIx; 330 static void Init(); GraphicsMultiDevice(int _decomposed,int _cursorId,long _gcFunction,int _backingStoreMode)331 GraphicsMultiDevice( int _decomposed, int _cursorId, long _gcFunction, int _backingStoreMode) : GraphicsDevice(), 332 decomposed(_decomposed), 333 cursorId(_cursorId), 334 gcFunction(_gcFunction), 335 backingStoreMode(_backingStoreMode), 336 fontname(""), 337 staticDisplay(1) 338 { 339 //pretty much nothing to do... 340 } ~GraphicsMultiDevice()341 ~GraphicsMultiDevice() { 342 WindowListT::iterator i; 343 for (i = winList.begin(); i != winList.end(); ++i) if ((*i) != NULL) {delete *i; *i = NULL; } 344 } 345 DByteGDL* WindowState(); 346 bool WState( int ix); 347 int MaxWin(); 348 void SetActWin(int wIx); 349 void TidyWindowsList(bool d=true); 350 void RaiseWin(int wIx); 351 void LowerWin(int wIx); 352 void IconicWin(int wIx); 353 void DeIconicWin(int wIx); 354 void EventHandler(); 355 bool WDelete(int wIx); 356 bool WSize(int wIx, int *xSize, int *ySize); 357 bool WSet(int wIx); 358 bool WShow(int ix, bool show, int iconic); 359 int WAddFree(); 360 GDLGStream* GetStreamAt(int wIx) const; 361 void ChangeStreamAt(int wIx, GDLGStream* newStream); 362 bool UnsetFocus(); 363 bool Decomposed(bool value); 364 DLong GetDecomposed(); GetFontnames()365 BaseGDL* GetFontnames(){ ThrowGDLException("DEVICE: Keyword GET_FONTNAMES not allowed for call to: DEVICE" );return NULL;} GetFontnum()366 DLong GetFontnum(){ ThrowGDLException("DEVICE: Keyword GET_FONTNUM not allowed for call to: DEVICE" );return 0;} SetFont(DString & f)367 bool SetFont(DString &f) {fontname=f; return true;} GetCurrentFont()368 DString GetCurrentFont() {return fontname;} 369 bool SetBackingStore(int value); 370 bool Hide(); 371 int MaxNonFreeWin(); 372 int ActWin(); 373 int GetNonManagedWidgetActWin(bool doTidyWindowList=true); 374 bool CopyRegion(DLongGDL* me); SetCharacterSize(DLong x,DLong y)375 virtual bool SetCharacterSize( DLong x, DLong y) { 376 int tagx = dStruct->Desc()->TagIndex( "X_CH_SIZE"); 377 int tagy = dStruct->Desc()->TagIndex( "Y_CH_SIZE"); 378 DLongGDL* newxch = static_cast<DLongGDL*>( dStruct->GetTag( tagx)); 379 DLongGDL* newych = static_cast<DLongGDL*>( dStruct->GetTag( tagy)); 380 (*newxch)[0]=x; 381 (*newych)[0]=y; 382 WindowListT::iterator i; 383 int tagxppcm = dStruct->Desc()->TagIndex( "X_PX_CM"); 384 int tagyppcm = dStruct->Desc()->TagIndex( "Y_PX_CM"); 385 DFloat xppm = (*static_cast<DFloatGDL*>(dStruct->GetTag(tagxppcm)))[0]*0.1; 386 DFloat yppm = (*static_cast<DFloatGDL*>(dStruct->GetTag(tagyppcm)))[0]*0.1; 387 388 PLFLT newsize=x/xppm; 389 PLFLT newSpacing=y/yppm; 390 for (i = winList.begin(); i != winList.end(); ++i) if ((*i) != NULL) {(*i)->setLineSpacing(newSpacing); (*i)->RenewPlplotDefaultCharsize(newsize);} 391 return true; 392 } 393 }; 394 395 #endif 396 397