]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/dc.cpp
Added URL support to attribute objects and to wxRichTextCtrl,
[wxWidgets.git] / src / msw / dc.cpp
index ca841ef82304c5e0c0f9dcf91f321c96f00f81d2..f22685ba9726e53ae9dffc683aaee7e4b377e776 100644 (file)
@@ -25,6 +25,7 @@
 #endif
 
 #ifndef WX_PRECOMP
 #endif
 
 #ifndef WX_PRECOMP
+    #include "wx/msw/wrapcdlg.h"
     #include "wx/image.h"
     #include "wx/window.h"
     #include "wx/dc.h"
     #include "wx/image.h"
     #include "wx/window.h"
     #include "wx/dc.h"
     #include "wx/dcmemory.h"
     #include "wx/log.h"
     #include "wx/icon.h"
     #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"
 #endif
 
 #include "wx/sysopt.h"
-#include "wx/dcprint.h"
-#include "wx/module.h"
 #include "wx/dynlib.h"
 
 #ifdef wxHAVE_RAW_BITMAP
 #include "wx/dynlib.h"
 
 #ifdef wxHAVE_RAW_BITMAP
 
 #include <string.h>
 
 
 #include <string.h>
 
-#include "wx/msw/wrapcdlg.h"
 #ifndef __WIN32__
     #include <print.h>
 #endif
 
 #ifndef AC_SRC_ALPHA
 #ifndef __WIN32__
     #include <print.h>
 #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 */
 #endif
 
 /* Quaternary raster codes */
@@ -196,36 +200,44 @@ private:
     DECLARE_NO_COPY_CLASS(StretchBltModeChanger)
 };
 
     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:
 {
 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;
 
         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:
     }
 
 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
 
 // ===========================================================================
 // implementation
@@ -554,9 +566,9 @@ void wxDC::Clear()
         if (!m_selectedBitmap.Ok())
             return;
 
         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__
     }
 
 #ifndef __WXWINCE__
@@ -1488,7 +1500,7 @@ void wxDC::SetFont(const wxFont& font)
         else // selected ok
         {
             if ( !m_oldFont )
         else // selected ok
         {
             if ( !m_oldFont )
-                m_oldFont = (WXHPEN)hfont;
+                m_oldFont = (WXHFONT)hfont;
 
             m_font = font;
         }
 
             m_font = font;
         }
@@ -1581,7 +1593,7 @@ void wxDC::SetBrush(const wxBrush& brush)
         else // selected ok
         {
             if ( !m_oldBrush )
         else // selected ok
         {
             if ( !m_oldBrush )
-                m_oldBrush = (WXHPEN)hbrush;
+                m_oldBrush = (WXHBRUSH)hbrush;
 
             m_brush = brush;
         }
 
             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();
     {
         // 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();
     }
 
     widths.Empty();
@@ -2258,7 +2270,7 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest,
                                      ds.dsBm.bmBits,
                                      (LPBITMAPINFO)&ds.dsBmih,
                                      DIB_RGB_COLORS,
                                      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
                                      ) == (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);
 
                                         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;
     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);
 #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 )
     {
 
     if ( pfnGradientFill )
     {
@@ -2705,3 +2719,46 @@ void wxDC::DoGradientFillLinear (const wxRect& rect,
 
     wxDCBase::DoGradientFillLinear(rect, initialColour, destColour, nDirection);
 }
 
     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);
+}