X-Git-Url: http://git.kpe.io/?p=ctsim.git;a=blobdiff_plain;f=libctgraphics%2Fsgp.cpp;h=9757fe9fb03449e911e7d0fcee351488be47540a;hp=1062901737201670c32db960935990d70bc26d5e;hb=f7ee98f7d964ed361068179f0e7ea4475ed1abdf;hpb=980bef9b95bef1ab728634181a5672088fd47066 diff --git a/libctgraphics/sgp.cpp b/libctgraphics/sgp.cpp index 1062901..9757fe9 100644 --- a/libctgraphics/sgp.cpp +++ b/libctgraphics/sgp.cpp @@ -1,13 +1,13 @@ /***************************************************************************** ** FILE IDENTIFICATION ** -** Name: sgp.cpp Simple Graphics Package -** Programmer: Kevin Rosenberg +** Name: sgp.cpp Simple Graphics Package +** 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.8 2000/07/31 14:48:35 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 @@ -29,38 +29,37 @@ #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, 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, int ysize) + : m_iPhysicalXSize(xsize), m_iPhysicalYSize(ysize), m_idDriver(0), m_pDC(pDC) { - m_pDC = pDC; m_idDriver |= SGPDRIVER_WXWINDOWS; } #endif -SGPDriver::SGPDriver (const char* szWinTitle = "", int xsize = 640, int ysize = 480) +SGPDriver::SGPDriver (const char* szWinTitle, int xsize, int ysize) : m_iPhysicalXSize(xsize), m_iPhysicalYSize(ysize), m_sWindowTitle(szWinTitle), m_idDriver(0) { #ifdef HAVE_G2_H @@ -71,8 +70,10 @@ SGPDriver::SGPDriver (const char* szWinTitle = "", int xsize = 640, int ysize = SGPDriver::~SGPDriver () { - if (isG2()) +#if HAVE_G2_H + if (isG2()) g2_close (m_idG2); +#endif } @@ -80,7 +81,7 @@ SGPDriver::~SGPDriver () // SGP::SGP Constructor for Simple Graphics Package SGP::SGP (const SGPDriver& driver) - : m_driver (driver) + : m_driver (driver) { m_iPhysicalXSize = m_driver.getPhysicalXSize(); m_iPhysicalYSize = m_driver.getPhysicalYSize(); @@ -90,17 +91,61 @@ SGP::SGP (const SGPDriver& driver) ndc_to_mc.setIdentity(); m_ctm.setIdentity(); +#ifdef HAVE_WXWINDOWS + initFromDC (driver.idWX()); +#endif + setWindow (0., 0., 1., 1.); setViewport (0., 0., 1., 1.); moveAbs (0., 0.); stylusNDC (0., 0., false); - + setTextAngle (0.); - setTextSize (1. / 25.); + 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) { @@ -111,12 +156,12 @@ SGP::stylusNDC (double x, double y, bool beam) if (beam) { #if HAVE_WXWINDOWS - if (m_driver.isWX()) - m_driver.idWX()->DrawLine (m_iCurrentPhysicalX, m_iCurrentPhysicalY, xp, yp); + 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); + if (m_driver.isG2()) + g2_line (m_driver.idG2(), m_iCurrentPhysicalX, m_iCurrentPhysicalY, xp, yp); #endif } m_iCurrentPhysicalX = xp; @@ -126,18 +171,45 @@ SGP::stylusNDC (double x, double y, bool beam) void SGP::markerNDC (double x, double y) { + int xp = static_cast(x * (m_iPhysicalXSize - 1) + 0.5); + int yp = static_cast(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(x * (m_iPhysicalXSize - 1) + 0.5); + int yp = static_cast(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; } // NAME // clear Clear Window -void +void SGP::eraseWindow () { #if HAVE_G2_H @@ -145,14 +217,26 @@ 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 } // NAME -// sgp2_window Set window in world coordinates - +// sgp2_window Set window in world coordinates + void SGP::setWindow (double xmin, double ymin, double xmax, double ymax) @@ -161,7 +245,7 @@ SGP::setWindow (double xmin, double ymin, double xmax, double ymax) sys_error (ERR_WARNING, "Minimum > Maximum [sgp2_window]"); return; } - + xw_min = xmin; yw_min = ymin; xw_max = xmax; @@ -171,7 +255,7 @@ SGP::setWindow (double xmin, double ymin, double xmax, double ymax) // NAME -// sgp2_viewport Set viewport in NDC +// sgp2_viewport Set viewport in NDC void SGP::setViewport (double xmin, double ymin, double xmax, double ymax) @@ -180,39 +264,69 @@ SGP::setViewport (double xmin, double ymin, double xmax, double ymax) sys_error (ERR_WARNING, "Minimum > Maximum [sgp2_viewport]"); return; } - + xv_min = xmin; yv_min = ymin; xv_max = xmax; yv_max = ymax; m_bRecalcTransform = true; - - viewNDC[0] = xmin; // Array for clip_rect() + + viewNDC[0] = xmin; // Array for clip_rect() viewNDC[1] = ymin; viewNDC[2] = xmax; viewNDC[3] = ymax; } +void +SGP::getViewport (double& xmin, double& ymin, double& xmax, double& ymax) +{ + xmin = xv_min; + ymin = yv_min; + xmax = xv_max; + ymax = yv_max; +} + +void +SGP::getWindow (double& xmin, double& ymin, double& xmax, double& ymax) +{ + xmin = xw_min; + ymin = yw_min; + xmax = xw_max; + ymax = yw_max; +} + // NAME -// frameViewport draw box around viewport +// frameViewport draw box around viewport 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 +void SGP::setColor (int icol) { if (icol >= 0 && icol < s_iRGBColorCount) { @@ -225,31 +339,138 @@ SGP::setColor (int icol) #if HAVE_WXWINDOWS if (m_driver.isWX()) { wxColor colour (s_aRGBColor[icol].getRed(), s_aRGBColor[icol].getGreen(), s_aRGBColor[icol].getBlue()); - wxPen pen (colour, 1, wxSOLID); - m_driver.idWX()->SetPen (pen); + m_pen.SetColour (colour); + m_driver.idWX()->SetPen (m_pen); } #endif } } void -SGP::setMarker (int idMarke, int iColor) +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 idMarker) +{ + m_iMarker = idMarker; } //============================================================== -// set line style. Pass 16 bit repeating pattern +// set line style. Pass 16 bit repeating pattern //============================================================== -void +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 } //============================================================== -// absolute draw to +// absolute draw to //*============================================================== -void +void SGP::lineAbs (double x, double y) { if (m_bRecalcTransform) @@ -262,49 +483,145 @@ SGP::lineAbs (double x, double y) double x2 = x; double y2 = y; 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 + + if (clip_rect (x1, y1, x2, y2, viewNDC) == true) { // clip to viewport + stylusNDC (x1, y1, false); // move to first point + stylusNDC (x2, y2, true); // draw to second point } m_dCurrentWorldX = x; m_dCurrentWorldY = y; } -void +void SGP::moveAbs (double x, double y) { m_dCurrentWorldX = x; - m_dCurrentWorldY = y; /* moves are not clipped */ + m_dCurrentWorldY = y; /* moves are not clipped */ } -void +void SGP::lineRel (double x, double y) { lineAbs (x + m_dCurrentWorldX, y + m_dCurrentWorldY); } -void +void SGP::moveRel (double x, double y) { moveAbs (x + m_dCurrentWorldX, y + m_dCurrentWorldY); } + +// Height is in master coordinates void SGP::setTextSize (double height) { + 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)); +#endif +#if HAVE_WXWINDOWS + if (m_driver.isWX()) { + double dHeightPixels = height * m_iPhysicalYSize; + double dHeightPoints = dHeightPixels * m_dPointsPerPixel; + m_pFont->SetPointSize (nearest(dHeightPoints)); + m_driver.idWX()->SetFont (*m_pFont); + } +#endif +} + +void +SGP::setTextNDCSize (double height) +{ + double dHeightPixels = height * m_iPhysicalYSize; +#if HAVE_G2_H + if (m_driver.isG2()) + g2_set_font_size(m_driver.idG2(), nearest(dHeightPixels)); +#endif +#if HAVE_WXWINDOWS + if (m_driver.isWX()) { + double dHeightPoints = dHeightPixels * m_dPointsPerPixel; + m_pFont->SetPointSize (nearest(dHeightPoints)); + m_driver.idWX()->SetFont (*m_pFont); + } +#endif +} + +void +SGP::setTextPointSize (double height) +{ +#if HAVE_G2_H + // if (m_driver.isG2()) + // g2_set_font_size(m_driver.idG2(), (height * m_iPhysicalYSize)); +#endif +#if HAVE_WXWINDOWS + if (m_driver.isWX()) { + m_iTextPointSize = static_cast(height+0.5); + m_pFont->SetPointSize (m_iTextPointSize); + m_driver.idWX()->SetFont (*m_pFont); + } +#endif +} + +void +SGP::getTextExtent (const char* szText, double* worldW, double* worldH) +{ +#if HAVE_WXWINDOWS + if (m_driver.isWX()) { + wxCoord deviceW, deviceH; + m_driver.idWX()->GetTextExtent (wxConvCurrent->cMB2WC(szText), &deviceW, &deviceH); + if (m_dTextAngle == 90 || m_dTextAngle == -90) { + wxCoord temp = deviceW; + deviceW = deviceH; + deviceH = temp; + } + *worldW = (xw_max - xw_min) * deviceW / static_cast(m_iPhysicalXSize);; + *worldH = (yw_max - yw_min) * deviceH / static_cast(m_iPhysicalYSize); + } +#endif +} + +double +SGP::getCharHeight () +{ + double dHeight = (1. / 25.); + +#if HAVE_WXWINDOWS + if (m_driver.isWX()) { + dHeight = m_driver.idWX()->GetCharHeight(); + dHeight /= static_cast(m_iPhysicalYSize); + dHeight /= (yv_max - yv_min); // scale to viewport; + } +#endif + dHeight *= (yw_max - yw_min); // scale to world coordinates + return dHeight; +} + +double +SGP::getCharWidth () +{ + double dWidth = (1. / 80.); + +#if HAVE_WXWINDOWS + if (m_driver.isWX()) { + dWidth = m_driver.idWX()->GetCharWidth(); + dWidth /= static_cast(m_iPhysicalXSize); + dWidth /= (xv_max - xv_min); // scale to viewport + } +#endif + dWidth *= (xw_max - xw_min); //scale to world coordinates + return dWidth; } void SGP::setTextAngle (double angle) { - m_dTextAngle = angle; + m_dTextAngle = convertRadiansToDegrees(angle); } -void +void SGP::polylineAbs (double x[], double y[], int n) { if (m_bRecalcTransform) @@ -315,29 +632,29 @@ SGP::polylineAbs (double x[], double y[], int n) double x2 = x[1], y2 = y[1]; mc_to_ndc.transformPoint (&x2, &y2); - double xt = x2; // don't pass (x2,y2) to clip, we need them - double yt = y2; // as the beginning point of the next line + double xt = x2; // don't pass (x2,y2) to clip, we need them + 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++) { - x1 = x2; y1 = y2; // NDC endpoint of last line + x1 = x2; y1 = y2; // NDC endpoint of last line x2 = x[i]; y2 = y[i]; mc_to_ndc.transformPoint (&x2, &y2); 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); } } } -void +void SGP::markerAbs (double x, double y) { if (m_bRecalcTransform) @@ -346,21 +663,20 @@ SGP::markerAbs (double x, double y) double xndc = x; double yndc = y; mc_to_ndc.transformPoint (&xndc, &yndc); - markerNDC (xndc, yndc); - stylusNDC (xndc, yndc, false); // move to location + markerNDC (xndc, yndc); m_dCurrentWorldX = x; m_dCurrentWorldY = y; } -void +void SGP::markerRel (double x, double y) { markerAbs (x + m_dCurrentWorldX, y + m_dCurrentWorldY); } -void +void SGP::pointAbs (double x, double y) { if (m_bRecalcTransform) @@ -368,13 +684,12 @@ 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; } -void +void SGP::pointRel (double x, double y) { pointAbs (x + m_dCurrentWorldX, y + m_dCurrentWorldY); @@ -382,12 +697,12 @@ SGP::pointRel (double x, double y) void -SGP::drawText (const string& rsMessage) +SGP::drawText (const std::string& rsMessage) { drawText (rsMessage.c_str()); } -void +void SGP::drawText (const char *pszMessage) { if (m_bRecalcTransform) @@ -397,7 +712,7 @@ SGP::drawText (const char *pszMessage) double yndc = m_dCurrentWorldY; mc_to_ndc.transformPoint (&xndc, &yndc); - stylusNDC (xndc, yndc, false); // move to location + stylusNDC (xndc, yndc, false); // move to location #if HAVE_G2_H if (m_driver.isG2()) { @@ -406,20 +721,19 @@ SGP::drawText (const char *pszMessage) #endif #if HAVE_WXWINDOWS if (m_driver.isWX()) { - wxString str (pszMessage); - m_driver.idWX()->DrawRotatedText (str, m_iCurrentPhysicalX, m_iCurrentPhysicalY, m_dTextAngle); + m_driver.idWX()->DrawRotatedText (wxConvCurrent->cMB2WC(pszMessage), m_iCurrentPhysicalX, m_iCurrentPhysicalY, m_dTextAngle); } #endif } // NAME -// drawRect Draw box in graphics mode +// drawRect Draw box in graphics mode // // SYNOPSIS // drawbox (xmin, ymin, xmax, ymax) -// double xmin, ymin Lower left corner of box -// double xmax, ymax Upper left corner of box +// double xmin, ymin Lower left corner of box +// double xmax, ymax Upper left corner of box // // NOTES // This routine leaves the current position of graphic cursor at lower @@ -428,61 +742,61 @@ SGP::drawText (const char *pszMessage) void SGP::drawRect (double xmin, double ymin, double xmax, double ymax) { - moveAbs (xmin, ymin); - lineAbs (xmax, ymin); - lineAbs (xmax, ymax); - lineAbs (xmin, ymax); - lineAbs (xmin, ymin); + moveAbs (xmin, ymin); + lineAbs (xmax, ymin); + lineAbs (xmax, ymax); + lineAbs (xmin, ymax); + lineAbs (xmin, ymin); } // FUNCTION -// sgp2_circle - draw circle of radius r at current center - -void +// sgp2_circle - draw circle of radius r at current center + +void SGP::drawCircle (const double r) { - drawArc (0.0, 7.0, r); + drawArc (r, 0.0, TWOPI); } -// ============================================================= -// draw arc around current center. pass angles and radius +//============================================================== +// draw arc around current center. angles in radius //============================================================== -void -SGP::drawArc (double start, double stop, const double r) -{ - if ((stop-start) > 2 * PI) - stop = start + 2 * PI; - if ((start-stop) > 2 * PI) - stop = start + 2 * PI; - while (start >= stop) - stop += 2*PI; - - double x = r * cos ((double) start); - double y = r * sin ((double) start); - moveRel (x, y); // move from center to start of arc - - double theta = 5 * PI / 180; - double c = cos(theta); - double s = sin(theta); - - double angle, xp, yp; - for (angle = start; angle < stop - theta; angle += theta) { - xp = c * x - s * y; - yp = s * x + c * y; - lineRel (xp - x, yp - y); +void +SGP::drawArc (const double r, double start, double stop) +{ + if (start > stop) { + double temp = start; + start = stop; + stop = temp; + } + + double xCent = m_dCurrentWorldX; + double yCent = m_dCurrentWorldY; + + double x = r * cos (start); + double y = r * sin (start); + moveAbs (xCent + x, yCent + y); // move from center to start of arc + + 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; } - c = cos (stop - angle); - s = sin (stop - angle); - xp = c * x - s * y; - yp = s * x + c * y; - lineRel (xp - x, yp - y); + double c = cos (stop - angle); + double s = sin (stop - angle); + double xp = c * x - s * y; + double yp = s * x + c * y; + lineAbs (xCent + xp, yCent + yp); - x = r * cos ((double) stop); - y = r * sin ((double) stop); - moveRel (-x, -y); // move back to center of circle + moveAbs (xCent, yCent); // move back to center of circle } @@ -522,14 +836,14 @@ SGP::transformMCtoNDC (double xIn, double yIn, double* x, double* y) // NAME -// calc_transform Calculate transform matrices +// calc_transform Calculate transform matrices void SGP::calc_transform () { double scaleX = (xv_max - xv_min) / (xw_max - xw_min); double scaleY = (yv_max - yv_min) / (yw_max - yw_min); - + wc_to_ndc.setIdentity(); wc_to_ndc.mtx[0][0] = scaleX; wc_to_ndc.mtx[2][0] = xv_min - scaleX * xw_min; @@ -549,7 +863,7 @@ SGP::ctmClear () calc_transform(); } -void +void SGP::ctmSet (const TransformationMatrix2D& m) { m_ctm = m; @@ -567,7 +881,7 @@ SGP::preTranslate (double x, double y) } -void +void SGP::postTranslate (double x, double y) { TransformationMatrix2D m; @@ -577,7 +891,7 @@ SGP::postTranslate (double x, double y) } -void +void SGP::preScale (double sx, double sy) { TransformationMatrix2D m; @@ -587,7 +901,7 @@ SGP::preScale (double sx, double sy) } -void +void SGP::postScale (double sx, double sy) { TransformationMatrix2D m; @@ -598,7 +912,7 @@ SGP::postScale (double sx, double sy) } -void +void SGP::preRotate (double theta) { TransformationMatrix2D m; @@ -609,7 +923,7 @@ SGP::preRotate (double theta) } -void +void SGP::postRotate (double theta) { TransformationMatrix2D m; @@ -619,7 +933,7 @@ SGP::postRotate (double theta) } -void +void SGP::preShear (double shrx, double shry) { TransformationMatrix2D m; @@ -629,7 +943,7 @@ SGP::preShear (double shrx, double shry) } -void +void SGP::postShear (double shrx, double shry) { TransformationMatrix2D m; @@ -644,17 +958,30 @@ SGP::postShear (double shrx, double shry) //////////////////////////////////////////////////////////////////////// // Pixel patterns of marker symbols (1x1 to 5x5 matrix) -const unsigned char SGP::MARKER_BITMAP[MARK_COUNT][5] = -{ - {'\000', '\000', '\010', '\000', '\000'}, // small dot - {'\000', '\034', '\024', '\034', '\000'}, // empty square - {'\000', '\034', '\034', '\034', '\000'}, // filled square - {'\000', '\010', '\024', '\010', '\000'}, // empty diamond - {'\000', '\010', '\034', '\010', '\000'}, // filled diamond - {'\010', '\010', '\076', '\010', '\010'}, // cross - {'\000', '\024', '\010', '\024', '\000'}, // X - {'\034', '\042', '\042', '\042', '\034'}, // open circle - {'\034', '\076', '\076', '\076', '\034'}, // filled circle - {'\076', '\042', '\042', '\042', '\076'}, // big open square - {'\010', '\024', '\042', '\024', '\010'}, // big open diamond +const unsigned char SGP::MARKER_BITMAP[MARK_COUNT][5] = +{ + {'\000', '\000', '\010', '\000', '\000'}, // small dot + {'\000', '\034', '\024', '\034', '\000'}, // empty square + {'\000', '\034', '\034', '\034', '\000'}, // filled square + {'\000', '\010', '\024', '\010', '\000'}, // empty diamond + {'\000', '\010', '\034', '\010', '\000'}, // filled diamond + {'\010', '\010', '\076', '\010', '\010'}, // cross + {'\000', '\024', '\010', '\024', '\000'}, // X + {'\034', '\042', '\042', '\042', '\034'}, // open circle + {'\034', '\076', '\076', '\076', '\034'}, // filled circle + {'\076', '\042', '\042', '\042', '\076'}, // big open square + {'\010', '\024', '\042', '\024', '\010'}, // big open diamond }; + + +#if HAVE_WXWINDOWS +void +SGP::setDC (wxDC* pDC) +{ + if (m_driver.isWX()) { + m_driver.setDC(pDC); + initFromDC (pDC); + setTextPointSize (m_iTextPointSize); + } +} +#endif