/////////////////////////////////////////////////////////////////////////////
-// Name: x11/dcclient.cpp
+// Name: src/x11/dcclient.cpp
// Purpose: wxClientDC class
// Author: Julian Smart, Robert Roebling
// Modified by:
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
-#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
- #pragma implementation "dcclient.h"
-#endif
+// 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 <math.h>
-
#if wxUSE_UNICODE
#include "glib.h"
#include "pango/pangox.h"
-#include "pango/pangoxft.h"
+#ifdef HAVE_PANGO_XFT
+ #include "pango/pangoxft.h"
+#endif
#include "pango_x.cpp"
#endif
// local defines
//-----------------------------------------------------------------------------
-#define USE_PAINT_REGION 1
+// VZ: what is this for exactly??
+#define USE_PAINT_REGION 0
//-----------------------------------------------------------------------------
// local data
IMPLEMENT_DYNAMIC_CLASS(wxWindowDC, wxDC)
-wxWindowDC::wxWindowDC()
+void wxWindowDC::Init()
{
m_display = (WXDisplay *) NULL;
m_penGC = (WXGC *) NULL;
m_owner = (wxWindow *)NULL;
#if wxUSE_UNICODE
- m_context = (PangoContext *)NULL;
+ m_context = wxTheApp->GetPangoContext();
m_fontdesc = (PangoFontDescription *)NULL;
#endif
}
{
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();
m_display = (WXDisplay *) wxGlobalDisplay();
#if wxUSE_UNICODE
- m_context = wxTheApp->GetPangoContext();
m_fontdesc = window->GetFont().GetNativeFontInfo()->description;
#endif
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)
{
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;
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;
XSetFont( (Display*) m_display, (GC) m_textGC, xfont->fid );
#if !wxUSE_NANOX
- if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
+ // This may be a test for whether the font is 16-bit, but it also
+ // seems to fail for valid 8-bit fonts too.
+ if (1) // (xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
#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
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") );
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)
#if wxUSE_UNICODE
PangoLayout *layout = pango_layout_new( m_context );
- if (!m_fontdesc)
- {
- char *crash = NULL;
- *crash = 0;
- }
+ if (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, m_fontdesc);
pango_layout_set_text(layout, "H", 1 );
int w,h;
pango_layout_get_pixel_size(layout, &w, &h);
#if wxUSE_UNICODE
PangoLayout *layout = pango_layout_new( m_context );
- if (!m_fontdesc)
- {
- char *crash = NULL;
- *crash = 0;
- }
-
- pango_layout_set_font_description(layout, m_fontdesc);
+ if (m_fontdesc)
+ pango_layout_set_font_description(layout, m_fontdesc);
+ else
+ pango_layout_set_font_description(layout, this->GetFont().GetNativeFontInfo()->description);
pango_layout_set_text(layout, "H", 1 );
int w,h;
wxCHECK_RET( Ok(), wxT("invalid dc") );
m_font = font;
+
+#if wxUSE_UNICODE
+ m_fontdesc = font.GetNativeFontInfo()->description;
+#endif
}
void wxWindowDC::SetPen( const wxPen &pen )
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
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
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)
IMPLEMENT_DYNAMIC_CLASS(wxDCModule, wxModule)
-bool wxDCModule::OnInit()
-{
- wxInitGCPool();
- return true;
-}
-
-void wxDCModule::OnExit()
-{
- wxCleanUpGCPool();
-}