From: Vadim Zeitlin Date: Sat, 2 Feb 2002 16:08:14 +0000 (+0000) Subject: 1. fixed bug in wxDC::SetMapMode() which broke the scrolling X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/1e2081a1b9962f3d58afce7b45845ba7956d3c20 1. fixed bug in wxDC::SetMapMode() which broke the scrolling 2. some cleanups in wxDC code 3. SetAxisOrientation() still doesn't work... git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@13972 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/msw/dc.h b/include/wx/msw/dc.h index bdb94b9116..9087250fe7 100644 --- a/include/wx/msw/dc.h +++ b/include/wx/msw/dc.h @@ -23,54 +23,6 @@ // macros // --------------------------------------------------------------------------- -// Logical to device -// Absolute -#define XLOG2DEV(x) (x) -#define YLOG2DEV(y) (y) - -// Relative -#define XLOG2DEVREL(x) (x) -#define YLOG2DEVREL(y) (y) - -// Device to logical -// Absolute -#define XDEV2LOG(x) (x) - -#define YDEV2LOG(y) (y) - -// Relative -#define XDEV2LOGREL(x) (x) -#define YDEV2LOGREL(y) (y) - -/* - * Have the same macros as for XView but not for every operation: - * just for calculating window/viewport extent (a better way of scaling). - */ - -// Logical to device -// Absolute -#define MS_XLOG2DEV(x) LogicalToDevice(x) - -#define MS_YLOG2DEV(y) LogicalToDevice(y) - -// Relative -#define MS_XLOG2DEVREL(x) LogicalToDeviceXRel(x) -#define MS_YLOG2DEVREL(y) LogicalToDeviceYRel(y) - -// Device to logical -// Absolute -#define MS_XDEV2LOG(x) DeviceToLogicalX(x) - -#define MS_YDEV2LOG(y) DeviceToLogicalY(y) - -// Relative -#define MS_XDEV2LOGREL(x) DeviceToLogicalXRel(x) -#define MS_YDEV2LOGREL(y) DeviceToLogicalYRel(y) - -#define YSCALE(y) (yorigin - (y)) - -#define wx_round(a) (int)((a)+.5) - #if wxUSE_DC_CACHEING /* * Cached blitting, maintaining a cache @@ -239,8 +191,7 @@ protected: void SetClippingHrgn(WXHRGN hrgn); // MSW-specific member variables - int m_windowExtX; - int m_windowExtY; + // ----------------------------- // the window associated with this DC (may be NULL) wxWindow *m_canvas; diff --git a/src/msw/dc.cpp b/src/msw/dc.cpp index c222cbbf4c..f4aeebe02b 100644 --- a/src/msw/dc.cpp +++ b/src/msw/dc.cpp @@ -77,6 +77,25 @@ static const int MM_METRIC = 10; // MSDN docs for how this and other numbers in wxDC::Blit() are obtained) #define DSTCOPY 0x00AA0029 // a.k.a. NOP operation +// ---------------------------------------------------------------------------- +// macros for logical <-> device coords conversion +// ---------------------------------------------------------------------------- + +/* + We currently let Windows do all the translations itself so these macros are + not really needed (any more) but keep them to enhance readability of the + code by allowing to see where are the logical and where are the device + coordinates used. + */ + +// logical to device +#define XLOG2DEV(x) (x) +#define YLOG2DEV(y) (y) + +// device to logical +#define XDEV2LOG(x) (x) +#define YDEV2LOG(y) (y) + // --------------------------------------------------------------------------- // private functions // --------------------------------------------------------------------------- @@ -184,12 +203,8 @@ wxDC::wxDC() m_bOwnsDC = FALSE; m_hDC = 0; - - m_windowExtX = VIEWPORT_EXTENT; - m_windowExtY = VIEWPORT_EXTENT; } - wxDC::~wxDC() { if ( m_hDC != 0 ) @@ -437,14 +452,17 @@ void wxDC::Clear() (void) ::SetMapMode(GetHdc(), MM_TEXT); - DWORD colour = GetBkColor(GetHdc()); - HBRUSH brush = CreateSolidBrush(colour); - FillRect(GetHdc(), &rect, brush); - DeleteObject(brush); + DWORD colour = ::GetBkColor(GetHdc()); + HBRUSH brush = ::CreateSolidBrush(colour); + ::FillRect(GetHdc(), &rect, brush); + ::DeleteObject(brush); + + int width = DeviceToLogicalXRel(VIEWPORT_EXTENT)*m_signX, + height = DeviceToLogicalYRel(VIEWPORT_EXTENT)*m_signY; ::SetMapMode(GetHdc(), MM_ANISOTROPIC); ::SetViewportExtEx(GetHdc(), VIEWPORT_EXTENT, VIEWPORT_EXTENT, NULL); - ::SetWindowExtEx(GetHdc(), m_windowExtX, m_windowExtY, NULL); + ::SetWindowExtEx(GetHdc(), width, height, NULL); ::SetViewportOrgEx(GetHdc(), (int)m_deviceOriginX, (int)m_deviceOriginY, NULL); ::SetWindowOrgEx(GetHdc(), (int)m_logicalOriginX, (int)m_logicalOriginY, NULL); } @@ -524,10 +542,6 @@ void wxDC::DoDrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2) (void)MoveToEx(GetHdc(), XLOG2DEV(x1), YLOG2DEV(y1), NULL); (void)LineTo(GetHdc(), XLOG2DEV(x2), YLOG2DEV(y2)); - // Normalization: Windows doesn't draw the last point of the line. - // But apparently neither does GTK+, so we take it out again. -// (void)LineTo(GetHdc(), XLOG2DEV(x2) + 1, YLOG2DEV(y2)); - CalcBoundingBox(x1, y1); CalcBoundingBox(x2, y2); } @@ -1423,7 +1437,7 @@ wxCoord wxDC::GetCharHeight() const GetTextMetrics(GetHdc(), &lpTextMetric); - return YDEV2LOGREL(lpTextMetric.tmHeight); + return lpTextMetric.tmHeight; } wxCoord wxDC::GetCharWidth() const @@ -1436,7 +1450,7 @@ wxCoord wxDC::GetCharWidth() const GetTextMetrics(GetHdc(), &lpTextMetric); - return XDEV2LOGREL(lpTextMetric.tmAveCharWidth); + return lpTextMetric.tmAveCharWidth; } void wxDC::DoGetTextExtent(const wxString& string, wxCoord *x, wxCoord *y, @@ -1472,10 +1486,14 @@ void wxDC::DoGetTextExtent(const wxString& string, wxCoord *x, wxCoord *y, GetTextExtentPoint(GetHdc(), string, string.length(), &sizeRect); GetTextMetrics(GetHdc(), &tm); - if (x) *x = XDEV2LOGREL(sizeRect.cx); - if (y) *y = YDEV2LOGREL(sizeRect.cy); - if (descent) *descent = tm.tmDescent; - if (externalLeading) *externalLeading = tm.tmExternalLeading; + if (x) + *x = sizeRect.cx; + if (y) + *y = sizeRect.cy; + if (descent) + *descent = tm.tmDescent; + if (externalLeading) + *externalLeading = tm.tmExternalLeading; if ( hfontOld ) { @@ -1491,68 +1509,67 @@ void wxDC::SetMapMode(int mode) m_mappingMode = mode; - int pixel_width = 0; - int pixel_height = 0; - int mm_width = 0; - int mm_height = 0; - - pixel_width = GetDeviceCaps(GetHdc(), HORZRES); - pixel_height = GetDeviceCaps(GetHdc(), VERTRES); - mm_width = GetDeviceCaps(GetHdc(), HORZSIZE); - mm_height = GetDeviceCaps(GetHdc(), VERTSIZE); - - if ((pixel_width == 0) || (pixel_height == 0) || (mm_width == 0) || (mm_height == 0)) + if ( mode == wxMM_TEXT ) { - return; + m_logicalScaleX = + m_logicalScaleY = 1.0; } - - double mm2pixelsX = pixel_width/mm_width; - double mm2pixelsY = pixel_height/mm_height; - - switch (mode) + else // need to do some calculations { - case wxMM_TWIPS: - { - m_logicalScaleX = (twips2mm * mm2pixelsX); - m_logicalScaleY = (twips2mm * mm2pixelsY); - break; - } - case wxMM_POINTS: - { - m_logicalScaleX = (pt2mm * mm2pixelsX); - m_logicalScaleY = (pt2mm * mm2pixelsY); - break; - } - case wxMM_METRIC: - { - m_logicalScaleX = mm2pixelsX; - m_logicalScaleY = mm2pixelsY; - break; - } - case wxMM_LOMETRIC: + int pixel_width = ::GetDeviceCaps(GetHdc(), HORZRES), + pixel_height = ::GetDeviceCaps(GetHdc(), VERTRES), + mm_width = ::GetDeviceCaps(GetHdc(), HORZSIZE), + mm_height = ::GetDeviceCaps(GetHdc(), VERTSIZE); + + if ( (mm_width == 0) || (mm_height == 0) ) { - m_logicalScaleX = (mm2pixelsX/10.0); - m_logicalScaleY = (mm2pixelsY/10.0); - break; + // we can't calculate mm2pixels[XY] then! + return; } - default: - case wxMM_TEXT: + + double mm2pixelsX = pixel_width / mm_width, + mm2pixelsY = pixel_height / mm_height; + + switch (mode) { - m_logicalScaleX = 1.0; - m_logicalScaleY = 1.0; - break; + case wxMM_TWIPS: + m_logicalScaleX = twips2mm * mm2pixelsX; + m_logicalScaleY = twips2mm * mm2pixelsY; + break; + + case wxMM_POINTS: + m_logicalScaleX = pt2mm * mm2pixelsX; + m_logicalScaleY = pt2mm * mm2pixelsY; + break; + + case wxMM_METRIC: + m_logicalScaleX = mm2pixelsX; + m_logicalScaleY = mm2pixelsY; + break; + + case wxMM_LOMETRIC: + m_logicalScaleX = mm2pixelsX / 10.0; + m_logicalScaleY = mm2pixelsY / 10.0; + break; + + default: + wxFAIL_MSG( _T("unknown mapping mode in SetMapMode") ); } } - if (::GetMapMode(GetHdc()) != MM_ANISOTROPIC) - ::SetMapMode(GetHdc(), MM_ANISOTROPIC); + // VZ: it seems very wasteful to always use MM_ANISOTROPIC when in 99% of + // cases we could do with MM_TEXT and in the remaining 0.9% with + // MM_ISOTROPIC (TODO!) + ::SetMapMode(GetHdc(), MM_ANISOTROPIC); + + int width = DeviceToLogicalXRel(VIEWPORT_EXTENT)*m_signX, + height = DeviceToLogicalYRel(VIEWPORT_EXTENT)*m_signY; - SetViewportExtEx(GetHdc(), VIEWPORT_EXTENT, VIEWPORT_EXTENT, NULL); - m_windowExtX = (int)MS_XDEV2LOG(VIEWPORT_EXTENT); - m_windowExtY = (int)MS_YDEV2LOG(VIEWPORT_EXTENT); - ::SetWindowExtEx(GetHdc(), m_windowExtX, m_windowExtY, NULL); - ::SetViewportOrgEx(GetHdc(), (int)m_deviceOriginX, (int)m_deviceOriginY, NULL); - ::SetWindowOrgEx(GetHdc(), (int)m_logicalOriginX, (int)m_logicalOriginY, NULL); + ::SetViewportExtEx(GetHdc(), VIEWPORT_EXTENT, VIEWPORT_EXTENT, NULL); + ::SetWindowExtEx(GetHdc(), width, height, NULL); + + ::SetViewportOrgEx(GetHdc(), m_deviceOriginX, m_deviceOriginY, NULL); + ::SetWindowOrgEx(GetHdc(), m_logicalOriginX, m_logicalOriginY, NULL); } void wxDC::SetUserScale(double x, double y) @@ -1561,6 +1578,9 @@ void wxDC::SetUserScale(double x, double y) if (!GetHDC()) return; #endif + if ( x == m_userScaleX && y == m_userScaleY ) + return; + m_userScaleX = x; m_userScaleY = y; @@ -1573,10 +1593,16 @@ void wxDC::SetAxisOrientation(bool xLeftRight, bool yBottomUp) if (!GetHDC()) return; #endif - m_signX = xLeftRight ? 1 : -1; - m_signY = yBottomUp ? -1 : 1; + int signX = xLeftRight ? 1 : -1, + signY = yBottomUp ? -1 : 1; - SetMapMode(m_mappingMode); + if ( signX != m_signX || signY != m_signY ) + { + m_signX = signX; + m_signY = signY; + + SetMapMode(m_mappingMode); + } } void wxDC::SetSystemScale(double x, double y) @@ -1585,6 +1611,9 @@ void wxDC::SetSystemScale(double x, double y) if (!GetHDC()) return; #endif + if ( x == m_scaleX && y == m_scaleY ) + return; + m_scaleX = x; m_scaleY = y; @@ -1597,6 +1626,9 @@ void wxDC::SetLogicalOrigin(wxCoord x, wxCoord y) if (!GetHDC()) return; #endif + if ( x == m_logicalOriginX && y == m_logicalOriginY ) + return; + m_logicalOriginX = x; m_logicalOriginY = y; @@ -1609,6 +1641,9 @@ void wxDC::SetDeviceOrigin(wxCoord x, wxCoord y) if (!GetHDC()) return; #endif + if ( x == m_deviceOriginX && y == m_deviceOriginY ) + return; + m_deviceOriginX = x; m_deviceOriginY = y; @@ -1621,49 +1656,45 @@ void wxDC::SetDeviceOrigin(wxCoord x, wxCoord y) wxCoord wxDCBase::DeviceToLogicalX(wxCoord x) const { - double xRel = x - m_deviceOriginX; - xRel /= m_logicalScaleX*m_userScaleX*m_signX*m_scaleX; - return (wxCoord)(xRel + m_logicalOriginX); + return DeviceToLogicalXRel(x - m_deviceOriginX)*m_signX + m_logicalOriginX; } wxCoord wxDCBase::DeviceToLogicalXRel(wxCoord x) const { - // axis orientation is not taken into account for conversion of a distance - return (wxCoord) ((x)/(m_logicalScaleX*m_userScaleX*m_scaleX)); + // axis orientation is not taken into account for conversion of a distance + return (wxCoord)(x / (m_logicalScaleX*m_userScaleX*m_scaleX)); } wxCoord wxDCBase::DeviceToLogicalY(wxCoord y) const { - double yRel = y - m_deviceOriginY; - yRel /= m_logicalScaleY*m_userScaleY*m_signY*m_scaleY; - return (wxCoord)(yRel + m_logicalOriginY); + return DeviceToLogicalYRel(y - m_deviceOriginY)*m_signY + m_logicalOriginY; } wxCoord wxDCBase::DeviceToLogicalYRel(wxCoord y) const { - // axis orientation is not taken into account for conversion of a distance - return (wxCoord) ((y)/(m_logicalScaleY*m_userScaleY*m_scaleY)); + // axis orientation is not taken into account for conversion of a distance + return (wxCoord)( y / (m_logicalScaleY*m_userScaleY*m_scaleY)); } wxCoord wxDCBase::LogicalToDeviceX(wxCoord x) const { - return (wxCoord) ((x - m_logicalOriginX)*m_logicalScaleX*m_userScaleX*m_signX*m_scaleX + m_deviceOriginX); + return LogicalToDeviceXRel(x - m_logicalOriginX)*m_signX + m_deviceOriginX; } wxCoord wxDCBase::LogicalToDeviceXRel(wxCoord x) const { - // axis orientation is not taken into account for conversion of a distance + // axis orientation is not taken into account for conversion of a distance return (wxCoord) (x*m_logicalScaleX*m_userScaleX*m_scaleX); } wxCoord wxDCBase::LogicalToDeviceY(wxCoord y) const { - return (wxCoord) ((y - m_logicalOriginY)*m_logicalScaleY*m_userScaleY*m_signY*m_scaleY + m_deviceOriginY); + return LogicalToDeviceYRel(y - m_logicalOriginY)*m_signY + m_deviceOriginY; } wxCoord wxDCBase::LogicalToDeviceYRel(wxCoord y) const { - // axis orientation is not taken into account for conversion of a distance + // axis orientation is not taken into account for conversion of a distance return (wxCoord) (y*m_logicalScaleY*m_userScaleY*m_scaleY); }