X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a4f4d548ce0d3533fe9e84d812643cc7c21dd580..6e1609b1e0784f299933742e02c58462df809acc:/src/x11/dcclient.cpp diff --git a/src/x11/dcclient.cpp b/src/x11/dcclient.cpp index 0278302b5f..5e19609f43 100644 --- a/src/x11/dcclient.cpp +++ b/src/x11/dcclient.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: x11/dcclient.cpp +// Name: src/x11/dcclient.cpp // Purpose: wxClientDC class // Author: Julian Smart, Robert Roebling // Modified by: @@ -9,18 +9,24 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// +// for compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + #include "wx/dcclient.h" -#include "wx/dcmemory.h" -#include "wx/window.h" -#include "wx/app.h" -#include "wx/image.h" -#include "wx/module.h" + +#ifndef WX_PRECOMP + #include "wx/app.h" + #include "wx/window.h" + #include "wx/dcmemory.h" + #include "wx/math.h" + #include "wx/image.h" + #include "wx/module.h" +#endif + #include "wx/fontutil.h" #include "wx/x11/private.h" -#include "wx/math.h" - #if wxUSE_UNICODE #include "glib.h" #include "pango/pangox.h" @@ -35,7 +41,8 @@ // local defines //----------------------------------------------------------------------------- -#define USE_PAINT_REGION 1 +// VZ: what is this for exactly?? +#define USE_PAINT_REGION 0 //----------------------------------------------------------------------------- // local data @@ -159,7 +166,7 @@ static void wxFreePoolGC( GC gc ) IMPLEMENT_DYNAMIC_CLASS(wxWindowDC, wxDC) -wxWindowDC::wxWindowDC() +void wxWindowDC::Init() { m_display = (WXDisplay *) NULL; m_penGC = (WXGC *) NULL; @@ -172,7 +179,7 @@ wxWindowDC::wxWindowDC() m_owner = (wxWindow *)NULL; #if wxUSE_UNICODE - m_context = (PangoContext *)NULL; + m_context = wxTheApp->GetPangoContext(); m_fontdesc = (PangoFontDescription *)NULL; #endif } @@ -181,15 +188,8 @@ wxWindowDC::wxWindowDC( wxWindow *window ) { wxASSERT_MSG( window, wxT("DC needs a window") ); - 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_owner = (wxWindow *)NULL; - m_isMemDC = false; - m_isScreenDC = false; + Init(); + m_font = window->GetFont(); m_window = (WXWindow*) window->GetMainWindow(); @@ -206,7 +206,6 @@ wxWindowDC::wxWindowDC( wxWindow *window ) m_display = (WXDisplay *) wxGlobalDisplay(); #if wxUSE_UNICODE - m_context = wxTheApp->GetPangoContext(); m_fontdesc = window->GetFont().GetNativeFontInfo()->description; #endif @@ -626,7 +625,8 @@ void wxWindowDC::DoDrawLines( int n, wxPoint points[], wxCoord xoffset, wxCoord } void wxWindowDC::DoDrawPolygon( int n, wxPoint points[], - wxCoord xoffset, wxCoord yoffset, int fillStyle ) + wxCoord xoffset, wxCoord yoffset, + int WXUNUSED(fillStyle) ) { wxCHECK_RET( Ok(), wxT("invalid window dc") ); @@ -1170,62 +1170,78 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, WXPixmap mask = NULL; if (use_bitmap.GetMask()) mask = use_bitmap.GetMask()->GetBitmap(); - if (useMask && mask) + bool setClipMask = false; + + if (!m_currentClippingRegion.IsNull() || (useMask && mask)) + { + // XSetClipMask() call is necessary (because of clip region and/or transparent mask) + setClipMask = true; + Pixmap new_pixmap = 0; + + if (!m_currentClippingRegion.IsNull()) { - WXPixmap new_mask = NULL; -#if 0 - if (!m_currentClippingRegion.IsNull()) - { - GdkColor col; - new_mask = gdk_pixmap_new( wxGetRootWindow()->window, ww, hh, 1 ); - GdkGC *gc = gdk_gc_new( new_mask ); - col.pixel = 0; - gdk_gc_set_foreground( gc, &col ); - gdk_draw_rectangle( new_mask, gc, TRUE, 0, 0, ww, hh ); - col.pixel = 0; - gdk_gc_set_background( gc, &col ); - col.pixel = 1; - gdk_gc_set_foreground( gc, &col ); - gdk_gc_set_clip_region( gc, m_currentClippingRegion.GetRegion() ); - gdk_gc_set_clip_origin( gc, -xx, -yy ); - gdk_gc_set_fill( gc, GDK_OPAQUE_STIPPLED ); - gdk_gc_set_stipple( gc, mask ); - gdk_draw_rectangle( new_mask, gc, TRUE, 0, 0, ww, hh ); - gdk_gc_unref( gc ); - } -#endif - if (is_mono) - { - if (new_mask) - XSetClipMask( (Display*) m_display, (GC) m_textGC, (Pixmap) new_mask ); - else - XSetClipMask( (Display*) m_display, (GC) m_textGC, (Pixmap) mask ); - XSetClipOrigin( (Display*) m_display, (GC) m_textGC, xx, yy ); - } - else + // clipping necessary => create new_pixmap + Display *xdisplay = (Display*) m_display; + int xscreen = DefaultScreen( xdisplay ); + Window xroot = RootWindow( xdisplay, xscreen ); + + new_pixmap = XCreatePixmap( xdisplay, xroot, ww, hh, 1 ); + GC gc = XCreateGC( xdisplay, new_pixmap, 0, NULL ); + + XSetForeground( xdisplay, gc, BlackPixel(xdisplay,xscreen) ); + + XSetFillStyle( xdisplay, gc, FillSolid ); + XFillRectangle( xdisplay, new_pixmap, gc, 0, 0, ww, hh ); + + XSetForeground( xdisplay, gc, WhitePixel(xdisplay,xscreen) ); + + if (useMask && mask) { - if (new_mask) - XSetClipMask( (Display*) m_display, (GC) m_penGC, (Pixmap) new_mask ); - else - XSetClipMask( (Display*) m_display, (GC) m_penGC, (Pixmap) mask ); - XSetClipOrigin( (Display*) m_display, (GC) m_penGC, xx, yy ); + // transparent mask => call XSetStipple + XSetFillStyle( xdisplay, gc, FillStippled ); + XSetTSOrigin( xdisplay, gc, 0, 0); + XSetStipple( xdisplay, gc, (Pixmap) mask); } - if (new_mask) - XFreePixmap( (Display*) m_display, (Pixmap) new_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 ); + + XFreeGC( xdisplay, gc ); + } + + if (is_mono) + { + if (new_pixmap) + XSetClipMask( (Display*) m_display, (GC) m_textGC, new_pixmap ); + else + XSetClipMask( (Display*) m_display, (GC) m_textGC, (Pixmap) mask ); + XSetClipOrigin( (Display*) m_display, (GC) m_textGC, xx, yy ); } + else + { + if (new_pixmap) + XSetClipMask( (Display*) m_display, (GC) m_penGC, new_pixmap ); + else + XSetClipMask( (Display*) m_display, (GC) m_penGC, (Pixmap) mask ); + XSetClipOrigin( (Display*) m_display, (GC) m_penGC, xx, yy ); + } + + if (new_pixmap) + XFreePixmap( (Display*) m_display, new_pixmap ); + } // 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_window, - (GC) m_textGC, 0, 0, w, h, xx, yy, 1 ); + (GC) m_textGC, 0, 0, ww, hh, xx, yy, 1 ); else XCopyArea( (Display*) m_display, (Pixmap) use_bitmap.GetPixmap(), (Window) m_window, - (GC) m_penGC, 0, 0, w, h, xx, yy ); + (GC) m_penGC, 0, 0, ww, hh, xx, yy ); // remove mask again if any - if (useMask && mask) + if (setClipMask) { if (is_mono) { @@ -1262,8 +1278,8 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he if (!m_window) return false; // transform the source DC coords to the device ones - xsrc = source->XLOG2DEV(xsrc); - ysrc = source->YLOG2DEV(ysrc); + xsrc = source->LogicalToDeviceX(xsrc); + ysrc = source->LogicalToDeviceY(ysrc); wxClientDC *srcDC = (wxClientDC*)source; wxMemoryDC *memDC = (wxMemoryDC*)source; @@ -1549,7 +1565,7 @@ void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) slen = strlen(text); XCharStruct overall_return; - (void)XTextExtents(xfont, (char*) text.c_str(), slen, &direction, + (void)XTextExtents(xfont, (const char*) text.c_str(), slen, &direction, &ascent, &descent, &overall_return); cx = overall_return.width; @@ -1571,7 +1587,7 @@ void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) #endif { XDrawString( (Display*) m_display, (Window) m_window, - (GC) m_textGC, x, y + XFontStructGetAscent(xfont), text.c_str(), text.Len() ); + (GC) m_textGC, x, y + XFontStructGetAscent(xfont), text.c_str(), text.length() ); } #if 0 @@ -1591,14 +1607,16 @@ void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) #endif } -void wxWindowDC::DoDrawRotatedText( const wxString &text, wxCoord x, wxCoord y, double angle ) +void wxWindowDC::DoDrawRotatedText(const wxString& WXUNUSED(text), + wxCoord WXUNUSED(x), wxCoord WXUNUSED(y), + double WXUNUSED(angle)) { - // later + wxFAIL_MSG( "not implemented" ); } void wxWindowDC::DoGetTextExtent( const wxString &string, wxCoord *width, wxCoord *height, wxCoord *descent, wxCoord *externalLeading, - wxFont *font ) const + const wxFont *font ) const { wxCHECK_RET( Ok(), wxT("invalid dc") ); @@ -1647,7 +1665,7 @@ void wxWindowDC::DoGetTextExtent( const wxString &string, wxCoord *width, wxCoor int direction, ascent, descent2; XCharStruct overall; - XTextExtents( xfont, (char*) string.c_str(), string.Len(), &direction, + XTextExtents( xfont, (const char*) string.c_str(), string.length(), &direction, &ascent, &descent2, &overall); if (width) @@ -1669,10 +1687,10 @@ wxCoord wxWindowDC::GetCharWidth() const PangoLayout *layout = pango_layout_new( m_context ); if (m_fontdesc) - pango_layout_set_font_description(layout, m_fontdesc); + pango_layout_set_font_description(layout, m_fontdesc); else - pango_layout_set_font_description(layout, this->GetFont().GetNativeFontInfo()->description); - + pango_layout_set_font_description(layout, this->GetFont().GetNativeFontInfo()->description); + pango_layout_set_text(layout, "H", 1 ); int w,h; pango_layout_get_pixel_size(layout, &w, &h); @@ -1703,10 +1721,10 @@ wxCoord wxWindowDC::GetCharHeight() const PangoLayout *layout = pango_layout_new( m_context ); if (m_fontdesc) - pango_layout_set_font_description(layout, m_fontdesc); + pango_layout_set_font_description(layout, m_fontdesc); else - pango_layout_set_font_description(layout, this->GetFont().GetNativeFontInfo()->description); - + pango_layout_set_font_description(layout, this->GetFont().GetNativeFontInfo()->description); + pango_layout_set_text(layout, "H", 1 ); int w,h; pango_layout_get_pixel_size(layout, &w, &h); @@ -1764,9 +1782,7 @@ void wxWindowDC::SetFont( const wxFont &font ) wxCHECK_RET( Ok(), wxT("invalid dc") ); m_font = font; - - return; - + #if wxUSE_UNICODE m_fontdesc = font.GetNativeFontInfo()->description; #endif @@ -2124,7 +2140,7 @@ void wxWindowDC::SetBackgroundMode( int mode ) } } -void wxWindowDC::SetPalette( const wxPalette& palette ) +void wxWindowDC::SetPalette( const wxPalette& WXUNUSED(palette) ) { #if 0 if (m_window) @@ -2147,19 +2163,25 @@ void wxWindowDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoo if (!m_window) return; + if (width <= 0) + width = 1; + + if (height <= 0) + height = 1; + wxRect rect; rect.x = XLOG2DEV(x); rect.y = YLOG2DEV(y); rect.width = XLOG2DEVREL(width); rect.height = YLOG2DEVREL(height); - if (!m_currentClippingRegion.IsNull()) + if (!m_currentClippingRegion.IsEmpty()) m_currentClippingRegion.Intersect( rect ); else - m_currentClippingRegion.Union( rect ); + m_currentClippingRegion = rect; #if USE_PAINT_REGION - if (!m_paintClippingRegion.IsNull()) + if (!m_paintClippingRegion.IsEmpty()) m_currentClippingRegion.Intersect( m_paintClippingRegion ); #endif @@ -2185,13 +2207,13 @@ void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion& region ) if (!m_window) return; - if (!m_currentClippingRegion.IsNull()) + if (!m_currentClippingRegion.IsEmpty()) m_currentClippingRegion.Intersect( region ); else - m_currentClippingRegion.Union( region ); + m_currentClippingRegion = region; #if USE_PAINT_REGION - if (!m_paintClippingRegion.IsNull()) + if (!m_paintClippingRegion.IsEmpty()) m_currentClippingRegion.Intersect( m_paintClippingRegion ); #endif @@ -2344,8 +2366,15 @@ wxPaintDC::wxPaintDC(wxWindow* window) class wxDCModule : public wxModule { public: - bool OnInit(); - void OnExit(); + // we must be cleaned up before wxDisplayModule which closes the global + // display + wxDCModule() + { + AddDependency(wxClassInfo::FindClass(_T("wxX11DisplayModule"))); + } + + bool OnInit() { wxInitGCPool(); return true; } + void OnExit() { wxCleanUpGCPool(); } private: DECLARE_DYNAMIC_CLASS(wxDCModule) @@ -2353,13 +2382,3 @@ private: IMPLEMENT_DYNAMIC_CLASS(wxDCModule, wxModule) -bool wxDCModule::OnInit() -{ - wxInitGCPool(); - return true; -} - -void wxDCModule::OnExit() -{ - wxCleanUpGCPool(); -}