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
This commit is contained in:
Vadim Zeitlin 2002-02-02 16:08:14 +00:00
parent 0d4d0e8d76
commit 1e2081a1b9
2 changed files with 120 additions and 138 deletions

View File

@ -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;

View File

@ -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:
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 = (twips2mm * mm2pixelsX);
m_logicalScaleY = (twips2mm * mm2pixelsY);
break;
// we can't calculate mm2pixels[XY] then!
return;
}
case wxMM_POINTS:
double mm2pixelsX = pixel_width / mm_width,
mm2pixelsY = pixel_height / mm_height;
switch (mode)
{
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:
case wxMM_TEXT:
{
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);
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);
int width = DeviceToLogicalXRel(VIEWPORT_EXTENT)*m_signX,
height = DeviceToLogicalYRel(VIEWPORT_EXTENT)*m_signY;
::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);
}