X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2b77c3fce750925bdd0cb33505439ddc5493a18e..07aaf32633ecf18ec3edfbb41793a112914792d0:/src/x11/dcclient.cpp diff --git a/src/x11/dcclient.cpp b/src/x11/dcclient.cpp index 264bd88993..46a9657a24 100644 --- a/src/x11/dcclient.cpp +++ b/src/x11/dcclient.cpp @@ -23,6 +23,7 @@ #endif #include "wx/fontutil.h" +#include "wx/vector.h" #include "wx/x11/private.h" #include "wx/x11/dcclient.h" @@ -61,7 +62,7 @@ #define IS_16_PIX_HATCH(s) ((s)!=wxCROSSDIAG_HATCH && (s)!=wxHORIZONTAL_HATCH && (s)!=wxVERTICAL_HATCH) static Pixmap hatches[num_hatches]; -static Pixmap *hatch_bitmap = (Pixmap *) NULL; +static Pixmap *hatch_bitmap = NULL; //----------------------------------------------------------------------------- // constants @@ -167,9 +168,9 @@ static void wxFreePoolGC( GC gc ) IMPLEMENT_ABSTRACT_CLASS(wxWindowDCImpl, wxX11DCImpl) -wxWindowDCImpl::wxWindowDCImpl( wxDC *owner ) +wxWindowDCImpl::wxWindowDCImpl( wxDC *owner ) : wxX11DCImpl( owner ) -{ +{ Init(); } @@ -182,7 +183,7 @@ wxWindowDCImpl::wxWindowDCImpl( wxDC* owner, wxWindow *window ) m_font = window->GetFont(); - m_x11window = (WXWindow*) window->GetMainWindow(); + m_x11window = (WXWindow*) window->X11GetMainWindow(); // not realized ? if (!m_x11window) @@ -221,19 +222,19 @@ wxWindowDCImpl::~wxWindowDCImpl() void wxWindowDCImpl::Init() { - m_display = (WXDisplay *) NULL; - m_penGC = (WXGC *) NULL; - m_brushGC = (WXGC *) NULL; - m_textGC = (WXGC *) NULL; - m_bgGC = (WXGC *) NULL; - m_cmap = (WXColormap *) NULL; + m_display = NULL; + m_penGC = NULL; + m_brushGC = NULL; + m_textGC = NULL; + m_bgGC = NULL; + m_cmap = NULL; m_isMemDC = false; m_isScreenDC = false; - m_x11window = (WXWindow*) NULL; + m_x11window = NULL; #if wxUSE_UNICODE m_context = wxTheApp->GetPangoContext(); - m_fontdesc = (PangoFontDescription *)NULL; + m_fontdesc = NULL; #endif } @@ -344,16 +345,16 @@ void wxWindowDCImpl::SetUpDC() void wxWindowDCImpl::DoGetSize( int* width, int* height ) const { - wxCHECK_RET( m_window, _T("GetSize() doesn't work without window") ); + wxCHECK_RET( m_window, wxT("GetSize() doesn't work without window") ); m_window->GetSize(width, height); } extern bool wxDoFloodFill(wxDC *dc, wxCoord x, wxCoord y, - const wxColour & col, int style); + const wxColour & col, wxFloodFillStyle style); bool wxWindowDCImpl::DoFloodFill(wxCoord x, wxCoord y, - const wxColour& col, int style) + const wxColour& col, wxFloodFillStyle style) { return wxDoFloodFill(GetOwner(), x, y, col, style); } @@ -620,7 +621,7 @@ void wxWindowDCImpl::DoDrawPoint( wxCoord x, wxCoord y ) CalcBoundingBox (x, y); } -void wxWindowDCImpl::DoDrawLines( int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset ) +void wxWindowDCImpl::DoDrawLines( int n, const wxPoint points[], wxCoord xoffset, wxCoord yoffset ) { wxCHECK_RET( IsOk(), wxT("invalid window dc") ); @@ -640,9 +641,9 @@ void wxWindowDCImpl::DoDrawLines( int n, wxPoint points[], wxCoord xoffset, wxCo delete[] xpoints; } -void wxWindowDCImpl::DoDrawPolygon( int n, wxPoint points[], +void wxWindowDCImpl::DoDrawPolygon( int n, const wxPoint points[], wxCoord xoffset, wxCoord yoffset, - int WXUNUSED(fillStyle) ) + wxPolygonFillMode WXUNUSED(fillStyle) ) { wxCHECK_RET( IsOk(), wxT("invalid window dc") ); @@ -1219,9 +1220,20 @@ void wxWindowDCImpl::DoDrawBitmap( const wxBitmap &bitmap, XSetStipple( xdisplay, gc, (Pixmap) mask); } - wxCoord clip_x, clip_y, clip_w, clip_h; - m_currentClippingRegion.GetBox(clip_x, clip_y, clip_w, clip_h); - XFillRectangle( xdisplay, new_pixmap, gc, clip_x-xx, clip_y-yy, clip_w, clip_h ); + wxVector rects; + for ( wxRegionIterator iter(m_currentClippingRegion); + iter; + ++iter ) + { + XRectangle rect; + rect.x = iter.GetX() - xx; + rect.y = iter.GetY() - yy; + rect.width = iter.GetWidth(); + rect.height = iter.GetHeight(); + rects.push_back(rect); + } + + XFillRectangles(xdisplay, new_pixmap, gc, &rects[0], rects.size()); XFreeGC( xdisplay, gc ); } @@ -1279,7 +1291,8 @@ void wxWindowDCImpl::DoDrawBitmap( const wxBitmap &bitmap, // wxUSE_NANOX/!wxUSE_NANOX bool wxWindowDCImpl::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height, - wxDC *source, wxCoord xsrc, wxCoord ysrc, int logical_func, bool useMask, + wxDC *source, wxCoord xsrc, wxCoord ysrc, + wxRasterOperationMode logical_func, bool useMask, wxCoord xsrcMask, wxCoord ysrcMask ) { /* this is the nth try to get this utterly useless function to @@ -1314,7 +1327,7 @@ bool wxWindowDCImpl::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoor if (src_impl->m_isMemDC) { wxBitmap selected = memDC->GetSelectedBitmap(); - + if (!selected.IsOk()) return false; /* we use the "XCopyArea" way to copy a memory dc into @@ -1373,13 +1386,13 @@ bool wxWindowDCImpl::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoor return true; } - int old_logical_func = m_logicalFunction; + wxRasterOperationMode old_logical_func = m_logicalFunction; SetLogicalFunction( logical_func ); if (use_bitmap_method) { wxBitmap selected = memDC->GetSelectedBitmap(); - + // scale/translate bitmap size wxCoord bm_width = selected.GetWidth(); wxCoord bm_height = selected.GetHeight(); @@ -1458,7 +1471,6 @@ bool wxWindowDCImpl::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoor // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For // drawing a mono-bitmap (XBitmap) we use the current text GC - if (is_mono) XCopyPlane( (Display*) m_display, (Pixmap) use_bitmap.GetBitmap(), (Window) m_x11window, (GC) m_textGC, xsrc, ysrc, width, height, xx, yy, 1 ); @@ -1487,6 +1499,14 @@ bool wxWindowDCImpl::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoor } else // use_bitmap_method { + wxDCImpl *impl = srcDC->GetImpl(); + wxWindowDCImpl *x11_impl = wxDynamicCast(impl, wxWindowDCImpl); + if (!x11_impl) + { + SetLogicalFunction( old_logical_func ); + return false; + } + if ((width != ww) || (height != hh)) { /* Draw source window into a bitmap as we cannot scale @@ -1506,7 +1526,7 @@ bool wxWindowDCImpl::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoor // copy including child window contents XSetSubwindowMode( (Display*) m_display, (GC) m_penGC, IncludeInferiors ); - XCopyArea( (Display*) m_display, (Window) srcDC->GetWindow(), (Window) bitmap.GetPixmap(), + XCopyArea( (Display*) m_display, (Window) x11_impl->GetX11Window(), (Window) bitmap.GetPixmap(), (GC) m_penGC, xsrc, ysrc, width, height, 0, 0 ); XSetSubwindowMode( (Display*) m_display, (GC) m_penGC, ClipByChildren ); @@ -1524,10 +1544,9 @@ bool wxWindowDCImpl::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoor else { // No scaling and not a memory dc with a mask either - // copy including child window contents XSetSubwindowMode( (Display*) m_display, (GC) m_penGC, IncludeInferiors ); - XCopyArea( (Display*) m_display, (Window) srcDC->GetWindow(), (Window) m_x11window, + XCopyArea( (Display*) m_display, (Window) x11_impl->GetX11Window(), (Window) m_x11window, (GC) m_penGC, xsrc, ysrc, width, height, xx, yy ); XSetSubwindowMode( (Display*) m_display, (GC) m_penGC, ClipByChildren ); } @@ -1551,8 +1570,8 @@ void wxWindowDCImpl::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) PangoLayout *layout = pango_layout_new(m_context); pango_layout_set_font_description(layout, m_fontdesc); - const wxCharBuffer data = wxConvUTF8.cWC2MB( text ); - pango_layout_set_text(layout, (const char*) data, strlen( (const char*) data )); + const wxScopedCharBuffer data(text.utf8_str()); + pango_layout_set_text(layout, data, data.length()); // Measure layout. int w,h; @@ -1639,7 +1658,9 @@ void wxWindowDCImpl::DoGetTextExtent( const wxString &string, wxCoord *width, wx wxCoord *descent, wxCoord *externalLeading, const wxFont *font ) const { - wxCHECK_RET( IsOk(), wxT("invalid dc") ); + // Do not test for DC validity here, querying text extents is supposed to + // work even with a non-initialized wxMemoryDC. And the code below does + // actually work in this case. if (string.empty()) { @@ -1656,8 +1677,8 @@ void wxWindowDCImpl::DoGetTextExtent( const wxString &string, wxCoord *width, wx else pango_layout_set_font_description(layout, m_fontdesc); - const wxCharBuffer data = wxConvUTF8.cWC2MB( string ); - pango_layout_set_text(layout, (const char*) data, strlen( (const char*) data )); + const wxScopedCharBuffer data(string.utf8_str()); + pango_layout_set_text(layout, data, data.length()); // Measure text. int w,h; @@ -1702,7 +1723,8 @@ void wxWindowDCImpl::DoGetTextExtent( const wxString &string, wxCoord *width, wx wxCoord wxWindowDCImpl::GetCharWidth() const { - wxCHECK_MSG( IsOk(), 0, wxT("invalid dc") ); + // Do not test for DC validity here for the same reasons as in + // DoGetTextExtent() above. #if wxUSE_UNICODE PangoLayout *layout = pango_layout_new( m_context ); @@ -1736,7 +1758,8 @@ wxCoord wxWindowDCImpl::GetCharWidth() const wxCoord wxWindowDCImpl::GetCharHeight() const { - wxCHECK_MSG( IsOk(), 0, wxT("invalid dc") ); + // Do not test for DC validity here for the same reasons as in + // DoGetTextExtent() above. #if wxUSE_UNICODE PangoLayout *layout = pango_layout_new( m_context ); @@ -1894,7 +1917,7 @@ void wxWindowDCImpl::SetPen( const wxPen &pen ) default: { lineStyle = LineSolid; - req_dash = (wxX11Dash*)NULL; + req_dash = NULL; req_nb_dash = 0; break; } @@ -2026,7 +2049,7 @@ void wxWindowDCImpl::SetBackground( const wxBrush &brush ) } } -void wxWindowDCImpl::SetLogicalFunction( int function ) +void wxWindowDCImpl::SetLogicalFunction( wxRasterOperationMode function ) { wxCHECK_RET( IsOk(), wxT("invalid dc") ); @@ -2208,7 +2231,7 @@ void wxWindowDCImpl::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, w wxCoord xx, yy, ww, hh; m_currentClippingRegion.GetBox( xx, yy, ww, hh ); - wxDCImpl::DoSetClippingRegion( xx, yy, ww, hh ); + wxX11DCImpl::DoSetClippingRegion( xx, yy, ww, hh ); XSetRegion( (Display*) m_display, (GC) m_penGC, (Region) m_currentClippingRegion.GetX11Region() ); XSetRegion( (Display*) m_display, (GC) m_brushGC, (Region) m_currentClippingRegion.GetX11Region() ); @@ -2216,7 +2239,7 @@ void wxWindowDCImpl::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, w XSetRegion( (Display*) m_display, (GC) m_bgGC, (Region) m_currentClippingRegion.GetX11Region() ); } -void wxWindowDCImpl::DoSetClippingRegionAsRegion( const wxRegion& region ) +void wxWindowDCImpl::DoSetDeviceClippingRegion( const wxRegion& region ) { wxCHECK_RET( IsOk(), wxT("invalid window dc") ); @@ -2240,7 +2263,7 @@ void wxWindowDCImpl::DoSetClippingRegionAsRegion( const wxRegion& region ) wxCoord xx, yy, ww, hh; m_currentClippingRegion.GetBox( xx, yy, ww, hh ); - wxDCImpl::DoSetClippingRegion( xx, yy, ww, hh ); + wxX11DCImpl::DoSetClippingRegion( xx, yy, ww, hh ); XSetRegion( (Display*) m_display, (GC) m_penGC, (Region) m_currentClippingRegion.GetX11Region() ); XSetRegion( (Display*) m_display, (GC) m_brushGC, (Region) m_currentClippingRegion.GetX11Region() ); @@ -2327,17 +2350,17 @@ int wxWindowDCImpl::GetDepth() const // wxClientDC //----------------------------------------------------------------------------- -IMPLEMENT_DYNAMIC_CLASS(wxClientDC, wxWindowDC) +IMPLEMENT_ABSTRACT_CLASS(wxClientDCImpl, wxWindowDCImpl) wxClientDCImpl::wxClientDCImpl( wxDC *owner, wxWindow *window ) : wxWindowDCImpl( owner, window ) { - wxCHECK_RET( window, _T("NULL window in wxClientDC::wxClientDC") ); + wxCHECK_RET( window, wxT("NULL window in wxClientDC::wxClientDC") ); m_x11window = (WXWindow*) window->GetClientAreaWindow(); // Adjust the client area when the wxWindow is not using 2 X11 windows. - if (m_x11window == (WXWindow*) window->GetMainWindow()) + if (m_x11window == (WXWindow*) window->X11GetMainWindow()) { wxPoint ptOrigin = window->GetClientAreaOrigin(); SetDeviceOrigin(ptOrigin.x, ptOrigin.y); @@ -2348,7 +2371,7 @@ wxClientDCImpl::wxClientDCImpl( wxDC *owner, wxWindow *window ) void wxClientDCImpl::DoGetSize(int *width, int *height) const { - wxCHECK_RET( m_window, _T("GetSize() doesn't work without window") ); + wxCHECK_RET( m_window, wxT("GetSize() doesn't work without window") ); m_window->GetClientSize( width, height ); } @@ -2391,7 +2414,7 @@ public: // display wxDCModule() { - AddDependency(wxClassInfo::FindClass(_T("wxX11DisplayModule"))); + AddDependency(wxClassInfo::FindClass(wxT("wxX11DisplayModule"))); } bool OnInit() { wxInitGCPool(); return true; }