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