X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/3cdcf4d444770f7f0ff2ca64807d8699764ed8b3..d2d0adc7765dfe904f0f7e97d85a2638c934a7d6:/src/msw/dc.cpp?ds=inline diff --git a/src/msw/dc.cpp b/src/msw/dc.cpp index ca841ef823..f22685ba97 100644 --- a/src/msw/dc.cpp +++ b/src/msw/dc.cpp @@ -25,6 +25,7 @@ #endif #ifndef WX_PRECOMP + #include "wx/msw/wrapcdlg.h" #include "wx/image.h" #include "wx/window.h" #include "wx/dc.h" @@ -35,11 +36,11 @@ #include "wx/dcmemory.h" #include "wx/log.h" #include "wx/icon.h" + #include "wx/dcprint.h" + #include "wx/module.h" #endif #include "wx/sysopt.h" -#include "wx/dcprint.h" -#include "wx/module.h" #include "wx/dynlib.h" #ifdef wxHAVE_RAW_BITMAP @@ -48,13 +49,16 @@ #include -#include "wx/msw/wrapcdlg.h" #ifndef __WIN32__ #include #endif #ifndef AC_SRC_ALPHA -#define AC_SRC_ALPHA 1 + #define AC_SRC_ALPHA 1 +#endif + +#ifndef LAYOUT_RTL + #define LAYOUT_RTL 1 #endif /* Quaternary raster codes */ @@ -196,36 +200,44 @@ private: DECLARE_NO_COPY_CLASS(StretchBltModeChanger) }; -// support for dynamic loading of msimg32.dll which we use for some functions -class wxMSImg32DLL +// helper class to cache dynamically loaded libraries and not attempt reloading +// them if it fails +class wxOnceOnlyDLLLoader { public: - // return the symbol with the given name if the DLL not loaded or symbol - // not present - static void *GetSymbol(const wxChar *name) + // ctor argument must be a literal string as we don't make a copy of it! + wxOnceOnlyDLLLoader(const wxChar *dllName) + : m_dllName(dllName) { + }; + + + // return the symbol with the given name or NULL if the DLL not loaded + // or symbol not present + void *GetSymbol(const wxChar *name) + { + // we're prepared to handle errors here wxLogNull noLog; - if ( !ms_triedToLoad ) + if ( m_dllName ) { - ms_triedToLoad = true; - ms_dll.Load(_T("msimg32")); + m_dll.Load(m_dllName); + + // reset the name whether we succeeded or failed so that we don't + // try again the next time + m_dllName = NULL; } - return ms_dll.IsLoaded() ? ms_dll.GetSymbol(name) : NULL; + return m_dll.IsLoaded() ? m_dll.GetSymbol(name) : NULL; } private: - static wxDynamicLibrary ms_dll; - static bool ms_triedToLoad; + wxDynamicLibrary m_dll; + const wxChar *m_dllName; }; -wxDynamicLibrary wxMSImg32DLL::ms_dll; -bool wxMSImg32DLL::ms_triedToLoad = false; - -// helper macro for getting the symbols from msimg32.dll: it supposes that a -// type "name_t" is defined and casts the returned symbol to it automatically -#define wxMSIMG32_SYMBOL(name) (name ## _t)wxMSImg32DLL::GetSymbol(_T(#name)) +static wxOnceOnlyDLLLoader wxGDI32DLL(_T("gdi32")); +static wxOnceOnlyDLLLoader wxMSIMG32DLL(_T("msimg32")); // =========================================================================== // implementation @@ -554,9 +566,9 @@ void wxDC::Clear() if (!m_selectedBitmap.Ok()) return; - rect.left = 0; rect.top = 0; - rect.right = m_selectedBitmap.GetWidth(); - rect.bottom = m_selectedBitmap.GetHeight(); + rect.left = -m_deviceOriginX; rect.top = -m_deviceOriginY; + rect.right = m_selectedBitmap.GetWidth()-m_deviceOriginX; + rect.bottom = m_selectedBitmap.GetHeight()-m_deviceOriginY; } #ifndef __WXWINCE__ @@ -1488,7 +1500,7 @@ void wxDC::SetFont(const wxFont& font) else // selected ok { if ( !m_oldFont ) - m_oldFont = (WXHPEN)hfont; + m_oldFont = (WXHFONT)hfont; m_font = font; } @@ -1581,7 +1593,7 @@ void wxDC::SetBrush(const wxBrush& brush) else // selected ok { if ( !m_oldBrush ) - m_oldBrush = (WXHPEN)hbrush; + m_oldBrush = (WXHBRUSH)hbrush; m_brush = brush; } @@ -1807,8 +1819,8 @@ bool wxDC::DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths) con { // Win9x and WinNT+ have different limits int version = wxGetOsVersion(); - maxLenText = version == wxWINDOWS_NT ? 65535 : 8192; - maxWidth = version == wxWINDOWS_NT ? INT_MAX : 32767; + maxLenText = version == wxOS_WINDOWS_NT ? 65535 : 8192; + maxWidth = version == wxOS_WINDOWS_NT ? INT_MAX : 32767; } widths.Empty(); @@ -2258,7 +2270,7 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, ds.dsBm.bmBits, (LPBITMAPINFO)&ds.dsBmih, DIB_RGB_COLORS, - SRCCOPY + dwRop ) == (int)GDI_ERROR ) { // On Win9x this API fails most (all?) of the time, so @@ -2541,7 +2553,8 @@ static bool AlphaBlt(HDC hdcDst, HDC,int,int,int,int, BLENDFUNCTION); - static AlphaBlend_t pfnAlphaBlend = wxMSIMG32_SYMBOL(AlphaBlend); + static AlphaBlend_t + pfnAlphaBlend = (AlphaBlend_t)wxMSIMG32DLL.GetSymbol(_T("AlphaBlend")); if ( pfnAlphaBlend ) { BLENDFUNCTION bf; @@ -2654,7 +2667,8 @@ void wxDC::DoGradientFillLinear (const wxRect& rect, #if defined(GRADIENT_FILL_RECT_H) && wxUSE_DYNLIB_CLASS typedef BOOL (WINAPI *GradientFill_t)(HDC, PTRIVERTEX, ULONG, PVOID, ULONG, ULONG); - static GradientFill_t pfnGradientFill = wxMSIMG32_SYMBOL(GradientFill); + static GradientFill_t pfnGradientFill = + (GradientFill_t)wxMSIMG32DLL.GetSymbol(_T("GradientFill")); if ( pfnGradientFill ) { @@ -2705,3 +2719,46 @@ void wxDC::DoGradientFillLinear (const wxRect& rect, wxDCBase::DoGradientFillLinear(rect, initialColour, destColour, nDirection); } + +static DWORD wxGetDCLayout(HDC hdc) +{ + typedef DWORD (WINAPI *GetLayout_t)(HDC); + static GetLayout_t + pfnGetLayout = (GetLayout_t)wxGDI32DLL.GetSymbol(_T("GetLayout")); + + return pfnGetLayout ? pfnGetLayout(hdc) : (DWORD)-1; +} + +wxLayoutDirection wxDC::GetLayoutDirection() const +{ + DWORD layout = wxGetDCLayout(GetHdc()); + + if ( layout == (DWORD)-1 ) + return wxLayout_Default; + + return layout & LAYOUT_RTL ? wxLayout_RightToLeft : wxLayout_LeftToRight; +} + +void wxDC::SetLayoutDirection(wxLayoutDirection dir) +{ + typedef DWORD (WINAPI *SetLayout_t)(HDC, DWORD); + static SetLayout_t + pfnSetLayout = (SetLayout_t)wxGDI32DLL.GetSymbol(_T("SetLayout")); + if ( !pfnSetLayout ) + return; + + if ( dir == wxLayout_Default ) + { + dir = wxTheApp->GetLayoutDirection(); + if ( dir == wxLayout_Default ) + return; + } + + DWORD layout = wxGetDCLayout(GetHdc()); + if ( dir == wxLayout_RightToLeft ) + layout |= LAYOUT_RTL; + else + layout &= ~LAYOUT_RTL; + + pfnSetLayout(GetHdc(), layout); +}