r7061: initial property settings
[ctsim.git] / libctgraphics / sgp.cpp
index f22dd378300339355e4757e1b88a93d6222a269d..65095c8968e062ef4b3b7f99943a924e2ae3c6a7 100644 (file)
@@ -5,9 +5,9 @@
 **     Programmer: Kevin Rosenberg
 **
 **  This is part of the CTSim program
-**  Copyright (C) 1983-2000 Kevin Rosenberg
+**  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: sgp.cpp,v 1.19 2000/12/18 02:23:43 kevin Exp $
+**  $Id$
 **
 **  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),
+SGP_RGBColor SGP::s_aRGBColor[] =
+{
+  SGP_RGBColor (0, 0, 0),
+  SGP_RGBColor (0, 0, 128),
+  SGP_RGBColor (0, 128, 0),
+  SGP_RGBColor (0, 128, 128),
+  SGP_RGBColor (128, 0, 0),
+  SGP_RGBColor (128, 0, 128),
+  SGP_RGBColor (128, 128, 0),
+  SGP_RGBColor (80, 80, 80),
+  SGP_RGBColor (160, 160, 160),
+  SGP_RGBColor (0, 0, 255),
+  SGP_RGBColor (0, 255, 0),
+  SGP_RGBColor (0, 255, 255),
+  SGP_RGBColor (255, 0, 0),
+  SGP_RGBColor (255, 0, 255),
+  SGP_RGBColor (255, 255, 0),
+  SGP_RGBColor (255, 255, 255),
 };
 
-int SGP::s_iRGBColorCount = sizeof(s_aRGBColor) / sizeof(class RGBColor);
+int SGP::s_iRGBColorCount = sizeof(s_aRGBColor) / sizeof(class SGP_RGBColor);
 
 #ifdef HAVE_WXWINDOWS
 SGPDriver::SGPDriver (wxDC* pDC, int xsize, int ysize)
@@ -91,21 +91,8 @@ SGP::SGP (const SGPDriver& driver)
   ndc_to_mc.setIdentity();
   m_ctm.setIdentity();
 
-#if HAVE_WXWINDOWS
-  m_pen.SetWidth(1);
-  m_pen.SetStyle(wxSOLID);
-
-  if (m_driver.isWX()) {
-    static const double dScreenDPI = 82;
-    static const double dPointsPerInch = 72.;
-    m_dPointsPerPixel = dPointsPerInch / dScreenDPI;
-    const int iTestPointSize = 72;
-    m_font.SetPointSize (iTestPointSize);
-    m_driver.idWX()->SetFont(m_font);
-    double dTestCharHeight = m_driver.idWX()->GetCharHeight();
-    m_dPointsPerPixel = iTestPointSize / dTestCharHeight;\r
-       m_driver.idWX()->SetBrush (*wxWHITE_BRUSH);
-  }
+#ifdef HAVE_WXWINDOWS
+  initFromDC (driver.idWX());
 #endif
 
   setWindow (0., 0., 1., 1.);
@@ -116,9 +103,49 @@ SGP::SGP (const SGPDriver& driver)
   setTextAngle (0.);
   setTextPointSize (12);
   setColor (C_BLACK);
+  setLineStyle (LS_SOLID);
+  setMarker (MARKER_POINT);
+}
+
+
+#ifdef HAVE_WXWINDOWS
+void
+SGP::initFromDC (wxDC* pDC)
+{
+  m_pen.SetWidth (1);
+
+  if (m_driver.isWX()) {
+    static const double dScreenDPI = 82;
+    static const double dPointsPerInch = 72.;
+    m_dPointsPerPixel = dPointsPerInch / dScreenDPI;
+    const int iTestPointSize = 12;
+    m_pFont = new wxFont (wxROMAN, wxNORMAL, wxNORMAL, wxNORMAL);
+    m_pFont->SetPointSize (iTestPointSize);
+    m_pFont->SetWeight (wxNORMAL);
+    m_pFont->SetStyle (wxNORMAL);
+    m_pFont->SetFamily (wxROMAN);
+#ifdef MSVC
+    m_pFont->SetFaceName(wxString("times new roman"));
+#endif
+    m_driver.idWX()->SetFont (*m_pFont);
+    double dTestCharHeight = m_driver.idWX()->GetCharHeight();
+    m_dPointsPerPixel = iTestPointSize / dTestCharHeight;
+       m_driver.idWX()->SetBackground (*wxWHITE_BRUSH);
+  }
 }
+#endif
 
 
+SGP::~SGP()
+{
+#if HAVE_WXWINDOWS
+  if (m_driver.isWX()) {
+ //   m_driver.idWX()->SetFont (wxNullFont);
+    delete m_pFont;
+  }
+#endif
+}
+
 void
 SGP::stylusNDC (double x, double y, bool beam)
 {
@@ -144,11 +171,38 @@ SGP::stylusNDC (double x, double y, bool beam)
 void
 SGP::markerNDC (double x, double y)
 {
+  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 HAVE_WXWINDOWS
+  if (m_driver.isWX()) {
+      m_driver.idWX()->DrawPoint (xp, yp);
+      m_driver.idWX()->DrawPoint (xp-1, yp-1);
+      m_driver.idWX()->DrawPoint (xp+1, yp+1);
+      m_driver.idWX()->DrawPoint (xp+1, yp-1);
+      m_driver.idWX()->DrawPoint (xp-1, yp+1);
+  }
+#endif
+  m_iCurrentPhysicalX = xp;
+  m_iCurrentPhysicalY = yp;
 }
 
 void
 SGP::pointNDC (double x, double y)
 {
+  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 HAVE_WXWINDOWS
+    if (m_driver.isWX())
+      m_driver.idWX()->DrawPoint (xp, yp);
+#endif
+  m_iCurrentPhysicalX = xp;
+  m_iCurrentPhysicalY = yp;
 }
 
 
@@ -163,8 +217,20 @@ SGP::eraseWindow ()
     g2_clear (m_driver.idG2());
 #endif
 #if HAVE_WXWINDOWS
-  if (m_driver.isWX())
-    m_driver.idWX()->Clear();
+  if (m_driver.isWX()) {
+       wxBrush brushWhite;
+       brushWhite.SetColour(255,255,255);
+       m_driver.idWX()->SetBackground(brushWhite);
+       m_driver.idWX()->Clear();
+       m_driver.idWX()->SetBackground(wxNullBrush);
+#if 1
+       wxPen pen;
+       pen.SetColour(255,255,255);
+       m_driver.idWX()->SetBrush (brushWhite);
+       m_driver.idWX()->DrawRectangle (0, 0, m_iPhysicalXSize, m_iPhysicalYSize);
+       m_driver.idWX()->SetBrush (wxNullBrush);
+#endif
+  }
 #endif
 }
 
@@ -357,8 +423,9 @@ SGP::setRasterOp (int ro)
 
 
 void
-SGP::setMarker (int idMarke, int iColor)
+SGP::setMarker (int idMarker)
 {
+  m_iMarker = idMarker;
 }
 
 //==============================================================
@@ -367,6 +434,36 @@ SGP::setMarker (int idMarke, int iColor)
 void 
 SGP::setLineStyle (int style)
 {
+  m_iLinestyle = style;
+
+#if HAVE_WXWINDOWS
+  if (m_driver.isWX()) {
+    switch (m_iLinestyle) {
+    case LS_SOLID:
+      m_pen.SetStyle (wxSOLID);
+      break;
+    case LS_DASH1:
+      m_pen.SetStyle (wxLONG_DASH);
+      break;
+    case LS_DASH2:
+      m_pen.SetStyle (wxSHORT_DASH);
+      break;
+    case LS_DASH3:
+      m_pen.SetStyle (wxDOT_DASH);
+      break;
+    case LS_DASH4:
+      m_pen.SetStyle (wxCROSS_HATCH);
+      break;
+    case LS_DOTTED:
+      m_pen.SetStyle (wxDOT);
+      break;
+    default:
+      m_pen.SetStyle (wxSOLID);
+      break;
+    }
+    m_driver.idWX()->SetPen (m_pen);
+  }
+#endif
 }
 
 //==============================================================
@@ -420,7 +517,7 @@ SGP::moveRel (double x, double y)
 void
 SGP::setTextSize (double height)
 {
-    height /= (xw_max - xw_min);
+    height /= (yw_max - yw_min);  // convert to NDC
 #if HAVE_G2_H
   if (m_driver.isG2())
     g2_set_font_size(m_driver.idG2(), (height * m_iPhysicalYSize));
@@ -429,8 +526,8 @@ SGP::setTextSize (double height)
   if (m_driver.isWX()) {
       double dHeightPixels = height * m_iPhysicalYSize;
       double dHeightPoints = dHeightPixels * m_dPointsPerPixel;
-      m_font.SetPointSize (nearest<int>(dHeightPoints));
-      m_driver.idWX()->SetFont (m_font);
+      m_pFont->SetPointSize (nearest<int>(dHeightPoints));
+      m_driver.idWX()->SetFont (*m_pFont);
   }
 #endif
 }
@@ -446,8 +543,8 @@ SGP::setTextNDCSize (double height)
 #if HAVE_WXWINDOWS
   if (m_driver.isWX()) {
       double dHeightPoints = dHeightPixels * m_dPointsPerPixel;
-      m_font.SetPointSize (nearest<int>(dHeightPoints));
-      m_driver.idWX()->SetFont (m_font);
+      m_pFont->SetPointSize (nearest<int>(dHeightPoints));
+      m_driver.idWX()->SetFont (*m_pFont);
   }
 #endif
 }
@@ -461,8 +558,9 @@ SGP::setTextPointSize (double height)
 #endif
 #if HAVE_WXWINDOWS
   if (m_driver.isWX()) {
-      m_font.SetPointSize (static_cast<int>(height+0.5));
-      m_driver.idWX()->SetFont (m_font);
+    m_iTextPointSize = static_cast<int>(height+0.5);
+      m_pFont->SetPointSize (m_iTextPointSize);
+      m_driver.idWX()->SetFont (*m_pFont);
   }
 #endif
 }
@@ -475,10 +573,13 @@ SGP::getTextExtent (const char* szText, double* worldW, double* worldH)
     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);
-    *worldW *= (xw_max - xw_min);
-    *worldH *= (yw_max - yw_min);
+    if (m_dTextAngle == 90 || m_dTextAngle == -90) {
+      wxCoord temp = deviceW;
+      deviceW = deviceH;
+      deviceH = temp;
+    }
+    *worldW = (xw_max - xw_min) * deviceW / static_cast<double>(m_iPhysicalXSize);;
+    *worldH = (yw_max - yw_min) * deviceH / static_cast<double>(m_iPhysicalYSize);
   }
 #endif
 }
@@ -492,9 +593,10 @@ SGP::getCharHeight ()
   if (m_driver.isWX()) {
     dHeight = m_driver.idWX()->GetCharHeight();
     dHeight /= static_cast<double>(m_iPhysicalYSize);
+         dHeight /= (yv_max - yv_min); // scale to viewport;
   }
 #endif
-  dHeight *= (yw_max - yw_min);
+  dHeight *= (yw_max - yw_min);  // scale to world coordinates
   return dHeight;
 }
 
@@ -507,9 +609,10 @@ SGP::getCharWidth ()
   if (m_driver.isWX()) {
     dWidth = m_driver.idWX()->GetCharWidth();
     dWidth /= static_cast<double>(m_iPhysicalXSize);
+         dWidth /= (xv_max - xv_min); // scale to viewport
   }
 #endif
-  dWidth *= (xw_max - xw_min);
+  dWidth *= (xw_max - xw_min); //scale to world coordinates
   return dWidth;
 }
 
@@ -562,7 +665,6 @@ SGP::markerAbs (double x, double y)
   double yndc = y;
   mc_to_ndc.transformPoint (&xndc, &yndc);
   markerNDC (xndc, yndc); 
-  stylusNDC (xndc, yndc, false);            // move to location 
   m_dCurrentWorldX = x;
   m_dCurrentWorldY = y;
 }
@@ -583,7 +685,6 @@ SGP::pointAbs (double x, double y)
   double xndc = x, yndc = y;
   mc_to_ndc.transformPoint (&xndc, &yndc);
   pointNDC (xndc, yndc);
-  stylusNDC (xndc, yndc, false);            // move to location 
   m_dCurrentWorldX = x;
   m_dCurrentWorldY = y;
 }
@@ -672,31 +773,32 @@ SGP::drawArc (const double r, double start, double stop)
     stop = temp;
   }
 
-  double x = r * cos ((double) start);
-  double y = r * sin ((double) start);
-  moveRel (x, y);          // move from center to start of arc 
+  double xCent = m_dCurrentWorldX;
+  double yCent = m_dCurrentWorldY;
 
-  const double thetaIncrement = (5 * (TWOPI / 360)); 
-  double cosTheta = cos(thetaIncrement);
-  double sinTheta = sin(thetaIncrement);
+  double x = r * cos (start);
+  double y = r * sin (start);
+  moveAbs (xCent + x, yCent + y);          // move from center to start of arc 
 
-  double angle, xp, yp;
-  for (angle = start; angle < stop - thetaIncrement; angle += thetaIncrement) {
-    xp = cosTheta * x - sinTheta * y; // translate point by thetaIncrement
-    yp = sinTheta * x + cosTheta * y;
-    lineAbs (xp, yp);
+  const double thetaIncrement = (5 * (TWOPI / 360));  // 5 degree increments
+  double cosTheta = cos (thetaIncrement);
+  double sinTheta = sin (thetaIncrement);
+
+  double angle;
+  for (angle = start; angle < stop; angle += thetaIncrement) {
+    double xp = cosTheta * x - sinTheta * y; // translate point by thetaIncrement
+    double yp = sinTheta * x + cosTheta * y;
+    lineAbs (xCent + xp, yCent + yp);
     x = xp; y = yp;
   }
 
   double c = cos (stop - angle);
   double s = sin (stop - angle);
-  xp = c * x - s * y;
-  yp = s * x + c * y;
-  lineAbs (xp, yp);
+  double xp = c * x - s * y;
+  double yp = s * x + c * y;
+  lineAbs (xCent + xp, yCent + yp);
 
-  x = r * cos (stop);
-  y = r * sin (stop);
-  moveRel (-x, -y);            // move back to center of circle 
+  moveAbs (xCent, yCent);              // move back to center of circle 
 }
 
 
@@ -878,7 +980,10 @@ const unsigned char SGP::MARKER_BITMAP[MARK_COUNT][5] =
 void
 SGP::setDC (wxDC* pDC)
 {
-  if (m_driver.isWX())
+  if (m_driver.isWX()) {
     m_driver.setDC(pDC);
+    initFromDC (pDC);
+    setTextPointSize (m_iTextPointSize);
+  }
 }
 #endif