X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ab6b6b15e0790bf3fd9e5b58da7077ac5592d8d3..a7734bdfb398c42321d985abdad7304bb3ac5182:/src/x11/dcclient.cpp diff --git a/src/x11/dcclient.cpp b/src/x11/dcclient.cpp index 23629d5500..d5832711b8 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,19 +9,33 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ - #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" + +#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 +#if wxUSE_UNICODE +#include "glib.h" +#include "pango/pangox.h" +#ifdef HAVE_PANGO_XFT + #include "pango/pangoxft.h" +#endif + +#include "pango_x.cpp" +#endif //----------------------------------------------------------------------------- // local defines @@ -117,11 +131,11 @@ static GC wxGetPoolGC( Window window, wxPoolGCType type ) wxGCPool[i].m_gc = XCreateGC( wxGlobalDisplay(), window, 0, NULL ); XSetGraphicsExposures( wxGlobalDisplay(), wxGCPool[i].m_gc, FALSE ); wxGCPool[i].m_type = type; - wxGCPool[i].m_used = FALSE; + wxGCPool[i].m_used = false; } if ((!wxGCPool[i].m_used) && (wxGCPool[i].m_type == type)) { - wxGCPool[i].m_used = TRUE; + wxGCPool[i].m_used = true; return wxGCPool[i].m_gc; } } @@ -137,7 +151,7 @@ static void wxFreePoolGC( GC gc ) { if (wxGCPool[i].m_gc == gc) { - wxGCPool[i].m_used = FALSE; + wxGCPool[i].m_used = false; return; } } @@ -151,7 +165,7 @@ static void wxFreePoolGC( GC gc ) IMPLEMENT_DYNAMIC_CLASS(wxWindowDC, wxDC) -wxWindowDC::wxWindowDC() +void wxWindowDC::Init() { m_display = (WXDisplay *) NULL; m_penGC = (WXGC *) NULL; @@ -159,24 +173,22 @@ wxWindowDC::wxWindowDC() m_textGC = (WXGC *) NULL; m_bgGC = (WXGC *) NULL; m_cmap = (WXColormap *) NULL; - m_isMemDC = FALSE; - m_isScreenDC = FALSE; + m_isMemDC = false; + m_isScreenDC = false; m_owner = (wxWindow *)NULL; + +#if wxUSE_UNICODE + m_context = wxTheApp->GetPangoContext(); + m_fontdesc = (PangoFontDescription *)NULL; +#endif } 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(); @@ -185,13 +197,17 @@ wxWindowDC::wxWindowDC( wxWindow *window ) if (!m_window) { // don't report problems - m_ok = TRUE; + m_ok = true; return; } m_display = (WXDisplay *) wxGlobalDisplay(); - + +#if wxUSE_UNICODE + m_fontdesc = window->GetFont().GetNativeFontInfo()->description; +#endif + int screen = DefaultScreen( (Display*) m_display ); m_cmap = (WXColormap) DefaultColormap( (Display*) m_display, screen ); @@ -214,7 +230,7 @@ wxWindowDC::~wxWindowDC() void wxWindowDC::SetUpDC() { - m_ok = TRUE; + m_ok = true; wxASSERT_MSG( !m_penGC, wxT("GCs already created") ); @@ -246,6 +262,9 @@ void wxWindowDC::SetUpDC() m_backgroundBrush.GetColour().CalcPixel( m_cmap ); unsigned long bg_col = m_backgroundBrush.GetColour().GetPixel(); + m_textForegroundColour = *wxBLACK; + m_textBackgroundColour = *wxWHITE; + /* m_textGC */ m_textForegroundColour.CalcPixel( m_cmap ); XSetForeground( (Display*) m_display, (GC) m_textGC, m_textForegroundColour.GetPixel() ); @@ -277,7 +296,7 @@ void wxWindowDC::SetUpDC() /* m_bgGC */ XSetForeground( (Display*) m_display, (GC) m_bgGC, bg_col ); XSetBackground( (Display*) m_display, (GC) m_bgGC, bg_col ); - + XSetFillStyle( (Display*) m_display, (GC) m_bgGC, FillSolid ); /* ROPs */ @@ -295,7 +314,7 @@ void wxWindowDC::SetUpDC() { int xscreen = DefaultScreen( (Display*) m_display ); Window xroot = RootWindow( (Display*) m_display, xscreen ); - + hatch_bitmap = hatches; hatch_bitmap[0] = XCreateBitmapFromData( (Display*) m_display, xroot, bdiag_bits, bdiag_width, bdiag_height ); hatch_bitmap[1] = XCreateBitmapFromData( (Display*) m_display, xroot, cdiag_bits, cdiag_width, cdiag_height ); @@ -313,10 +332,13 @@ void wxWindowDC::DoGetSize( int* width, int* height ) const m_owner->GetSize(width, height); } -void wxWindowDC::DoFloodFill( wxCoord WXUNUSED(x1), wxCoord WXUNUSED(y1), - const wxColour& WXUNUSED(col), int WXUNUSED(style) ) +extern bool wxDoFloodFill(wxDC *dc, wxCoord x, wxCoord y, + const wxColour & col, int style); + +bool wxWindowDC::DoFloodFill(wxCoord x, wxCoord y, + const wxColour& col, int style) { - wxFAIL_MSG("not implemented"); + return wxDoFloodFill(this, x, y, col, style); } bool wxWindowDC::DoGetPixel( wxCoord x1, wxCoord y1, wxColour *col ) const @@ -328,9 +350,9 @@ bool wxWindowDC::DoGetPixel( wxCoord x1, wxCoord y1, wxColour *col ) const memdc.SelectObject(bitmap); memdc.Blit(0, 0, 1, 1, (wxDC*) this, x1, y1); memdc.SelectObject(wxNullBitmap); - wxImage image(bitmap); + wxImage image(bitmap.ConvertToImage()); col->Set(image.GetRed(0, 0), image.GetGreen(0, 0), image.GetBlue(0, 0)); - return TRUE; + return true; } void wxWindowDC::DoDrawLine( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2 ) @@ -340,8 +362,19 @@ void wxWindowDC::DoDrawLine( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2 ) if (m_pen.GetStyle() != wxTRANSPARENT) { if (m_window) - XDrawLine( (Display*) m_display, (Window) m_window, - (GC) m_penGC, XLOG2DEV(x1), YLOG2DEV(y1), XLOG2DEV(x2), YLOG2DEV(y2) ); + { + // This hack is for the iPaq: XDrawLine draws + // nothing, whereas XDrawLines works... + wxPoint points[2]; + points[0].x = x1; + points[0].y = y1; + points[1].x = x2; + points[1].y = y2; + DrawLines( 2, points, 0, 0 ); + + // XDrawLine( (Display*) m_display, (Window) m_window, + // (GC) m_penGC, XLOG2DEV(x1), YLOG2DEV(y1), XLOG2DEV(x2), YLOG2DEV(y2) ); + } CalcBoundingBox(x1, y1); CalcBoundingBox(x2, y2); @@ -418,30 +451,30 @@ void wxWindowDC::DoDrawArc( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, wxCo XSetTSOrigin( (Display*) m_display, (GC) m_textGC, m_deviceOriginX % m_brush.GetStipple()->GetWidth(), m_deviceOriginY % m_brush.GetStipple()->GetHeight() ); - + XFillArc( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xxc-r, yyc-r, 2*r,2*r, alpha1, alpha2 ); - + XSetTSOrigin( (Display*) m_display, (GC) m_textGC, 0, 0 ); } else if (IS_15_PIX_HATCH(m_brush.GetStyle())) { XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, m_deviceOriginX % 15, m_deviceOriginY % 15 ); - + XFillArc( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xxc-r, yyc-r, 2*r,2*r, alpha1, alpha2 ); - + XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0 ); } else if (IS_16_PIX_HATCH(m_brush.GetStyle())) { XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, m_deviceOriginX % 16, m_deviceOriginY % 16 ); - + XFillArc( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xxc-r, yyc-r, 2*r,2*r, alpha1, alpha2 ); - + XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0 ); } else if (m_brush.GetStyle() == wxSTIPPLE) @@ -449,10 +482,10 @@ void wxWindowDC::DoDrawArc( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, wxCo XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, m_deviceOriginX % m_brush.GetStipple()->GetWidth(), m_deviceOriginY % m_brush.GetStipple()->GetHeight() ); - + XFillArc( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xxc-r, yyc-r, 2*r,2*r, alpha1, alpha2 ); - + XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0 ); } else @@ -466,10 +499,10 @@ void wxWindowDC::DoDrawArc( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, wxCo { XDrawArc( (Display*) m_display, (Window) m_window, (GC) m_penGC, xxc-r, yyc-r, 2*r,2*r, alpha1, alpha2 ); - + XDrawLine( (Display*) m_display, (Window) m_window, (GC) m_penGC, xx1, yy1, xxc, yyc ); - + XDrawLine( (Display*) m_display, (Window) m_window, (GC) m_penGC, xxc, yyc, xx2, yy2 ); } @@ -504,30 +537,30 @@ void wxWindowDC::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord width, wxCoord XSetTSOrigin( (Display*) m_display, (GC) m_textGC, m_deviceOriginX % m_brush.GetStipple()->GetWidth(), m_deviceOriginY % m_brush.GetStipple()->GetHeight() ); - + XFillArc( (Display*) m_display, (Window) m_window, (GC) m_textGC, xx, yy, ww, hh, start, end ); - + XSetTSOrigin( (Display*) m_display, (GC) m_textGC, 0, 0 ); } else if (IS_15_PIX_HATCH(m_brush.GetStyle())) { XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, m_deviceOriginX % 15, m_deviceOriginY % 15 ); - + XFillArc( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx, yy, ww, hh, start, end ); - + XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0 ); } else if (IS_16_PIX_HATCH(m_brush.GetStyle())) { XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, m_deviceOriginX % 16, m_deviceOriginY % 16 ); - + XFillArc( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx, yy, ww, hh, start, end ); - + XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0 ); } else if (m_brush.GetStyle() == wxSTIPPLE) @@ -535,10 +568,10 @@ void wxWindowDC::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord width, wxCoord XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, m_deviceOriginX % m_brush.GetStipple()->GetWidth(), m_deviceOriginY % m_brush.GetStipple()->GetHeight() ); - + XFillArc( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx, yy, ww, hh, start, end ); - + XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0 ); } else @@ -582,7 +615,7 @@ void wxWindowDC::DoDrawLines( int n, wxPoint points[], wxCoord xoffset, wxCoord { xpoints[i].x = XLOG2DEV (points[i].x + xoffset); xpoints[i].y = YLOG2DEV (points[i].y + yoffset); - + CalcBoundingBox( points[i].x + xoffset, points[i].y + yoffset ); } XDrawLines( (Display*) m_display, (Window) m_window, (GC) m_penGC, xpoints, n, 0 ); @@ -603,7 +636,7 @@ void wxWindowDC::DoDrawPolygon( int n, wxPoint points[], { xpoints[i].x = XLOG2DEV (points[i].x + xoffset); xpoints[i].y = YLOG2DEV (points[i].y + yoffset); - + CalcBoundingBox (points[i].x + xoffset, points[i].y + yoffset); } @@ -611,36 +644,36 @@ void wxWindowDC::DoDrawPolygon( int n, wxPoint points[], { if (m_brush.GetStyle() != wxTRANSPARENT) { - + if ((m_brush.GetStyle() == wxSTIPPLE_MASK_OPAQUE) && (m_brush.GetStipple()->GetMask())) { XSetTSOrigin( (Display*) m_display, (GC) m_textGC, m_deviceOriginX % m_brush.GetStipple()->GetWidth(), m_deviceOriginY % m_brush.GetStipple()->GetHeight() ); - + XFillPolygon( (Display*) m_display, (Window) m_window, (GC) m_textGC, xpoints, n, Complex, 0); - + XSetTSOrigin( (Display*) m_display, (GC) m_textGC, 0, 0 ); } else if (IS_15_PIX_HATCH(m_brush.GetStyle())) { XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, m_deviceOriginX % 15, m_deviceOriginY % 15 ); - + XFillPolygon( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xpoints, n, Complex, 0); - + XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0 ); } else if (IS_16_PIX_HATCH(m_brush.GetStyle())) { XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, m_deviceOriginX % 16, m_deviceOriginY % 16 ); - + XFillPolygon( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xpoints, n, Complex, 0); - + XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0 ); } else if (m_brush.GetStyle() == wxSTIPPLE) @@ -648,10 +681,10 @@ void wxWindowDC::DoDrawPolygon( int n, wxPoint points[], XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, m_deviceOriginX % m_brush.GetStipple()->GetWidth(), m_deviceOriginY % m_brush.GetStipple()->GetHeight() ); - + XFillPolygon( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xpoints, n, Complex, 0); - + XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0 ); } else @@ -689,7 +722,7 @@ void wxWindowDC::DoDrawRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoord h // CMB: handle -ve width and/or height if (ww < 0) { ww = -ww; xx = xx - ww; } if (hh < 0) { hh = -hh; yy = yy - hh; } - + if (m_window) { if (m_brush.GetStyle() != wxTRANSPARENT) @@ -699,30 +732,30 @@ void wxWindowDC::DoDrawRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoord h XSetTSOrigin( (Display*) m_display, (GC) m_textGC, m_deviceOriginX % m_brush.GetStipple()->GetWidth(), m_deviceOriginY % m_brush.GetStipple()->GetHeight() ); - + XFillRectangle( (Display*) m_display, (Window) m_window, (GC) m_textGC, xx, yy, ww, hh ); - + XSetTSOrigin( (Display*) m_display, (GC) m_textGC, 0, 0 ); } else if (IS_15_PIX_HATCH(m_brush.GetStyle())) { XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, m_deviceOriginX % 15, m_deviceOriginY % 15 ); - + XFillRectangle( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx, yy, ww, hh ); - + XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0 ); } else if (IS_16_PIX_HATCH(m_brush.GetStyle())) { XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, m_deviceOriginX % 16, m_deviceOriginY % 16 ); - + XFillRectangle( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx, yy, ww, hh ); - + XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0 ); } else if (m_brush.GetStyle() == wxSTIPPLE) @@ -730,10 +763,10 @@ void wxWindowDC::DoDrawRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoord h XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, m_deviceOriginX % m_brush.GetStipple()->GetWidth(), m_deviceOriginY % m_brush.GetStipple()->GetHeight() ); - + XFillRectangle( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx, yy, ww, hh ); - + XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0 ); } else @@ -756,7 +789,125 @@ void wxWindowDC::DoDrawRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoord h void wxWindowDC::DoDrawRoundedRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoord height, double radius ) { - // later + wxCHECK_RET( Ok(), wxT("invalid window dc") ); + + if (radius < 0.0) radius = - radius * ((width < height) ? width : height); + + wxCoord xx = XLOG2DEV(x); + wxCoord yy = YLOG2DEV(y); + wxCoord ww = m_signX * XLOG2DEVREL(width); + wxCoord hh = m_signY * YLOG2DEVREL(height); + wxCoord rr = XLOG2DEVREL((wxCoord)radius); + + // CMB: handle -ve width and/or height + if (ww < 0) { ww = -ww; xx = xx - ww; } + if (hh < 0) { hh = -hh; yy = yy - hh; } + + // CMB: if radius is zero use DrawRectangle() instead to avoid + // X drawing errors with small radii + if (rr == 0) + { + XDrawRectangle( (Display*) m_display, (Window) m_window, + (GC) m_penGC, x, y, width, height); + return; + } + + // CMB: draw nothing if transformed w or h is 0 + if (ww == 0 || hh == 0) return; + + // CMB: adjust size if outline is drawn otherwise the result is + // 1 pixel too wide and high + if (m_pen.GetStyle() != wxTRANSPARENT) + { + ww--; + hh--; + } + + if (m_window) + { + // CMB: ensure dd is not larger than rectangle otherwise we + // get an hour glass shape + wxCoord dd = 2 * rr; + if (dd > ww) dd = ww; + if (dd > hh) dd = hh; + rr = dd / 2; + + if (m_brush.GetStyle() != wxTRANSPARENT) + { + if ((m_brush.GetStyle() == wxSTIPPLE_MASK_OPAQUE) && (m_brush.GetStipple()->GetMask())) + { + XSetTSOrigin( (Display*) m_display, (GC) m_textGC, + m_deviceOriginX % m_brush.GetStipple()->GetWidth(), + m_deviceOriginY % m_brush.GetStipple()->GetHeight() ); + XFillRectangle( (Display*) m_display, (Window) m_window, (GC) m_textGC, xx+rr, yy, ww-dd+1, hh ); + XFillRectangle( (Display*) m_display, (Window) m_window, (GC) m_textGC, xx, yy+rr, ww, hh-dd+1 ); + XFillArc( (Display*) m_display, (Window) m_window, (GC) m_textGC, xx, yy, dd, dd, 90*64, 90*64 ); + XFillArc( (Display*) m_display, (Window) m_window, (GC) m_textGC, xx+ww-dd, yy, dd, dd, 0, 90*64 ); + XFillArc( (Display*) m_display, (Window) m_window, (GC) m_textGC, xx+ww-dd, yy+hh-dd, dd, dd, 270*64, 90*64 ); + XFillArc( (Display*) m_display, (Window) m_window, (GC) m_textGC, xx, yy+hh-dd, dd, dd, 180*64, 90*64 ); + XSetTSOrigin( (Display*) m_display, (GC) m_textGC, 0, 0); + } else + if (IS_15_PIX_HATCH(m_brush.GetStyle())) + { + XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, m_deviceOriginX % 15, m_deviceOriginY % 15 ); + XFillRectangle( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx+rr, yy, ww-dd+1, hh ); + XFillRectangle( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx, yy+rr, ww, hh-dd+1 ); + XFillArc( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx, yy, dd, dd, 90*64, 90*64 ); + XFillArc( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx+ww-dd, yy, dd, dd, 0, 90*64 ); + XFillArc( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx+ww-dd, yy+hh-dd, dd, dd, 270*64, 90*64 ); + XFillArc( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx, yy+hh-dd, dd, dd, 180*64, 90*64 ); + XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0); + } else + if (IS_16_PIX_HATCH(m_brush.GetStyle())) + { + XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, m_deviceOriginX % 16, m_deviceOriginY % 16 ); + XFillRectangle( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx+rr, yy, ww-dd+1, hh ); + XFillRectangle( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx, yy+rr, ww, hh-dd+1 ); + XFillArc( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx, yy, dd, dd, 90*64, 90*64 ); + XFillArc( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx+ww-dd, yy, dd, dd, 0, 90*64 ); + XFillArc( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx+ww-dd, yy+hh-dd, dd, dd, 270*64, 90*64 ); + XFillArc( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx, yy+hh-dd, dd, dd, 180*64, 90*64 ); + XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0); + } else + if (m_brush.GetStyle() == wxSTIPPLE) + { + XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, + m_deviceOriginX % m_brush.GetStipple()->GetWidth(), + m_deviceOriginY % m_brush.GetStipple()->GetHeight() ); + XFillRectangle( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx+rr, yy, ww-dd+1, hh ); + XFillRectangle( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx, yy+rr, ww, hh-dd+1 ); + XFillArc( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx, yy, dd, dd, 90*64, 90*64 ); + XFillArc( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx+ww-dd, yy, dd, dd, 0, 90*64 ); + XFillArc( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx+ww-dd, yy+hh-dd, dd, dd, 270*64, 90*64 ); + XFillArc( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx, yy+hh-dd, dd, dd, 180*64, 90*64 ); + XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0); + } + else + { + XFillRectangle( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx+rr, yy, ww-dd+1, hh ); + XFillRectangle( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx, yy+rr, ww, hh-dd+1 ); + XFillArc( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx, yy, dd, dd, 90*64, 90*64 ); + XFillArc( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx+ww-dd, yy, dd, dd, 0, 90*64 ); + XFillArc( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx+ww-dd, yy+hh-dd, dd, dd, 270*64, 90*64 ); + XFillArc( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx, yy+hh-dd, dd, dd, 180*64, 90*64 ); + } + } + if (m_pen.GetStyle() != wxTRANSPARENT) + { + XDrawLine( (Display*) m_display, (Window) m_window, (GC) m_penGC, xx+rr+1, yy, xx+ww-rr, yy ); + XDrawLine( (Display*) m_display, (Window) m_window, (GC) m_penGC, xx+rr+1, yy+hh, xx+ww-rr, yy+hh ); + XDrawLine( (Display*) m_display, (Window) m_window, (GC) m_penGC, xx, yy+rr+1, xx, yy+hh-rr ); + XDrawLine( (Display*) m_display, (Window) m_window, (GC) m_penGC, xx+ww, yy+rr+1, xx+ww, yy+hh-rr ); + XDrawArc( (Display*) m_display, (Window) m_window, (GC) m_penGC, xx, yy, dd, dd, 90*64, 90*64 ); + XDrawArc( (Display*) m_display, (Window) m_window, (GC) m_penGC, xx+ww-dd, yy, dd, dd, 0, 90*64 ); + XDrawArc( (Display*) m_display, (Window) m_window, (GC) m_penGC, xx+ww-dd, yy+hh-dd, dd, dd, 270*64, 90*64 ); + XDrawArc( (Display*) m_display, (Window) m_window, (GC) m_penGC, xx, yy+hh-dd, dd, dd, 180*64, 90*64 ); + } + } + + // this ignores the radius + CalcBoundingBox( x, y ); + CalcBoundingBox( x + width, y + height ); } void wxWindowDC::DoDrawEllipse( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) @@ -781,30 +932,30 @@ void wxWindowDC::DoDrawEllipse( wxCoord x, wxCoord y, wxCoord width, wxCoord hei XSetTSOrigin( (Display*) m_display, (GC) m_textGC, m_deviceOriginX % m_brush.GetStipple()->GetWidth(), m_deviceOriginY % m_brush.GetStipple()->GetHeight() ); - + XFillArc( (Display*) m_display, (Window) m_window, (GC) m_textGC, xx, yy, ww, hh, 0, 360*64 ); - + XSetTSOrigin( (Display*) m_display, (GC) m_textGC, 0, 0 ); } else if (IS_15_PIX_HATCH(m_brush.GetStyle())) { XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, m_deviceOriginX % 15, m_deviceOriginY % 15 ); - + XFillArc( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx, yy, ww, hh, 0, 360*64 ); - + XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0 ); } else if (IS_16_PIX_HATCH(m_brush.GetStyle())) { XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, m_deviceOriginX % 16, m_deviceOriginY % 16 ); - + XFillArc( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx, yy, ww, hh, 0, 360*64 ); - + XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0 ); } else if (m_brush.GetStyle() == wxSTIPPLE) @@ -812,10 +963,10 @@ void wxWindowDC::DoDrawEllipse( wxCoord x, wxCoord y, wxCoord width, wxCoord hei XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, m_deviceOriginX % m_brush.GetStipple()->GetWidth(), m_deviceOriginY % m_brush.GetStipple()->GetHeight() ); - + XFillArc( (Display*) m_display, (Window) m_window, (GC) m_brushGC, xx, yy, ww, hh, 0, 360*64 ); - + XSetTSOrigin( (Display*) m_display, (GC) m_brushGC, 0, 0 ); } else @@ -838,7 +989,7 @@ void wxWindowDC::DoDrawEllipse( wxCoord x, wxCoord y, wxCoord width, wxCoord hei void wxWindowDC::DoDrawIcon( const wxIcon &icon, wxCoord x, wxCoord y) { - DoDrawBitmap(icon, x, y, TRUE); + DoDrawBitmap(icon, x, y, true); } #if wxUSE_NANOX @@ -849,7 +1000,7 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, wxCHECK_RET( Ok(), wxT("invalid window dc") ); wxCHECK_RET( bitmap.Ok(), wxT("invalid bitmap") ); - + bool is_mono = (bitmap.GetBitmap() != NULL); /* scale/translate size and position */ @@ -880,14 +1031,14 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, wxBitmap use_bitmap; if ((w != ww) || (h != hh)) { - wxImage image( bitmap ); + wxImage image( bitmap.ConvertToImage() ); image.Rescale( ww, hh ); #if 0 if (is_mono) use_bitmap = image.ConvertToMonoBitmap(255,255,255); else #endif - use_bitmap = image.ConvertToBitmap(); + use_bitmap = image; } else { @@ -921,7 +1072,7 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, GrCopyArea(bufPixmap, gc, 0, 0, w, h, (Window) m_window, 0, 0, GR_MODE_COPY); #endif - + // Copy src to buffer using selected raster op (none selected // in DrawBitmap, so just use Gxcopy) GrCopyArea(bufPixmap, gc, 0, 0, w, h, pixmap, @@ -932,7 +1083,7 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, GrSetGCForeground(gc, BLACK); GrCopyArea(bufPixmap, gc, 0, 0, w, h, maskPixmap, 0, 0, GR_MODE_AND); - + // set unmasked area in dest to BLACK GrSetGCBackground(gc, BLACK); GrSetGCForeground(gc, WHITE); @@ -968,7 +1119,7 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, wxCHECK_RET( Ok(), wxT("invalid window dc") ); wxCHECK_RET( bitmap.Ok(), wxT("invalid bitmap") ); - + bool is_mono = (bitmap.GetBitmap() != NULL); // scale/translate size and position @@ -999,14 +1150,14 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, wxBitmap use_bitmap; if ((w != ww) || (h != hh)) { - wxImage image( bitmap ); + wxImage image( bitmap.ConvertToImage() ); image.Rescale( ww, hh ); #if 0 if (is_mono) use_bitmap = image.ConvertToMonoBitmap(255,255,255); else #endif - use_bitmap = image.ConvertToBitmap(); + use_bitmap = image; } else { @@ -1016,63 +1167,79 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, // apply mask if any 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()) + // 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) { - 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 ); + // transparent mask => call XSetStipple + XSetFillStyle( xdisplay, gc, FillStippled ); + XSetTSOrigin( xdisplay, gc, 0, 0); + 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 ); + + XFreeGC( xdisplay, gc ); + } + + if (is_mono) + { + if (new_pixmap) + XSetClipMask( (Display*) m_display, (GC) m_textGC, new_pixmap ); else - { - 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 ); - } - - if (new_mask) - XFreePixmap( (Display*) m_display, (Pixmap) new_mask ); + 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) { @@ -1102,11 +1269,11 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he of the source dc, but scales correctly on the target dc and knows about possible mask information in a memory dc. */ - wxCHECK_MSG( Ok(), FALSE, wxT("invalid window dc") ); + wxCHECK_MSG( Ok(), false, wxT("invalid window dc") ); - wxCHECK_MSG( source, FALSE, wxT("invalid source dc") ); + wxCHECK_MSG( source, false, wxT("invalid source dc") ); - if (!m_window) return FALSE; + if (!m_window) return false; // transform the source DC coords to the device ones xsrc = source->XLOG2DEV(xsrc); @@ -1115,19 +1282,19 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he wxClientDC *srcDC = (wxClientDC*)source; wxMemoryDC *memDC = (wxMemoryDC*)source; - bool use_bitmap_method = FALSE; - bool is_mono = FALSE; + bool use_bitmap_method = false; + bool is_mono = false; - // TODO: use the mask origin when drawing transparently + // TODO: use the mask origin when drawing transparently if (xsrcMask == -1 && ysrcMask == -1) { xsrcMask = xsrc; ysrcMask = ysrc; } - + if (srcDC->m_isMemDC) { - if (!memDC->m_selected.Ok()) return FALSE; + if (!memDC->m_selected.Ok()) return false; /* we use the "XCopyArea" way to copy a memory dc into y different window if the memory dc BOTH @@ -1140,15 +1307,15 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he /* we HAVE TO use the direct way for memory dcs that have mask since the XCopyArea doesn't know about masks */ - use_bitmap_method = TRUE; + use_bitmap_method = true; } else if (memDC->m_selected.GetDepth() == 1) { /* we HAVE TO use the direct way for memory dcs that are bitmaps because XCopyArea doesn't cope with different bit depths */ - is_mono = TRUE; - use_bitmap_method = TRUE; + is_mono = true; + use_bitmap_method = true; } else if ((xsrc == 0) && (ysrc == 0) && (width == memDC->m_selected.GetWidth()) && @@ -1158,11 +1325,11 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he in the memory dc is copied in which case XCopyArea wouldn't be able able to boost performace by reducing the area to be scaled */ - use_bitmap_method = TRUE; + use_bitmap_method = true; } else { - use_bitmap_method = FALSE; + use_bitmap_method = false; } } @@ -1182,7 +1349,7 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he wxRegion tmp( xx,yy,ww,hh ); tmp.Intersect( m_currentClippingRegion ); if (tmp.IsEmpty()) - return TRUE; + return true; } int old_logical_func = m_logicalFunction; @@ -1202,7 +1369,7 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he if ((bm_width != bm_ww) || (bm_height != bm_hh)) { - wxImage image( memDC->m_selected ); + wxImage image( memDC->m_selected.ConvertToImage() ); image = image.Scale( bm_ww, bm_hh ); #if 0 @@ -1210,7 +1377,7 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he use_bitmap = image.ConvertToMonoBitmap(255,255,255); else #endif - use_bitmap = image.ConvertToBitmap(); + use_bitmap = image; } else { @@ -1261,7 +1428,7 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he XSetClipMask( (Display*) m_display, (GC) m_penGC, (Pixmap) mask ); XSetClipOrigin( (Display*) m_display, (GC) m_penGC, xx, yy ); } - + if (new_mask) XFreePixmap( (Display*) m_display, (Pixmap) new_mask ); } @@ -1321,14 +1488,14 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he XSetSubwindowMode( (Display*) m_display, (GC) m_penGC, ClipByChildren ); // scale image - wxImage image( bitmap ); + wxImage image( bitmap.ConvertToImage() ); image = image.Scale( ww, hh ); // convert to bitmap - bitmap = image.ConvertToBitmap(); + bitmap = image; // draw scaled bitmap - XCopyArea( (Display*) m_display, (Window) bitmap.GetPixmap(), (Window) m_window, + XCopyArea( (Display*) m_display, (Window) bitmap.GetPixmap(), (Window) m_window, (GC) m_penGC, 0, 0, width, height, xx, yy ); } else @@ -1337,15 +1504,15 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he // copy including child window contents XSetSubwindowMode( (Display*) m_display, (GC) m_penGC, IncludeInferiors ); - XCopyArea( (Display*) m_display, (Window) srcDC->GetWindow(), (Window) m_window, + XCopyArea( (Display*) m_display, (Window) srcDC->GetWindow(), (Window) m_window, (GC) m_penGC, xsrc, ysrc, width, height, xx, yy ); XSetSubwindowMode( (Display*) m_display, (GC) m_penGC, ClipByChildren ); } } SetLogicalFunction( old_logical_func ); - - return TRUE; + + return true; } void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) @@ -1354,13 +1521,34 @@ void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) if (!m_window) return; + x = XLOG2DEV(x); + y = YLOG2DEV(y); + +#if wxUSE_UNICODE + 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 )); + + // Measure layout. + int w,h; + pango_layout_get_pixel_size(layout, &w, &h); + wxCoord width = w; + wxCoord height = h; + + // Draw layout. + x11_draw_layout( (Drawable) m_window, (GC) m_textGC, x, y, layout, m_textForegroundColour ); + + g_object_unref( G_OBJECT( layout ) ); + + CalcBoundingBox (x + width, y + height); + CalcBoundingBox (x, y); +#else XFontStruct *xfont = (XFontStruct*) m_font.GetFontStruct( m_scaleY, m_display ); wxCHECK_RET( xfont, wxT("invalid font") ); - x = XLOG2DEV(x); - y = YLOG2DEV(y); - // First draw a rectangle representing the text background, if a text // background is specified if (m_textBackgroundColour.Ok () && (m_backgroundMode != wxTRANSPARENT)) @@ -1381,6 +1569,7 @@ void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) cx = overall_return.width; cy = ascent + descent; m_textBackgroundColour.CalcPixel(m_cmap); + m_textForegroundColour.CalcPixel(m_cmap); XSetForeground ((Display*) m_display, (GC) m_textGC, m_textBackgroundColour.GetPixel()); XFillRectangle( (Display*) m_display, (Window) m_window, (GC) m_textGC, x, y, cx, cy ); @@ -1390,11 +1579,13 @@ void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) 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() ); + XDrawString( (Display*) m_display, (Window) m_window, + (GC) m_textGC, x, y + XFontStructGetAscent(xfont), text.c_str(), text.length() ); } #if 0 @@ -1407,10 +1598,11 @@ void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) width = wxCoord(width / m_scaleX); height = wxCoord(height / m_scaleY); - + CalcBoundingBox (x + width, y + height); CalcBoundingBox (x, y); #endif +#endif } void wxWindowDC::DoDrawRotatedText( const wxString &text, wxCoord x, wxCoord y, double angle ) @@ -1422,21 +1614,54 @@ void wxWindowDC::DoGetTextExtent( const wxString &string, wxCoord *width, wxCoor wxCoord *descent, wxCoord *externalLeading, wxFont *font ) const { - wxCHECK_RET( Ok(), "invalid dc" ); + wxCHECK_RET( Ok(), wxT("invalid dc") ); + + if (string.empty()) + { + if (width) (*width) = 0; + if (height) (*height) = 0; + return; + } + +#if wxUSE_UNICODE + PangoLayout *layout = pango_layout_new( m_context ); + if (font) + pango_layout_set_font_description( layout, font->GetNativeFontInfo()->description ); + 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 )); + + // Measure text. + int w,h; + pango_layout_get_pixel_size(layout, &w, &h); + + if (width) (*width) = (wxCoord) w; + if (height) (*height) = (wxCoord) h; + if (descent) + { + // Do something about metrics here. TODO. + (*descent) = 0; + } + if (externalLeading) (*externalLeading) = 0; // ?? + + g_object_unref( G_OBJECT( layout ) ); +#else wxFont fontToUse = m_font; if (font) fontToUse = *font; - wxCHECK_RET( fontToUse.Ok(), "invalid font" ); + wxCHECK_RET( fontToUse.Ok(), wxT("invalid font") ); XFontStruct *xfont = (XFontStruct*) fontToUse.GetFontStruct( m_scaleY, m_display ); wxCHECK_RET( xfont, wxT("invalid font") ); - + int direction, ascent, descent2; XCharStruct overall; - XTextExtents( xfont, (char*) string.c_str(), string.Len(), &direction, + XTextExtents( xfont, (char*) string.c_str(), string.length(), &direction, &ascent, &descent2, &overall); if (width) @@ -1447,13 +1672,29 @@ void wxWindowDC::DoGetTextExtent( const wxString &string, wxCoord *width, wxCoor *descent = (wxCoord)(descent2 / m_scaleY ); if (externalLeading) *externalLeading = 0; // ?? +#endif } wxCoord wxWindowDC::GetCharWidth() const { - wxCHECK_MSG( Ok(), 0, "invalid dc" ); - - wxCHECK_MSG( m_font.Ok(), 0, "invalid font" ); + wxCHECK_MSG( Ok(), 0, wxT("invalid dc") ); + +#if wxUSE_UNICODE + PangoLayout *layout = pango_layout_new( m_context ); + + 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; + pango_layout_get_pixel_size(layout, &w, &h); + g_object_unref( G_OBJECT( layout ) ); + + return w; +#else + wxCHECK_MSG( m_font.Ok(), 0, wxT("invalid font") ); XFontStruct *xfont = (XFontStruct*) m_font.GetFontStruct( m_scaleY, m_display ); @@ -1461,17 +1702,33 @@ wxCoord wxWindowDC::GetCharWidth() const int direction, ascent, descent; XCharStruct overall; - + XTextExtents( xfont, "H", 1, &direction, &ascent, &descent, &overall ); - + return (wxCoord)(overall.width / m_scaleX); +#endif } wxCoord wxWindowDC::GetCharHeight() const { - wxCHECK_MSG( Ok(), 0, "invalid dc" ); - - wxCHECK_MSG( m_font.Ok(), 0, "invalid font" ); + wxCHECK_MSG( Ok(), 0, wxT("invalid dc") ); + +#if wxUSE_UNICODE + PangoLayout *layout = pango_layout_new( m_context ); + + 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; + pango_layout_get_pixel_size(layout, &w, &h); + g_object_unref( G_OBJECT( layout ) ); + + return h; +#else + wxCHECK_MSG( m_font.Ok(), 0, wxT("invalid font") ); XFontStruct *xfont = (XFontStruct*) m_font.GetFontStruct( m_scaleY, m_display ); @@ -1479,10 +1736,11 @@ wxCoord wxWindowDC::GetCharHeight() const int direction, ascent, descent; XCharStruct overall; - + XTextExtents( xfont, "H", 1, &direction, &ascent, &descent, &overall ); - + return (wxCoord)((ascent+descent) / m_scaleY); +#endif } void wxWindowDC::Clear() @@ -1517,9 +1775,15 @@ void wxWindowDC::Clear() void wxWindowDC::SetFont( const wxFont &font ) { - wxCHECK_RET( Ok(), "invalid dc" ); + wxCHECK_RET( Ok(), wxT("invalid dc") ); m_font = font; + + return; + +#if wxUSE_UNICODE + m_fontdesc = font.GetNativeFontInfo()->description; +#endif } void wxWindowDC::SetPen( const wxPen &pen ) @@ -1663,7 +1927,7 @@ void wxWindowDC::SetBrush( const wxBrush &brush ) m_brush.GetColour().CalcPixel( m_cmap ); XSetForeground( (Display*) m_display, (GC) m_brushGC, m_brush.GetColour().GetPixel() ); - + XSetFillStyle( (Display*) m_display, (GC) m_brushGC, FillSolid ); if ((m_brush.GetStyle() == wxSTIPPLE) && (m_brush.GetStipple()->Ok())) @@ -1686,7 +1950,7 @@ void wxWindowDC::SetBrush( const wxBrush &brush ) XSetStipple( (Display*) m_display, (GC) m_textGC, (Pixmap) m_brush.GetStipple()->GetMask()->GetBitmap() ); } - if (IS_HATCH(m_brush.GetStyle())) + if (m_brush.IsHatch()) { XSetFillStyle( (Display*) m_display, (GC) m_brushGC, FillStippled ); int num = m_brush.GetStyle() - wxBDIAGONAL_HATCH; @@ -1731,7 +1995,7 @@ void wxWindowDC::SetBackground( const wxBrush &brush ) } } - if (IS_HATCH(m_backgroundBrush.GetStyle())) + if (m_backgroundBrush.IsHatch()) { XSetFillStyle( (Display*) m_display, (GC) m_bgGC, FillStippled ); int num = m_backgroundBrush.GetStyle() - wxBDIAGONAL_HATCH; @@ -1741,7 +2005,7 @@ void wxWindowDC::SetBackground( const wxBrush &brush ) void wxWindowDC::SetLogicalFunction( int function ) { - wxCHECK_RET( Ok(), "invalid dc" ); + wxCHECK_RET( Ok(), wxT("invalid dc") ); int x_function; @@ -1751,7 +2015,7 @@ void wxWindowDC::SetLogicalFunction( int function ) // VZ: shouldn't this be a CHECK? if (!m_window) return; - + switch (function) { case wxCLEAR: @@ -1812,7 +2076,7 @@ void wxWindowDC::SetLogicalFunction( int function ) // operations (i.e. DrawText/DrawRotatedText). // True, but mono-bitmaps use the m_textGC and they use ROPs as well. XSetFunction( (Display*) m_display, (GC) m_textGC, x_function ); - + m_logicalFunction = function; } @@ -2040,16 +2304,17 @@ wxClientDC::wxClientDC( wxWindow *window ) : wxWindowDC( window ) { wxCHECK_RET( window, _T("NULL window in wxClientDC::wxClientDC") ); - - m_window = (WXWindow*) window->GetClientWindow(); - -#if wxUSE_TWO_WINDOWS -#else - wxPoint ptOrigin = window->GetClientAreaOrigin(); - SetDeviceOrigin(ptOrigin.x, ptOrigin.y); - wxSize size = window->GetClientSize(); - SetClippingRegion(wxPoint(0, 0), size); -#endif // __WXUNIVERSAL__ + + m_window = (WXWindow*) window->GetClientAreaWindow(); + + // Adjust the client area when the wxWindow is not using 2 X11 windows. + if (m_window == (WXWindow*) window->GetMainWindow()) + { + wxPoint ptOrigin = window->GetClientAreaOrigin(); + SetDeviceOrigin(ptOrigin.x, ptOrigin.y); + wxSize size = window->GetClientSize(); + SetClippingRegion(wxPoint(0, 0), size); + } } void wxClientDC::DoGetSize(int *width, int *height) const @@ -2093,8 +2358,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) @@ -2102,13 +2374,3 @@ private: IMPLEMENT_DYNAMIC_CLASS(wxDCModule, wxModule) -bool wxDCModule::OnInit() -{ - wxInitGCPool(); - return TRUE; -} - -void wxDCModule::OnExit() -{ - wxCleanUpGCPool(); -}