added wxDC::Set/GetLayoutDirection() and implemented it for wxMSW (patch from Tim Kosse)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@41867 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2006-10-10 08:31:23 +00:00
parent d18868bb9b
commit 6ae7410f55
4 changed files with 121 additions and 20 deletions

View File

@@ -634,6 +634,20 @@ initially and only after calling \helpref{wxDC::SetFont}{wxdcsetfont} a valid
font is returned.
\membersection{wxDC::GetLayoutDirection}\label{wxdcgetlayoutdirection}
\constfunc{wxLayoutDirection}{GetLayoutDirection}{\void}
Gets the current layout direction of the device context. On platforms where RTL layout
is supported, the return value will either be \texttt{wxLayout_LeftToRight} or
\texttt{wxLayout_RightToLeft}. If RTL layout is not supported, the return value will
be \texttt{wxLayout_Default}.
\wxheading{See also}
\helpref{SetLayoutDirection}{wxdcsetlayoutdirection}
\membersection{wxDC::GetLogicalFunction}\label{wxdcgetlogicalfunction}
\func{int}{GetLogicalFunction}{\void}
@@ -997,6 +1011,18 @@ should not pass {\tt wxNullFont} to this method.
See also \helpref{wxFont}{wxfont}.
\membersection{wxDC::SetLayoutDirection}\label{wxdcsetlayoutdirection}
\func{void}{SetLayoutDirection}{\param{wxLayoutDirection}{ dir}}
Sets the current layout direction for the device context. \arg{dir} may be either
\texttt{wxLayout_Default}, \texttt{wxLayout_LeftToRight} or \texttt{wxLayout_RightToLeft}.
\wxheading{See also}
\helpref{GetLayoutDirection}{wxdcgetlayoutdirection}
\membersection{wxDC::SetLogicalFunction}\label{wxdcsetlogicalfunction}
\func{void}{SetLogicalFunction}{\param{int}{ function}}

View File

@@ -651,6 +651,16 @@ public:
if (h) *h = hh;
}
// RTL related functions
// ---------------------
// get or change the layout direction (LTR or RTL) for this dc,
// wxLayout_Default is returned if layout direction is not supported
virtual wxLayoutDirection GetLayoutDirection() const
{ return wxLayout_Default; }
virtual void SetLayoutDirection(wxLayoutDirection WXUNUSED(dir))
{ }
protected:
// the pure virtual functions which should be implemented by wxDC
virtual bool DoFloodFill(wxCoord x, wxCoord y, const wxColour& col,

View File

@@ -133,6 +133,14 @@ public:
static void ClearCache();
#endif
// RTL related functions
// ---------------------
// get or change the layout direction (LTR or RTL) for this dc,
// wxLayout_Default is returned if layout direction is not supported
virtual wxLayoutDirection GetLayoutDirection() const;
virtual void SetLayoutDirection(wxLayoutDirection dir);
protected:
void Init()
{

View File

@@ -57,6 +57,10 @@
#define AC_SRC_ALPHA 1
#endif
#ifndef LAYOUT_RTL
#define LAYOUT_RTL 1
#endif
/* Quaternary raster codes */
#ifndef MAKEROP4
#define MAKEROP4(fore,back) (DWORD)((((back) << 8) & 0xFF000000) | (fore))
@@ -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
@@ -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);
}