r185: *** empty log message ***
[ctsim.git] / libctgraphics / sgp.cpp
index e1a1142e8448a476252010fe899b8cb4614eb8c9..52a2430ad942d98d0f63d2b934a671db10b5f6d0 100644 (file)
@@ -7,7 +7,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: sgp.cpp,v 1.5 2000/07/28 08:28:08 kevin Exp $
+**  $Id: sgp.cpp,v 1.11 2000/08/27 20:32:55 kevin Exp $
 **
 **  This program is free software; you can redistribute it and/or modify
 **  it under the terms of the GNU General Public License (version 2) as
 #include "sgp.h"
 
 
+RGBColor SGP::s_aRGBColor[] =
+{
+  RGBColor (0, 0, 0),
+  RGBColor (0, 0, 128),
+  RGBColor (0, 128, 0),
+  RGBColor (0, 128, 128),
+  RGBColor (128, 0, 0),
+  RGBColor (128, 0, 128),
+  RGBColor (128, 128, 0),
+  RGBColor (80, 80, 80),
+  RGBColor (160, 160, 160),
+  RGBColor (0, 0, 255),
+  RGBColor (0, 255, 0),
+  RGBColor (0, 255, 255),
+  RGBColor (255, 0, 0),
+  RGBColor (255, 0, 255),
+  RGBColor (255, 255, 0),
+  RGBColor (255, 255, 255),
+};
+
+int SGP::s_iRGBColorCount = sizeof(s_aRGBColor) / sizeof(class RGBColor);
 
 #ifdef HAVE_WXWINDOWS
-SGPDriver::SGPDriver (wxDC* pDC, const char* szWinTitle = "", int xsize = 640, int ysize = 480)
-  : m_iPhysicalXSize(xsize), m_iPhysicalYSize(ysize), m_sWindowTitle(szWinTitle), m_idDriver(0)
+SGPDriver::SGPDriver (wxDC* pDC, int xsize = 640, int ysize = 480)
+  : m_iPhysicalXSize(xsize), m_iPhysicalYSize(ysize), m_idDriver(0)
 {
   m_pDC = pDC;
   m_idDriver |= SGPDRIVER_WXWINDOWS;
@@ -69,27 +90,40 @@ SGP::SGP (const SGPDriver& driver)
   ndc_to_mc.setIdentity();
   m_ctm.setIdentity();
 
+#if HAVE_WXWINDOWS
+  m_pen.SetWidth(1);
+  m_pen.SetStyle(wxSOLID);
+#endif
+
   setWindow (0., 0., 1., 1.);
   setViewport (0., 0., 1., 1.);
   moveAbs (0., 0.);
-  m_iCurrentPhysicalX = 0;
-  m_iCurrentPhysicalY = 0;
+  stylusNDC (0., 0., false);
  
   setTextAngle (0.);
   setTextSize (1. / 25.);
+  setColor (C_BLACK);
+
 }
 
 
 void
 SGP::stylusNDC (double x, double y, bool beam)
 {
-  int xp = static_cast<int>(x * m_iPhysicalXSize + 0.5);
-  int yp = static_cast<int>(y * m_iPhysicalYSize + 0.5);
+  int xp = static_cast<int>(x * (m_iPhysicalXSize - 1) + 0.5);
+  int yp = static_cast<int>(y * (m_iPhysicalYSize - 1) + 0.5);
+  if (m_driver.isWX())
+    yp = m_iPhysicalYSize - yp;
+
   if (beam) {
+#if HAVE_WXWINDOWS
       if (m_driver.isWX())
          m_driver.idWX()->DrawLine (m_iCurrentPhysicalX, m_iCurrentPhysicalY, xp, yp);
+#endif
+#if HAVE_G2_H
       if (m_driver.isG2())
          g2_line (m_driver.idG2(), m_iCurrentPhysicalX, m_iCurrentPhysicalY, xp, yp);
+#endif
   }
   m_iCurrentPhysicalX = xp;
   m_iCurrentPhysicalY = yp;
@@ -112,10 +146,14 @@ SGP::pointNDC (double x, double y)
 void 
 SGP::eraseWindow ()
 {
+#if HAVE_G2_H
   if (m_driver.isG2())
     g2_clear (m_driver.idG2());
+#endif
+#if HAVE_WXWINDOWS
   if (m_driver.isWX())
     m_driver.idWX()->Clear();
+#endif
 }
 
 // NAME
@@ -168,23 +206,126 @@ SGP::setViewport (double xmin, double ymin, double xmax, double ymax)
 void
 SGP::frameViewport (void)
 {
-  stylusNDC (xv_min, yv_min, 0);
-  stylusNDC (xv_max, yv_min, 1);
-  stylusNDC (xv_max, yv_max, 1);
-  stylusNDC (xv_min, yv_max, 1);
-  stylusNDC (xv_min, yv_min, 1);
+  stylusNDC (xv_min, yv_min, false);
+  stylusNDC (xv_max, yv_min, true);
+  stylusNDC (xv_max, yv_max, true);
+  stylusNDC (xv_min, yv_max, true);
+  stylusNDC (xv_min, yv_min, true);
 }
 
 void
 SGP::setTextColor (int iFGcolor, int iBGcolor)
 {
+#if HAVE_WXWINDOWS
+  if (m_driver.isWX()) {
+    if (iFGcolor >= 0) {
+      wxColor colour (s_aRGBColor[iFGcolor].getRed(), s_aRGBColor[iFGcolor].getGreen(), s_aRGBColor[iFGcolor].getBlue());
+      m_driver.idWX()->SetTextForeground (colour);
+    }
+    if (iBGcolor >= 0) {
+      wxColor colour (s_aRGBColor[iBGcolor].getRed(), s_aRGBColor[iBGcolor].getGreen(), s_aRGBColor[iBGcolor].getBlue());
+      m_driver.idWX()->SetTextBackground (colour);
+    }
+  }
+#endif
 }
 
 void 
 SGP::setColor (int icol)
 {
+  if (icol >= 0 && icol < s_iRGBColorCount) {
+#if HAVE_G2_H
+    if (m_driver.isG2()) {
+      int iInk = g2_ink (m_driver.idG2(), s_aRGBColor[icol].getRed() / 255., s_aRGBColor[icol].getGreen() / 255., s_aRGBColor[icol].getBlue() / 255.);
+      g2_pen (m_driver.idG2(), iInk);
+    }
+#endif
+#if HAVE_WXWINDOWS
+    if (m_driver.isWX()) {
+      wxColor colour (s_aRGBColor[icol].getRed(), s_aRGBColor[icol].getGreen(), s_aRGBColor[icol].getBlue());
+      m_pen.SetColour (colour);
+      m_driver.idWX()->SetPen (m_pen);
+    }
+#endif
+  }
 }
 
+void 
+SGP::setPenWidth (int iWidth)
+{
+  if (iWidth >= 0) {
+#if HAVE_WXWINDOWS
+    if (m_driver.isWX()) {
+      m_pen.SetWidth (iWidth);
+      m_driver.idWX()->SetPen (m_pen);
+    }
+#endif
+  }
+}
+
+void
+SGP::setRasterOp (int ro)
+{
+#if HAVE_WXWINDOWS
+  if (m_driver.isWX()) {
+    int wxFxn = -1;
+    switch (ro) {
+    case RO_AND:
+      wxFxn = wxAND;
+      break;
+    case RO_AND_INVERT:
+      wxFxn = wxAND_INVERT;
+      break;
+    case RO_AND_REVERSE:
+      wxFxn = wxAND_REVERSE;
+      break;
+    case RO_CLEAR:
+      wxFxn = wxCLEAR;
+      break;
+    case RO_COPY:
+      wxFxn = wxCOPY;
+      break;
+    case RO_EQUIV:
+      wxFxn = wxEQUIV;
+      break;
+    case RO_INVERT:
+      wxFxn = wxINVERT;
+      break;
+    case RO_NAND:
+      wxFxn = wxNAND;
+      break;
+    case RO_NOR:
+      wxFxn = wxNOR;
+      break;
+    case RO_NO_OP:
+      wxFxn = wxNO_OP;
+      break;
+    case RO_OR:
+      wxFxn = wxOR;
+      break;
+    case RO_OR_INVERT:
+      wxFxn = wxOR_INVERT;
+      break;
+    case RO_OR_REVERSE:
+      wxFxn = wxOR_REVERSE;
+      break;
+    case RO_SET:
+      wxFxn = wxSET;
+      break;
+    case RO_SRC_INVERT:
+      wxFxn = wxSRC_INVERT;
+      break;
+    case RO_XOR:
+      wxFxn = wxXOR;
+      break;
+    }
+    if (wxFxn >= 0)
+      m_driver.idWX()->SetLogicalFunction (wxFxn);
+  }
+#endif
+}
+
+
 void
 SGP::setMarker (int idMarke, int iColor)
 {
@@ -214,11 +355,11 @@ SGP::lineAbs (double x, double y)
 
   double x2 = x;
   double y2 = y;
-  mc_to_ndc.transformPoint (&x1, &y2);
+  mc_to_ndc.transformPoint (&x2, &y2);
   
   if (clip_rect (x1, y1, x2, y2, viewNDC) == true) { // clip to viewport 
-    stylusNDC (x1, y1, 0);  // move to first point
-    stylusNDC (x2, y2, 1);  // draw to second point 
+    stylusNDC (x1, y1, false);  // move to first point
+    stylusNDC (x2, y2, true);  // draw to second point 
   }
 
   m_dCurrentWorldX = x;
@@ -251,6 +392,37 @@ SGP::setTextSize (double height)
     g2_set_font_size(m_driver.idG2(), (height * m_iPhysicalYSize));
 }
 
+void
+SGP::getTextExtent (const char* szText, double* worldW, double* worldH)
+{
+#if HAVE_WXWINDOWS
+  if (m_driver.isWX()) {
+    wxString sText (szText);
+    wxCoord deviceW, deviceH;
+    m_driver.idWX()->GetTextExtent (sText, &deviceW, &deviceH);
+    *worldW = static_cast<double>(deviceW) / static_cast<double>(m_iPhysicalXSize);;
+    *worldH = static_cast<double>(deviceH) / static_cast<double>(m_iPhysicalYSize);
+    //    cout << deviceW << ", " << deviceH << ", " << *worldW << ", " << *worldH << endl;
+    *worldW *= (xw_max - xw_min);
+    *worldH *= (yw_max - yw_min);
+  }
+#endif
+}
+
+double
+SGP::getCharHeight ()
+{
+  double dHeight = (1. / 25.);
+
+#if HAVE_WXWINDOWS
+  if (m_driver.isWX()) {
+    dHeight = m_driver.idWX()->GetCharHeight();
+    dHeight /= static_cast<double>(m_iPhysicalYSize);;
+  }
+#endif
+    return (dHeight * (xw_max - xw_min));
+}
+
 void
 SGP::setTextAngle (double angle)
 {
@@ -272,8 +444,8 @@ SGP::polylineAbs (double x[], double y[], int n)
   double yt = y2;      // as the beginning point of the next line 
 
   if (clip_rect (x1, y1, xt, yt, viewNDC)) {
-    stylusNDC (x1, y1, 0);
-    stylusNDC (xt, yt, 1);
+    stylusNDC (x1, y1, false);
+    stylusNDC (xt, yt, true);
   }
   
   for (int i = 2; i < n; i++) {
@@ -283,8 +455,8 @@ SGP::polylineAbs (double x[], double y[], int n)
     xt = x2;
     yt = y2;
     if (clip_rect (x1, y1, xt, yt, viewNDC)) {
-      stylusNDC (x1, y1, 0);
-      stylusNDC (xt, yt, 1);
+      stylusNDC (x1, y1, false);
+      stylusNDC (xt, yt, true);
     }
   }
 }
@@ -352,12 +524,17 @@ SGP::drawText (const char *pszMessage)
 
   stylusNDC (xndc, yndc, false);            // move to location 
 
+#if HAVE_G2_H
   if (m_driver.isG2()) {
-    if (m_dTextAngle == 0.)
-      g2_string (m_driver.idG2(), m_iCurrentPhysicalX, m_iCurrentPhysicalY, const_cast<char*>(pszMessage));
+    g2_string (m_driver.idG2(), m_iCurrentPhysicalX, m_iCurrentPhysicalY, const_cast<char*>(pszMessage));
   }
+#endif
+#if HAVE_WXWINDOWS
   if (m_driver.isWX()) {
+    wxString str (pszMessage);
+    m_driver.idWX()->DrawRotatedText (str, m_iCurrentPhysicalX, m_iCurrentPhysicalY, m_dTextAngle);
   }
+#endif
 }
 
 
@@ -389,7 +566,7 @@ SGP::drawRect (double xmin, double ymin, double xmax, double ymax)
 void 
 SGP::drawCircle (const double r)
 {
-       drawArc (0.0, 7.0, r);
+       drawArc (r, 0.0, 7.0);
 }
 
 // =============================================================
@@ -397,7 +574,7 @@ SGP::drawCircle (const double r)
 //==============================================================
 
 void 
-SGP::drawArc (double start, double stop, const double r)
+SGP::drawArc (const double r, double start, double stop)
 {
   if ((stop-start) > 2 * PI)
     stop = start + 2 * PI;