#include "wx/icon.h"
#endif
+#include "wx/settings.h"
#include "wx/dcprint.h"
#include <string.h>
// clipping
// ---------------------------------------------------------------------------
-#define DO_SET_CLIPPING_BOX() \
-{ \
- RECT rect; \
- \
- GetClipBox(GetHdc(), &rect); \
- \
- m_clipX1 = (wxCoord) XDEV2LOG(rect.left); \
- m_clipY1 = (wxCoord) YDEV2LOG(rect.top); \
- m_clipX2 = (wxCoord) XDEV2LOG(rect.right); \
- m_clipY2 = (wxCoord) YDEV2LOG(rect.bottom); \
+void wxDC::UpdateClipBox()
+{
+ RECT rect;
+ GetClipBox(GetHdc(), &rect);
+
+ m_clipX1 = (wxCoord) XDEV2LOG(rect.left);
+ m_clipY1 = (wxCoord) YDEV2LOG(rect.top);
+ m_clipX2 = (wxCoord) XDEV2LOG(rect.right);
+ m_clipY2 = (wxCoord) YDEV2LOG(rect.bottom);
}
-void wxDC::DoSetClippingRegion(wxCoord cx, wxCoord cy, wxCoord cw, wxCoord ch)
+void wxDC::DoSetClippingRegion(wxCoord x, wxCoord y, wxCoord w, wxCoord h)
{
m_clipping = TRUE;
- IntersectClipRect(GetHdc(), XLOG2DEV(cx), YLOG2DEV(cy),
- XLOG2DEV(cx + cw), YLOG2DEV(cy + ch));
- DO_SET_CLIPPING_BOX()
+
+ // the region coords are always the device ones, so do the translation
+ // manually
+ //
+ // FIXME: possible +/-1 error here, to check!
+ HRGN hrgn = ::CreateRectRgn(LogicalToDeviceX(x),
+ LogicalToDeviceY(y),
+ LogicalToDeviceX(x + w),
+ LogicalToDeviceY(y + h));
+ if ( !hrgn )
+ {
+ wxLogLastError(_T("CreateRectRgn"));
+ }
+ else
+ {
+ if ( ::SelectClipRgn(GetHdc(), hrgn) == ERROR )
+ {
+ wxLogLastError(_T("SelectClipRgn"));
+ }
+
+ UpdateClipBox();
+ }
}
void wxDC::DoSetClippingRegionAsRegion(const wxRegion& region)
{
- wxCHECK_RET( region.GetHRGN(), wxT("invalid clipping region") );
+ wxCHECK_RET( GetHrgnOf(region), wxT("invalid clipping region") );
m_clipping = TRUE;
#ifdef __WIN16__
- SelectClipRgn(GetHdc(), (HRGN) region.GetHRGN());
-#else
- ExtSelectClipRgn(GetHdc(), (HRGN) region.GetHRGN(), RGN_AND);
-#endif
+ SelectClipRgn(GetHdc(), GetHrgnOf(region));
+#else // Win32
+ ExtSelectClipRgn(GetHdc(), GetHrgnOf(region), RGN_AND);
+#endif // Win16/32
- DO_SET_CLIPPING_BOX()
+ UpdateClipBox();
}
void wxDC::DestroyClippingRegion()
SelectClipRgn(GetHdc(), rgn);
DeleteObject(rgn);
}
+
m_clipping = FALSE;
}
if ( useMask )
{
#ifdef __WIN32__
- HDC hdcMem = ::CreateCompatibleDC(GetHdc());
- ::SelectObject(hdcMem, GetHbitmapOf(bmp));
-
// use MaskBlt() with ROP which doesn't do anything to dst in the mask
// points
- bool ok = ::MaskBlt(GetHdc(), x, y, width, height,
+ // On some systems, MaskBlt succeeds yet is much much slower
+ // than the wxWindows fall-back implementation. So we need
+ // to be able to switch this on and off at runtime.
+ bool ok = FALSE;
+ if (wxSystemSettings::GetOptionInt(wxT("no-maskblt")) == 0)
+ {
+ HDC hdcMem = ::CreateCompatibleDC(GetHdc());
+ ::SelectObject(hdcMem, GetHbitmapOf(bmp));
+
+ ok = ::MaskBlt(GetHdc(), x, y, width, height,
hdcMem, 0, 0,
hbmpMask, 0, 0,
MAKEROP4(SRCCOPY, DSTCOPY)) != 0;
- ::DeleteDC(hdcMem);
+ ::DeleteDC(hdcMem);
+ }
if ( !ok )
#endif // Win32
return FALSE;
}
- bool success;
+ bool success = FALSE;
if (useMask)
{
// transparent, so use "DSTCOPY" ROP for the mask points (the usual
// meaning of fg and bg is inverted which corresponds to wxWin notion
// of the mask which is also contrary to the Windows one)
- success = ::MaskBlt(GetHdc(), xdest, ydest, width, height,
+
+ // On some systems, MaskBlt succeeds yet is much much slower
+ // than the wxWindows fall-back implementation. So we need
+ // to be able to switch this on and off at runtime.
+ if (wxSystemSettings::GetOptionInt(wxT("no-maskblt")) == 0)
+ {
+ success = ::MaskBlt(GetHdc(), xdest, ydest, width, height,
GetHdcOf(*source), xsrc, ysrc,
(HBITMAP)mask->GetMaskBitmap(), xsrc, ysrc,
MAKEROP4(dwRop, DSTCOPY)) != 0;
+ }
if ( !success )
#endif // Win32