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:
@@ -634,6 +634,20 @@ initially and only after calling \helpref{wxDC::SetFont}{wxdcsetfont} a valid
|
|||||||
font is returned.
|
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}
|
\membersection{wxDC::GetLogicalFunction}\label{wxdcgetlogicalfunction}
|
||||||
|
|
||||||
\func{int}{GetLogicalFunction}{\void}
|
\func{int}{GetLogicalFunction}{\void}
|
||||||
@@ -997,6 +1011,18 @@ should not pass {\tt wxNullFont} to this method.
|
|||||||
See also \helpref{wxFont}{wxfont}.
|
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}
|
\membersection{wxDC::SetLogicalFunction}\label{wxdcsetlogicalfunction}
|
||||||
|
|
||||||
\func{void}{SetLogicalFunction}{\param{int}{ function}}
|
\func{void}{SetLogicalFunction}{\param{int}{ function}}
|
||||||
|
@@ -651,6 +651,16 @@ public:
|
|||||||
if (h) *h = hh;
|
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:
|
protected:
|
||||||
// the pure virtual functions which should be implemented by wxDC
|
// the pure virtual functions which should be implemented by wxDC
|
||||||
virtual bool DoFloodFill(wxCoord x, wxCoord y, const wxColour& col,
|
virtual bool DoFloodFill(wxCoord x, wxCoord y, const wxColour& col,
|
||||||
|
@@ -133,6 +133,14 @@ public:
|
|||||||
static void ClearCache();
|
static void ClearCache();
|
||||||
#endif
|
#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:
|
protected:
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
|
@@ -57,6 +57,10 @@
|
|||||||
#define AC_SRC_ALPHA 1
|
#define AC_SRC_ALPHA 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef LAYOUT_RTL
|
||||||
|
#define LAYOUT_RTL 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Quaternary raster codes */
|
/* Quaternary raster codes */
|
||||||
#ifndef MAKEROP4
|
#ifndef MAKEROP4
|
||||||
#define MAKEROP4(fore,back) (DWORD)((((back) << 8) & 0xFF000000) | (fore))
|
#define MAKEROP4(fore,back) (DWORD)((((back) << 8) & 0xFF000000) | (fore))
|
||||||
@@ -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
|
// helper class to cache dynamically loaded libraries and not attempt reloading
|
||||||
class wxMSImg32DLL
|
// them if it fails
|
||||||
|
class wxOnceOnlyDLLLoader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// return the symbol with the given name if the DLL not loaded or symbol
|
// ctor argument must be a literal string as we don't make a copy of it!
|
||||||
// not present
|
wxOnceOnlyDLLLoader(const wxChar *dllName)
|
||||||
static void *GetSymbol(const wxChar *name)
|
: 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;
|
m_dll.Load(m_dllName);
|
||||||
ms_dll.Load(_T("msimg32"));
|
|
||||||
|
// 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;
|
wxDynamicLibrary m_dll;
|
||||||
static bool ms_triedToLoad;
|
const wxChar *m_dllName;
|
||||||
};
|
};
|
||||||
|
|
||||||
wxDynamicLibrary wxMSImg32DLL::ms_dll;
|
static wxOnceOnlyDLLLoader wxGDI32DLL(_T("gdi32"));
|
||||||
bool wxMSImg32DLL::ms_triedToLoad = false;
|
static wxOnceOnlyDLLLoader wxMSIMG32DLL(_T("msimg32"));
|
||||||
|
|
||||||
// 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))
|
|
||||||
|
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
// implementation
|
// implementation
|
||||||
@@ -2541,7 +2553,8 @@ static bool AlphaBlt(HDC hdcDst,
|
|||||||
HDC,int,int,int,int,
|
HDC,int,int,int,int,
|
||||||
BLENDFUNCTION);
|
BLENDFUNCTION);
|
||||||
|
|
||||||
static AlphaBlend_t pfnAlphaBlend = wxMSIMG32_SYMBOL(AlphaBlend);
|
static AlphaBlend_t
|
||||||
|
pfnAlphaBlend = (AlphaBlend_t)wxMSIMG32DLL.GetSymbol(_T("AlphaBlend"));
|
||||||
if ( pfnAlphaBlend )
|
if ( pfnAlphaBlend )
|
||||||
{
|
{
|
||||||
BLENDFUNCTION bf;
|
BLENDFUNCTION bf;
|
||||||
@@ -2654,7 +2667,8 @@ void wxDC::DoGradientFillLinear (const wxRect& rect,
|
|||||||
#if defined(GRADIENT_FILL_RECT_H) && wxUSE_DYNLIB_CLASS
|
#if defined(GRADIENT_FILL_RECT_H) && wxUSE_DYNLIB_CLASS
|
||||||
typedef BOOL
|
typedef BOOL
|
||||||
(WINAPI *GradientFill_t)(HDC, PTRIVERTEX, ULONG, PVOID, ULONG, ULONG);
|
(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);
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user