Restore source DC state when wxCairoContext is destroyed (wxMSW).
Since raw DC (encapsulated in source wxDC) can be modified in wxCairoContext explicitly (e.g. when context is instantiated from wxPrinterDC or wxEnhMetaFileDC) or implicitly (by some Cairo functions) we have to store its state in ctor and restore it in dtor to assure consistent state of the source wxDC.
This commit is contained in:
@@ -184,7 +184,9 @@
|
|||||||
m( cairo_surface_t*, cairo_win32_surface_create, \
|
m( cairo_surface_t*, cairo_win32_surface_create, \
|
||||||
(HDC hdc), (hdc), NULL ) \
|
(HDC hdc), (hdc), NULL ) \
|
||||||
m( cairo_surface_t*, cairo_win32_printing_surface_create, \
|
m( cairo_surface_t*, cairo_win32_printing_surface_create, \
|
||||||
(HDC hdc), (hdc), NULL )
|
(HDC hdc), (hdc), NULL ) \
|
||||||
|
m( HDC, cairo_win32_surface_get_dc, \
|
||||||
|
(cairo_surface_t *surface), (surface), NULL )
|
||||||
#else
|
#else
|
||||||
#define wxCAIRO_PLATFORM_METHODS(m)
|
#define wxCAIRO_PLATFORM_METHODS(m)
|
||||||
#endif
|
#endif
|
||||||
|
@@ -509,6 +509,7 @@ protected:
|
|||||||
#ifdef __WXMSW__
|
#ifdef __WXMSW__
|
||||||
cairo_surface_t* m_mswSurface;
|
cairo_surface_t* m_mswSurface;
|
||||||
WindowHDC m_mswWindowHDC;
|
WindowHDC m_mswWindowHDC;
|
||||||
|
int m_mswStateSavedDC;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -1741,6 +1742,7 @@ wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, const wxPrinterDC&
|
|||||||
// text rendering when printing using Cairo. Switch it to MM_TEXT
|
// text rendering when printing using Cairo. Switch it to MM_TEXT
|
||||||
// map mode to avoid this problem.
|
// map mode to avoid this problem.
|
||||||
HDC hdc = (HDC)dc.GetHDC();
|
HDC hdc = (HDC)dc.GetHDC();
|
||||||
|
m_mswStateSavedDC = ::SaveDC(hdc);
|
||||||
::SetMapMode(hdc, MM_TEXT);
|
::SetMapMode(hdc, MM_TEXT);
|
||||||
m_mswSurface = cairo_win32_printing_surface_create(hdc);
|
m_mswSurface = cairo_win32_printing_surface_create(hdc);
|
||||||
Init( cairo_create(m_mswSurface) );
|
Init( cairo_create(m_mswSurface) );
|
||||||
@@ -1792,7 +1794,9 @@ wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, const wxWindowDC&
|
|||||||
m_enableOffset = dc.GetContentScaleFactor() <= 1;
|
m_enableOffset = dc.GetContentScaleFactor() <= 1;
|
||||||
|
|
||||||
#ifdef __WXMSW__
|
#ifdef __WXMSW__
|
||||||
m_mswSurface = cairo_win32_surface_create((HDC)dc.GetHDC());
|
HDC hdc = (HDC)dc.GetHDC();
|
||||||
|
m_mswStateSavedDC = ::SaveDC(hdc);
|
||||||
|
m_mswSurface = cairo_win32_surface_create(hdc);
|
||||||
Init( cairo_create(m_mswSurface) );
|
Init( cairo_create(m_mswSurface) );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1850,13 +1854,15 @@ wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, const wxMemoryDC&
|
|||||||
wxASSERT_MSG(bmp.IsOk(),
|
wxASSERT_MSG(bmp.IsOk(),
|
||||||
wxS("Should select a bitmap before creating wxCairoContext"));
|
wxS("Should select a bitmap before creating wxCairoContext"));
|
||||||
|
|
||||||
|
HDC hdc = (HDC)dc.GetHDC();
|
||||||
|
m_mswStateSavedDC = ::SaveDC(hdc);
|
||||||
bool hasBitmap = false;
|
bool hasBitmap = false;
|
||||||
|
|
||||||
// cairo_win32_surface_create creates a 24-bit bitmap,
|
// cairo_win32_surface_create creates a 24-bit bitmap,
|
||||||
// so if we 32bpp bitmap, we need to create a 32-bit surface instead.
|
// so if we 32bpp bitmap, we need to create a 32-bit surface instead.
|
||||||
if (bmp.GetDepth() < 32)
|
if (bmp.GetDepth() < 32)
|
||||||
{
|
{
|
||||||
m_mswSurface = cairo_win32_surface_create(dc.GetHDC());
|
m_mswSurface = cairo_win32_surface_create(hdc);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1937,7 +1943,7 @@ wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, const wxMemoryDC&
|
|||||||
// Fallback if we failed to create Cairo surface from 32bpp bitmap.
|
// Fallback if we failed to create Cairo surface from 32bpp bitmap.
|
||||||
if( !hasBitmap )
|
if( !hasBitmap )
|
||||||
{
|
{
|
||||||
m_mswSurface = cairo_win32_surface_create(dc.GetHDC());
|
m_mswSurface = cairo_win32_surface_create(hdc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2027,6 +2033,7 @@ wxCairoContext::wxCairoContext(wxGraphicsRenderer* renderer, const wxEnhMetaFile
|
|||||||
// text rendering when printing using Cairo. Switch it to MM_TEXT
|
// text rendering when printing using Cairo. Switch it to MM_TEXT
|
||||||
// map mode to avoid this problem.
|
// map mode to avoid this problem.
|
||||||
HDC hdc = (HDC)dc.GetHDC();
|
HDC hdc = (HDC)dc.GetHDC();
|
||||||
|
m_mswStateSavedDC = ::SaveDC(hdc);
|
||||||
::SetMapMode(hdc, MM_TEXT);
|
::SetMapMode(hdc, MM_TEXT);
|
||||||
m_mswSurface = cairo_win32_printing_surface_create(hdc);
|
m_mswSurface = cairo_win32_printing_surface_create(hdc);
|
||||||
Init( cairo_create(m_mswSurface) );
|
Init( cairo_create(m_mswSurface) );
|
||||||
@@ -2044,6 +2051,7 @@ wxCairoContext::wxCairoContext(wxGraphicsRenderer* renderer, const wxEnhMetaFile
|
|||||||
wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, HDC handle )
|
wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, HDC handle )
|
||||||
: wxGraphicsContext(renderer)
|
: wxGraphicsContext(renderer)
|
||||||
{
|
{
|
||||||
|
m_mswStateSavedDC = ::SaveDC(handle);
|
||||||
m_mswSurface = cairo_win32_surface_create(handle);
|
m_mswSurface = cairo_win32_surface_create(handle);
|
||||||
Init( cairo_create(m_mswSurface) );
|
Init( cairo_create(m_mswSurface) );
|
||||||
m_width = 0;
|
m_width = 0;
|
||||||
@@ -2082,6 +2090,7 @@ wxCairoContext::wxCairoContext(wxGraphicsRenderer* renderer, HWND hWnd)
|
|||||||
double scaleY = ::GetDeviceCaps((HDC)m_mswWindowHDC, LOGPIXELSY) / 96.0f;
|
double scaleY = ::GetDeviceCaps((HDC)m_mswWindowHDC, LOGPIXELSY) / 96.0f;
|
||||||
m_enableOffset = scaleY <= 1.0;
|
m_enableOffset = scaleY <= 1.0;
|
||||||
|
|
||||||
|
m_mswStateSavedDC = 0;
|
||||||
m_mswSurface = cairo_win32_surface_create((HDC)m_mswWindowHDC);
|
m_mswSurface = cairo_win32_surface_create((HDC)m_mswWindowHDC);
|
||||||
Init(cairo_create(m_mswSurface));
|
Init(cairo_create(m_mswSurface));
|
||||||
m_width = 0;
|
m_width = 0;
|
||||||
@@ -2101,6 +2110,7 @@ wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, cairo_t *context )
|
|||||||
{
|
{
|
||||||
#ifdef __WXMSW__
|
#ifdef __WXMSW__
|
||||||
m_mswSurface = NULL;
|
m_mswSurface = NULL;
|
||||||
|
m_mswStateSavedDC = 0;
|
||||||
#endif // __WXMSW__
|
#endif // __WXMSW__
|
||||||
Init( context );
|
Init( context );
|
||||||
m_width =
|
m_width =
|
||||||
@@ -2135,6 +2145,7 @@ wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, wxWindow *window)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __WXMSW__
|
#ifdef __WXMSW__
|
||||||
|
m_mswStateSavedDC = 0;
|
||||||
m_mswSurface = cairo_win32_surface_create((HDC)m_mswWindowHDC);
|
m_mswSurface = cairo_win32_surface_create((HDC)m_mswWindowHDC);
|
||||||
Init(cairo_create(m_mswSurface));
|
Init(cairo_create(m_mswSurface));
|
||||||
#endif
|
#endif
|
||||||
@@ -2149,6 +2160,7 @@ wxCairoContext::wxCairoContext(wxGraphicsRenderer* renderer) :
|
|||||||
{
|
{
|
||||||
#ifdef __WXMSW__
|
#ifdef __WXMSW__
|
||||||
m_mswSurface = NULL;
|
m_mswSurface = NULL;
|
||||||
|
m_mswStateSavedDC = 0;
|
||||||
#endif // __WXMSW__
|
#endif // __WXMSW__
|
||||||
m_context = NULL;
|
m_context = NULL;
|
||||||
}
|
}
|
||||||
@@ -2163,7 +2175,14 @@ wxCairoContext::~wxCairoContext()
|
|||||||
}
|
}
|
||||||
#ifdef __WXMSW__
|
#ifdef __WXMSW__
|
||||||
if ( m_mswSurface )
|
if ( m_mswSurface )
|
||||||
|
{
|
||||||
|
HDC hdc = cairo_win32_surface_get_dc(m_mswSurface);
|
||||||
|
|
||||||
cairo_surface_destroy(m_mswSurface);
|
cairo_surface_destroy(m_mswSurface);
|
||||||
|
|
||||||
|
if ( hdc && m_mswStateSavedDC != 0 )
|
||||||
|
::RestoreDC(hdc, m_mswStateSavedDC);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef __WXQT__
|
#ifdef __WXQT__
|
||||||
if ( m_qtPainter != NULL )
|
if ( m_qtPainter != NULL )
|
||||||
|
Reference in New Issue
Block a user