Fix RTL mirroring for wxClientDC, etc with GTK3

The changes to the Cairo context must be done before wxGC::CreateFromNative()
is called, otherwise they will be overwritten
This commit is contained in:
Paul Cornett
2021-02-06 08:28:13 -08:00
parent 67fc7c5508
commit 62c119fa1e
2 changed files with 15 additions and 27 deletions

View File

@@ -41,6 +41,7 @@ public:
protected: protected:
// Set m_size from the given (valid) GdkWindow. // Set m_size from the given (valid) GdkWindow.
void InitSize(GdkWindow* window); void InitSize(GdkWindow* window);
void AdjustForRTL(cairo_t* cr);
wxSize m_size; wxSize m_size;
wxLayoutDirection m_layoutDir; wxLayoutDirection m_layoutDir;

View File

@@ -366,26 +366,8 @@ void wxGTKCairoDCImpl::SetLayoutDirection(wxLayoutDirection dir)
if (dir == wxLayout_Default && m_window) if (dir == wxLayout_Default && m_window)
dir = m_window->GetLayoutDirection(); dir = m_window->GetLayoutDirection();
if (m_layoutDir != dir)
{
if (m_graphicContext)
{
if (dir == wxLayout_RightToLeft)
{
// wxDC is mirrored for RTL
m_graphicContext->Translate(m_size.x, 0);
m_graphicContext->Scale(-1, 1);
}
else if (m_layoutDir == wxLayout_RightToLeft)
{
m_graphicContext->Scale(-1, 1);
m_graphicContext->Translate(-m_size.x, 0);
}
}
m_layoutDir = dir; m_layoutDir = dir;
} }
}
wxLayoutDirection wxGTKCairoDCImpl::GetLayoutDirection() const wxLayoutDirection wxGTKCairoDCImpl::GetLayoutDirection() const
{ {
@@ -395,6 +377,15 @@ wxLayoutDirection wxGTKCairoDCImpl::GetLayoutDirection() const
? wxLayout_RightToLeft ? wxLayout_RightToLeft
: wxLayout_LeftToRight; : wxLayout_LeftToRight;
} }
void wxGTKCairoDCImpl::AdjustForRTL(cairo_t* cr)
{
if (m_layoutDir == wxLayout_RightToLeft)
{
cairo_translate(cr, m_size.x, 0);
cairo_scale(cr, -1, 1);
}
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
wxWindowDCImpl::wxWindowDCImpl(wxWindowDC* owner, wxWindow* window) wxWindowDCImpl::wxWindowDCImpl(wxWindowDC* owner, wxWindow* window)
@@ -412,6 +403,8 @@ wxWindowDCImpl::wxWindowDCImpl(wxWindowDC* owner, wxWindow* window)
if (gdkWindow) if (gdkWindow)
{ {
cairo_t* cr = gdk_cairo_create(gdkWindow); cairo_t* cr = gdk_cairo_create(gdkWindow);
SetLayoutDirection(wxLayout_Default);
AdjustForRTL(cr);
wxGraphicsContext* gc = wxGraphicsContext::CreateFromNative(cr); wxGraphicsContext* gc = wxGraphicsContext::CreateFromNative(cr);
cairo_destroy(cr); cairo_destroy(cr);
gc->EnableOffset(m_contentScaleFactor <= 1); gc->EnableOffset(m_contentScaleFactor <= 1);
@@ -437,8 +430,6 @@ wxWindowDCImpl::wxWindowDCImpl(wxWindowDC* owner, wxWindow* window)
} }
if (x || y) if (x || y)
SetDeviceLocalOrigin(x, y); SetDeviceLocalOrigin(x, y);
SetLayoutDirection(wxLayout_Default);
} }
else else
SetGraphicsContext(wxGraphicsContext::Create()); SetGraphicsContext(wxGraphicsContext::Create());
@@ -461,6 +452,7 @@ wxClientDCImpl::wxClientDCImpl(wxClientDC* owner, wxWindow* window)
if (gdkWindow) if (gdkWindow)
{ {
cairo_t* cr = gdk_cairo_create(gdkWindow); cairo_t* cr = gdk_cairo_create(gdkWindow);
AdjustForRTL(cr);
wxGraphicsContext* gc = wxGraphicsContext::CreateFromNative(cr); wxGraphicsContext* gc = wxGraphicsContext::CreateFromNative(cr);
cairo_destroy(cr); cairo_destroy(cr);
gc->EnableOffset(m_contentScaleFactor <= 1); gc->EnableOffset(m_contentScaleFactor <= 1);
@@ -473,7 +465,6 @@ wxClientDCImpl::wxClientDCImpl(wxClientDC* owner, wxWindow* window)
cairo_clip(cr); cairo_clip(cr);
SetDeviceLocalOrigin(a.x, a.y); SetDeviceLocalOrigin(a.x, a.y);
} }
SetLayoutDirection(wxLayout_Default);
} }
else else
SetGraphicsContext(wxGraphicsContext::Create()); SetGraphicsContext(wxGraphicsContext::Create());
@@ -578,16 +569,12 @@ void wxMemoryDCImpl::Setup()
m_size = m_bitmap.GetScaledSize(); m_size = m_bitmap.GetScaledSize();
m_contentScaleFactor = m_bitmap.GetScaleFactor(); m_contentScaleFactor = m_bitmap.GetScaleFactor();
cairo_t* cr = m_bitmap.CairoCreate(); cairo_t* cr = m_bitmap.CairoCreate();
AdjustForRTL(cr);
gc = wxGraphicsContext::CreateFromNative(cr); gc = wxGraphicsContext::CreateFromNative(cr);
cairo_destroy(cr); cairo_destroy(cr);
gc->EnableOffset(m_contentScaleFactor <= 1); gc->EnableOffset(m_contentScaleFactor <= 1);
} }
SetGraphicsContext(gc); SetGraphicsContext(gc);
// re-apply layout direction
const wxLayoutDirection dir = m_layoutDir;
m_layoutDir = wxLayout_Default;
SetLayoutDirection(dir);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------