From 3cd0b8c5b5a320bba065c4da306be3687d144157 Mon Sep 17 00:00:00 2001 From: Robert Roebling Date: Mon, 11 Feb 2002 20:41:24 +0000 Subject: [PATCH] wxX11: Updated wxColour for handling Colormaps and ref couting. Updated wxClientDC et al. for conforming to wxGTK. Many tricky parts, particularly the bitmap drawing and blitting is still missing. Any sample crashes now for some reason with an X error. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@14136 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/defs.h | 1 + include/wx/x11/colour.h | 109 +- include/wx/x11/dc.h | 28 +- include/wx/x11/dcclient.h | 180 ++- include/wx/x11/dcmemory.h | 15 +- include/wx/x11/dcscreen.h | 39 +- include/wx/x11/window.h | 3 + src/gtk/dcclient.cpp | 4 +- src/gtk1/dcclient.cpp | 4 +- src/x11/bitmap.cpp | 2 + src/x11/colour.cpp | 366 ++--- src/x11/dc.cpp | 54 +- src/x11/dcclient.cpp | 2861 ++++++++++++++++++------------------- src/x11/dcmemory.cpp | 152 +- src/x11/dcscreen.cpp | 151 +- src/x11/window.cpp | 55 +- 16 files changed, 1902 insertions(+), 2122 deletions(-) diff --git a/include/wx/defs.h b/include/wx/defs.h index 1182724f77..0f78049a5b 100644 --- a/include/wx/defs.h +++ b/include/wx/defs.h @@ -1860,6 +1860,7 @@ typedef void* WXWindow; typedef void* WXWidget; typedef void* WXAppContext; typedef void* WXColormap; +typedef void* WXColor; typedef void WXDisplay; typedef void WXEvent; typedef void* WXCursor; diff --git a/include/wx/x11/colour.h b/include/wx/x11/colour.h index 0a3409aa7b..884b849c57 100644 --- a/include/wx/x11/colour.h +++ b/include/wx/x11/colour.h @@ -1,11 +1,11 @@ ///////////////////////////////////////////////////////////////////////////// // Name: colour.h // Purpose: wxColour class -// Author: Julian Smart +// Author: Julian Smart, Robert Roebling // Modified by: // Created: 17/09/98 // RCS-ID: $Id$ -// Copyright: (c) Julian Smart +// Copyright: (c) Julian Smart, Robert Roebling // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -16,77 +16,82 @@ #pragma interface "colour.h" #endif +#include "wx/defs.h" #include "wx/object.h" #include "wx/string.h" +#include "wx/gdiobj.h" +#include "wx/palette.h" -// Colour -class WXDLLEXPORT wxColour : public wxObject +//----------------------------------------------------------------------------- +// classes +//----------------------------------------------------------------------------- + +class wxDC; +class wxPaintDC; +class wxBitmap; +class wxWindow; + +class wxColour; + +//----------------------------------------------------------------------------- +// wxColour +//----------------------------------------------------------------------------- + +class wxColour: public wxGDIObject { - DECLARE_DYNAMIC_CLASS(wxColour) public: - // ctors - // default - wxColour(); - // from RGB + wxColour() { } + + // Construct from RGB wxColour( unsigned char red, unsigned char green, unsigned char blue ); wxColour( unsigned long colRGB ) { Set(colRGB); } - - // implicit conversion from the colour name + + // Implicit conversion from the colour name wxColour( const wxString &colourName ) { InitFromName(colourName); } wxColour( const char *colourName ) { InitFromName(colourName); } - - // copy ctors and assignment operators - wxColour( const wxColour& col ); - wxColour& operator = ( const wxColour& col ); - - // dtor + + wxColour( const wxColour& col ) { Ref(col); } + wxColour& operator = ( const wxColour& col ) { Ref(col); return *this; } + ~wxColour(); - - // Set() functions + + bool Ok() const { return m_refData != NULL; } + + bool operator == ( const wxColour& col ) const; + bool operator != ( const wxColour& col ) const { return !(*this == col); } + void Set( unsigned char red, unsigned char green, unsigned char blue ); void Set( unsigned long colRGB ) { - // we don't need to know sizeof(long) here because we assume that the three + // We don't need to know sizeof(long) here because we assume that the three // least significant bytes contain the R, G and B values Set((unsigned char)colRGB, (unsigned char)(colRGB >> 8), (unsigned char)(colRGB >> 16)); } + + unsigned char Red() const; + unsigned char Green() const; + unsigned char Blue() const; + + // Implementation part - // accessors - bool Ok() const {return m_isInit; } - unsigned char Red() const { return m_red; } - unsigned char Green() const { return m_green; } - unsigned char Blue() const { return m_blue; } - - int GetPixel() const { return m_pixel; }; - void SetPixel(int pixel) { m_pixel = pixel; m_isInit = TRUE; }; - - inline bool operator == (const wxColour& colour) const { return (m_red == colour.m_red && m_green == colour.m_green && m_blue == colour.m_blue); } - - inline bool operator != (const wxColour& colour) const { return (!(m_red == colour.m_red && m_green == colour.m_green && m_blue == colour.m_blue)); } - - // Allocate a colour, or nearest colour, using the given display. - // If realloc is TRUE, ignore the existing pixel, otherwise just return - // the existing one. - // Returns the allocated pixel. - - // TODO: can this handle mono displays? If not, we should have an extra - // flag to specify whether this should be black or white by default. - - int AllocColour(WXDisplay* display, bool realloc = FALSE); - - void InitFromName(const wxString& col); + void CalcPixel( WXColormap cmap ); + unsigned long GetPixel() const; + WXColor *GetColor() const; + +protected: + // ref counting code + virtual wxObjectRefData *CreateRefData() const; + virtual wxObjectRefData *CloneRefData(const wxObjectRefData *data) const; + // Helper functions + void InitFromName(const wxString& colourName); + private: - bool m_isInit; - unsigned char m_red; - unsigned char m_blue; - unsigned char m_green; - -public: - int m_pixel; + DECLARE_DYNAMIC_CLASS(wxColour) }; #endif -// _WX_COLOUR_H_ + +// _WX_COLOUR_H_ \ No newline at end of file diff --git a/include/wx/x11/dc.h b/include/wx/x11/dc.h index f456f8d57f..f4e58fb5d9 100644 --- a/include/wx/x11/dc.h +++ b/include/wx/x11/dc.h @@ -43,8 +43,6 @@ class WXDLLEXPORT wxDC : public wxDCBase { - DECLARE_DYNAMIC_CLASS(wxDC) - public: wxDC(); ~wxDC() { } @@ -64,13 +62,8 @@ public: virtual void SetAxisOrientation(bool xLeftRight, bool yBottomUp); protected: - virtual void DoDrawIcon(const wxIcon& icon, wxCoord x, wxCoord y); - virtual void DoDrawBitmap(const wxBitmap &bmp, wxCoord x, wxCoord y, - bool useMask = FALSE); - virtual void DoSetClippingRegion(wxCoord x, wxCoord y, wxCoord width, wxCoord height); - virtual void DoGetSize(int *width, int *height) const; virtual void DoGetSizeMM(int* width, int* height) const; public: @@ -114,15 +107,6 @@ public: else return (wxCoord)((double)(new_x) * m_scaleX - 0.5) * m_signX + m_deviceOriginX; } - // Without device translation, for backing pixmap purposes - wxCoord XLOG2DEV_2(wxCoord x) const - { - wxCoord new_x = x - m_logicalOriginX; - if (new_x > 0) - return (wxCoord)((double)(new_x) * m_scaleX + 0.5) * m_signX; - else - return (wxCoord)((double)(new_x) * m_scaleX - 0.5) * m_signX; - } wxCoord XLOG2DEVREL(wxCoord x) const { if (x > 0) @@ -138,15 +122,6 @@ public: else return (wxCoord)((double)(new_y) * m_scaleY - 0.5) * m_signY + m_deviceOriginY; } - // Without device translation, for backing pixmap purposes - wxCoord YLOG2DEV_2(wxCoord y) const - { - wxCoord new_y = y - m_logicalOriginY; - if (new_y > 0) - return (wxCoord)((double)(new_y) * m_scaleY + 0.5) * m_signY; - else - return (wxCoord)((double)(new_y) * m_scaleY - 0.5) * m_signY; - } wxCoord YLOG2DEVREL(wxCoord y) const { if (y > 0) @@ -162,6 +137,9 @@ public: // recompute scale? bool m_needComputeScaleX, m_needComputeScaleY; + +private: + DECLARE_ABSTRACT_CLASS(wxDC) }; #endif diff --git a/include/wx/x11/dcclient.h b/include/wx/x11/dcclient.h index ab3fc7a215..bfbce74123 100644 --- a/include/wx/x11/dcclient.h +++ b/include/wx/x11/dcclient.h @@ -17,87 +17,45 @@ #endif #include "wx/dc.h" +#include "wx/region.h" // ----------------------------------------------------------------------------- // fwd declarations // ----------------------------------------------------------------------------- -class WXDLLEXPORT wxWindowDC; -class WXDLLEXPORT wxWindow; +class wxWindow; -// Under Windows, wxClientDC, wxPaintDC and wxWindowDC are implemented -// differently. On many platforms, however, they will be the same. +class wxWindowDC; +class wxPaintDC; +class wxClientDC; //----------------------------------------------------------------------------- // wxWindowDC //----------------------------------------------------------------------------- -class WXDLLEXPORT wxWindowDC : public wxDC +class wxWindowDC : public wxDC { - DECLARE_DYNAMIC_CLASS(wxWindowDC) - public: wxWindowDC(); wxWindowDC( wxWindow *win ); ~wxWindowDC(); - // TODO this function is Motif-only for now - should it go into base class? - void Clear(const wxRect& rect); - - // implement base class pure virtuals - // ---------------------------------- - - virtual void Clear(); - - virtual void SetFont(const wxFont& font); - virtual void SetPen(const wxPen& pen); - virtual void SetBrush(const wxBrush& brush); - virtual void SetBackground(const wxBrush& brush); - virtual void SetBackgroundMode(int mode); - virtual void SetPalette(const wxPalette& palette); - virtual void SetLogicalFunction( int function ); - - virtual void SetTextForeground(const wxColour& colour); - virtual void SetTextBackground(const wxColour& colour); - - virtual wxCoord GetCharHeight() const; - virtual wxCoord GetCharWidth() const; - virtual void DoGetTextExtent(const wxString& string, - wxCoord *x, wxCoord *y, - wxCoord *descent = NULL, - wxCoord *externalLeading = NULL, - wxFont *theFont = NULL) const; - - virtual bool CanDrawBitmap() const; - virtual bool CanGetTextExtent() const; - - virtual int GetDepth() const; - virtual wxSize GetPPI() const; - - virtual void DestroyClippingRegion(); - - // Helper function for setting clipping - void SetDCClipping(); - - // implementation from now on - // -------------------------- - - WXGC GetGC() const { return m_gc; } - WXGC GetBackingGC() const { return m_gcBacking; } - WXDisplay* GetDisplay() const { return m_display; } - bool GetAutoSetting() const { return m_autoSetting; } - void SetAutoSetting(bool flag) { m_autoSetting = flag; } - + virtual bool CanDrawBitmap() const { return TRUE; } + virtual bool CanGetTextExtent() const { return TRUE; } + protected: - virtual void DoFloodFill(wxCoord x, wxCoord y, const wxColour& col, - int style = wxFLOOD_SURFACE); - - virtual bool DoGetPixel(wxCoord x, wxCoord y, wxColour *col) const; + virtual void DoGetSize(int *width, int *height) const; + virtual void DoFloodFill( wxCoord x, wxCoord y, const wxColour& col, int style = wxFLOOD_SURFACE ); + virtual bool DoGetPixel( wxCoord x, wxCoord y, wxColour *col ) const; virtual void DoDrawPoint(wxCoord x, wxCoord y); virtual void DoDrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2); + virtual void DoDrawIcon( const wxIcon &icon, wxCoord x, wxCoord y ); + virtual void DoDrawBitmap( const wxBitmap &bitmap, wxCoord x, wxCoord y, + bool useMask = FALSE ); + virtual void DoDrawArc(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, wxCoord xc, wxCoord yc); @@ -128,49 +86,89 @@ protected: virtual void DoDrawPolygon(int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset, int fillStyle = wxODDEVEN_RULE); + + +public: + virtual void Clear(); + + virtual void SetFont(const wxFont& font); + virtual void SetPen(const wxPen& pen); + virtual void SetBrush(const wxBrush& brush); + virtual void SetBackground(const wxBrush& brush); + virtual void SetBackgroundMode(int mode); + virtual void SetPalette(const wxPalette& palette); + virtual void SetLogicalFunction( int function ); + + virtual void SetTextForeground(const wxColour& colour); + virtual void SetTextBackground(const wxColour& colour); + + virtual wxCoord GetCharHeight() const; + virtual wxCoord GetCharWidth() const; + virtual void DoGetTextExtent(const wxString& string, + wxCoord *x, wxCoord *y, + wxCoord *descent = NULL, + wxCoord *externalLeading = NULL, + wxFont *theFont = NULL) const; - WXGC m_gc; - WXGC m_gcBacking; - WXDisplay* m_display; - wxWindow* m_window; - WXRegion m_currentRegion; // Current clipping region (incl. paint clip region) - WXRegion m_userRegion; // User-defined clipping region - WXPixmap m_pixmap; // Pixmap for drawing on + virtual int GetDepth() const; + virtual wxSize GetPPI() const; - // Not sure if we'll need all of these - int m_backgroundPixel; - wxColour m_currentColour; - // int m_currentBkMode; - int m_currentPenWidth ; - int m_currentPenJoin ; - int m_currentPenCap ; - int m_currentPenDashCount ; - wxX11Dash* m_currentPenDash ; - wxBitmap m_currentStipple ; - int m_currentStyle ; - int m_currentFill ; - int m_autoSetting ; // See comment in dcclient.cpp - WXFont m_oldFont; + virtual void DestroyClippingRegion(); + +protected: + // implementation + // -------------- + + WXDisplay *m_display; + WXWindow m_window; + WXGC m_penGC; + WXGC m_brushGC; + WXGC m_textGC; + WXGC m_bgGC; + WXColormap m_cmap; + bool m_isMemDC; + bool m_isScreenDC; + wxWindow *m_owner; + wxRegion m_currentClippingRegion; + wxRegion m_paintClippingRegion; + + void SetUpDC(); + void Destroy(); + void ComputeScaleAndOrigin(); + +private: + DECLARE_DYNAMIC_CLASS(wxWindowDC) }; -class WXDLLEXPORT wxPaintDC: public wxWindowDC +//----------------------------------------------------------------------------- +// wxClientDC +//----------------------------------------------------------------------------- + +class wxClientDC : public wxWindowDC { - DECLARE_DYNAMIC_CLASS(wxPaintDC) - public: - wxPaintDC() { } - wxPaintDC(wxWindow* win); - - ~wxPaintDC(); + wxClientDC() { } + wxClientDC( wxWindow *win ); + +protected: + virtual void DoGetSize(int *width, int *height) const; + +private: + DECLARE_DYNAMIC_CLASS(wxClientDC) }; -class WXDLLEXPORT wxClientDC: public wxWindowDC +//----------------------------------------------------------------------------- +// wxPaintDC +//----------------------------------------------------------------------------- + +class wxPaintDC : public wxClientDC { - DECLARE_DYNAMIC_CLASS(wxClientDC) - public: - wxClientDC() { } - wxClientDC(wxWindow* win) : wxWindowDC(win) { } + wxPaintDC() { } + wxPaintDC( wxWindow *win ); + +private: + DECLARE_DYNAMIC_CLASS(wxPaintDC) }; #endif diff --git a/include/wx/x11/dcmemory.h b/include/wx/x11/dcmemory.h index 5d85ded03e..0e49834acf 100644 --- a/include/wx/x11/dcmemory.h +++ b/include/wx/x11/dcmemory.h @@ -20,23 +20,18 @@ class wxMemoryDC : public wxWindowDC { - DECLARE_DYNAMIC_CLASS(wxMemoryDC) - public: wxMemoryDC(); wxMemoryDC( wxDC *dc ); // Create compatible DC ~wxMemoryDC(); - virtual void SelectObject( const wxBitmap& bitmap ); - void DoGetSize( int *width, int *height ) const; - - wxBitmap& GetBitmap() const { return (wxBitmap&) m_bitmap; } - + + // implementation + wxBitmap m_selected; + private: - friend class wxPaintDC; - - wxBitmap m_bitmap; + DECLARE_DYNAMIC_CLASS(wxMemoryDC) }; #endif diff --git a/include/wx/x11/dcscreen.h b/include/wx/x11/dcscreen.h index 27cf673db2..c1f9751d4a 100644 --- a/include/wx/x11/dcscreen.h +++ b/include/wx/x11/dcscreen.h @@ -18,31 +18,34 @@ #include "wx/dcclient.h" -class WXDLLEXPORT wxScreenDC: public wxWindowDC +//----------------------------------------------------------------------------- +// wxScreenDC +//----------------------------------------------------------------------------- + +class wxScreenDC : public wxPaintDC { - DECLARE_DYNAMIC_CLASS(wxScreenDC) - public: - // Create a DC representing the whole screen wxScreenDC(); - ~wxScreenDC(); - - // Compatibility with X's requirements for - // drawing on top of all windows - static bool StartDrawingOnTop(wxWindow* window); - static bool StartDrawingOnTop(wxRect* rect = NULL); + virtual ~wxScreenDC(); + + static bool StartDrawingOnTop( wxWindow *window ); + static bool StartDrawingOnTop( wxRect *rect = (wxRect *) NULL ); static bool EndDrawingOnTop(); - + + // implementation + + static WXWindow *sm_overlayWindow; + static int sm_overlayWindowX; + static int sm_overlayWindowY; + +protected: + virtual void DoGetSize(int *width, int *height) const; + private: - static WXWindow sm_overlayWindow; - - // If we have started transparent drawing at a non-(0,0) point - // then we will have to adjust the device origin in the - // constructor. - static int sm_overlayWindowX; - static int sm_overlayWindowY; + DECLARE_DYNAMIC_CLASS(wxScreenDC) }; + #endif // _WX_DCSCREEN_H_ diff --git a/include/wx/x11/window.h b/include/wx/x11/window.h index 4a4b780bef..a92d8c0741 100644 --- a/include/wx/x11/window.h +++ b/include/wx/x11/window.h @@ -123,6 +123,9 @@ public: // Generates paint events void X11SendPaintEvents(); + // Clip to paint region? + bool GetClipPaintRegion() { return m_clipPaintRegion; } + // sets the fore/background colour for the given widget static void DoChangeForegroundColour(WXWindow widget, wxColour& foregroundColour); static void DoChangeBackgroundColour(WXWindow widget, wxColour& backgroundColour, bool changeArmColour = FALSE); diff --git a/src/gtk/dcclient.cpp b/src/gtk/dcclient.cpp index 0f66d18b6d..51f831c216 100644 --- a/src/gtk/dcclient.cpp +++ b/src/gtk/dcclient.cpp @@ -246,6 +246,8 @@ wxWindowDC::wxWindowDC() wxWindowDC::wxWindowDC( wxWindow *window ) { + wxASSERT_MSG( window, wxT("DC needs a window") ); + m_penGC = (GdkGC *) NULL; m_brushGC = (GdkGC *) NULL; m_textGC = (GdkGC *) NULL; @@ -256,8 +258,6 @@ wxWindowDC::wxWindowDC( wxWindow *window ) m_isScreenDC = FALSE; m_font = window->GetFont(); - wxASSERT_MSG( window, wxT("DC needs a window") ); - GtkWidget *widget = window->m_wxwindow; // some controls don't have m_wxwindow - like wxStaticBox, but the user diff --git a/src/gtk1/dcclient.cpp b/src/gtk1/dcclient.cpp index 0f66d18b6d..51f831c216 100644 --- a/src/gtk1/dcclient.cpp +++ b/src/gtk1/dcclient.cpp @@ -246,6 +246,8 @@ wxWindowDC::wxWindowDC() wxWindowDC::wxWindowDC( wxWindow *window ) { + wxASSERT_MSG( window, wxT("DC needs a window") ); + m_penGC = (GdkGC *) NULL; m_brushGC = (GdkGC *) NULL; m_textGC = (GdkGC *) NULL; @@ -256,8 +258,6 @@ wxWindowDC::wxWindowDC( wxWindow *window ) m_isScreenDC = FALSE; m_font = window->GetFont(); - wxASSERT_MSG( window, wxT("DC needs a window") ); - GtkWidget *widget = window->m_wxwindow; // some controls don't have m_wxwindow - like wxStaticBox, but the user diff --git a/src/x11/bitmap.cpp b/src/x11/bitmap.cpp index 794b7df0d8..9a4f71feb1 100644 --- a/src/x11/bitmap.cpp +++ b/src/x11/bitmap.cpp @@ -531,11 +531,13 @@ wxBitmap wxCreateMaskedBitmap(const wxBitmap& bitmap, wxColour& colour) srcDC.SelectObject(bitmap); destDC.SelectObject(newBitmap); +#if 0 wxBrush brush(colour, wxSOLID); destDC.SetOptimization(FALSE); destDC.SetBackground(brush); destDC.Clear(); destDC.Blit(0, 0, bitmap.GetWidth(), bitmap.GetHeight(), & srcDC, 0, 0, wxCOPY, TRUE); +#endif return newBitmap; } diff --git a/src/x11/colour.cpp b/src/x11/colour.cpp index 37601ac3cf..347c6df140 100644 --- a/src/x11/colour.cpp +++ b/src/x11/colour.cpp @@ -1,214 +1,254 @@ ///////////////////////////////////////////////////////////////////////////// // Name: colour.cpp // Purpose: wxColour class -// Author: Julian Smart +// Author: Julian Smart, Robert Roebling // Modified by: // Created: 17/09/98 // RCS-ID: $Id$ -// Copyright: (c) Julian Smart +// Copyright: (c) Julian Smart, Robert Roebling // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -//// TODO: make wxColour a ref-counted object, -//// so pixel values get shared. #ifdef __GNUG__ #pragma implementation "colour.h" #endif #include "wx/gdicmn.h" -#include "wx/colour.h" -#include "wx/app.h" - -#ifdef __VMS__ -#pragma message disable nosimpint -#endif -#include -#ifdef __VMS__ -#pragma message enable nosimpint -#endif #include "wx/x11/private.h" -IMPLEMENT_DYNAMIC_CLASS(wxColour, wxObject) +//----------------------------------------------------------------------------- +// wxColour +//----------------------------------------------------------------------------- -// Colour - -wxColour::wxColour () +class wxColourRefData: public wxObjectRefData { - m_isInit = FALSE; - m_red = m_blue = m_green = 0; - m_pixel = -1; -} +public: + wxColourRefData() + { + m_color.red = 0; + m_color.green = 0; + m_color.blue = 0; + m_color.pixel = 0; + m_colormap = (WXColormap *) NULL; + m_hasPixel = FALSE; + } + + ~wxColourRefData() + { + FreeColour(); + } -wxColour::wxColour (unsigned char r, unsigned char g, unsigned char b) + bool operator == (const wxColourRefData& data) const + { + return (m_colormap == data.m_colormap && + m_hasPixel == data.m_hasPixel && + m_color.red == data.m_color.red && + m_color.green == data.m_color.green && + m_color.blue == data.m_color.blue && + m_color.pixel == data.m_color.pixel); + } + + void FreeColour(); + void AllocColour( WXColormap cmap ); + + XColor m_color; + WXColormap m_colormap; + bool m_hasPixel; + + friend class wxColour; + + // reference counter for systems with <= 8-Bit display + static unsigned short colMapAllocCounter[ 256 ]; +}; + +unsigned short wxColourRefData::colMapAllocCounter[ 256 ] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +void wxColourRefData::FreeColour() { - m_red = r; - m_green = g; - m_blue = b; - m_isInit = TRUE; - m_pixel = -1; + if (m_colormap) + { + Colormap cm = (Colormap)m_colormap; + +#if 0 + GdkColormapPrivate *private_colormap = (GdkColormapPrivate*) m_colormap; + if ((private_colormap->visual->type == GDK_VISUAL_GRAYSCALE) || + (private_colormap->visual->type == GDK_VISUAL_PSEUDO_COLOR)) + { + int idx = m_color.pixel; + colMapAllocCounter[ idx ] = colMapAllocCounter[ idx ] - 1; + + if (colMapAllocCounter[ idx ] == 0) + gdk_colormap_free_colors( m_colormap, &m_color, 1 ); + } +#endif + } } -wxColour::wxColour (const wxColour& col) +void wxColourRefData::AllocColour( WXColormap cmap ) { - m_red = col.m_red; - m_green = col.m_green; - m_blue = col.m_blue; - m_isInit = col.m_isInit; - m_pixel = col.m_pixel; + if (m_hasPixel && (m_colormap == cmap)) + return; + + FreeColour(); + +#if 0 + GdkColormapPrivate *private_colormap = (GdkColormapPrivate*) cmap; + if ((private_colormap->visual->type == GDK_VISUAL_GRAYSCALE) || + (private_colormap->visual->type == GDK_VISUAL_PSEUDO_COLOR)) + { + m_hasPixel = gdk_colormap_alloc_color( cmap, &m_color, FALSE, TRUE ); + int idx = m_color.pixel; + colMapAllocCounter[ idx ] = colMapAllocCounter[ idx ] + 1; + } + else +#endif + { + m_hasPixel = XAllocColor( wxGlobalDisplay(), (Colormap) cmap, &m_color ); + } + m_colormap = cmap; } -wxColour& wxColour::operator =(const wxColour& col) +//----------------------------------------------------------------------------- + +#define M_COLDATA ((wxColourRefData *)m_refData) + +#define SHIFT (8*(sizeof(short int)-sizeof(char))) + +IMPLEMENT_DYNAMIC_CLASS(wxColour,wxGDIObject) + +wxColour::wxColour( unsigned char red, unsigned char green, unsigned char blue ) { - m_red = col.m_red; - m_green = col.m_green; - m_blue = col.m_blue; - m_isInit = col.m_isInit; - m_pixel = col.m_pixel; - return *this; + m_refData = new wxColourRefData(); + M_COLDATA->m_color.red = ((unsigned short)red) << SHIFT; + M_COLDATA->m_color.green = ((unsigned short)green) << SHIFT; + M_COLDATA->m_color.blue = ((unsigned short)blue) << SHIFT; + M_COLDATA->m_color.pixel = 0; } -void wxColour::InitFromName(const wxString& col) +void wxColour::InitFromName( const wxString &colourName ) { - wxColour *the_colour = wxTheColourDatabase->FindColour (col); - if (the_colour) + wxNode *node = (wxNode *) NULL; + if ( (wxTheColourDatabase) && (node = wxTheColourDatabase->Find(colourName)) ) { - m_red = the_colour->Red (); - m_green = the_colour->Green (); - m_blue = the_colour->Blue (); - m_pixel = the_colour->m_pixel; - m_isInit = TRUE; + wxColour *col = (wxColour*)node->Data(); + UnRef(); + if (col) Ref( *col ); } else { - m_red = 0; - m_green = 0; - m_blue = 0; - m_isInit = FALSE; + m_refData = new wxColourRefData(); + if (!XParseColor( wxGlobalDisplay(), (Colormap) M_COLDATA->m_colormap, colourName.mb_str(), &M_COLDATA->m_color )) + { + // VZ: asserts are good in general but this one is triggered by + // calling wxColourDatabase::FindColour() with an + // unrecognized colour name and this can't be avoided from the + // user code, so don't give it here + // + // a better solution would be to changed code in FindColour() + + //wxFAIL_MSG( wxT("wxColour: couldn't find colour") ); + + delete m_refData; + m_refData = (wxObjectRefData *) NULL; + } } } -wxColour::~wxColour () +wxColour::~wxColour() { } -void wxColour::Set (unsigned char r, unsigned char g, unsigned char b) +bool wxColour::operator == ( const wxColour& col ) const { - m_red = r; - m_green = g; - m_blue = b; - m_isInit = TRUE; - m_pixel = -1; + if (m_refData == col.m_refData) return TRUE; + + if (!m_refData || !col.m_refData) return FALSE; + + XColor *own = &(((wxColourRefData*)m_refData)->m_color); + XColor *other = &(((wxColourRefData*)col.m_refData)->m_color); + if (own->red != other->red) return FALSE; + if (own->blue != other->blue) return FALSE; + if (own->green != other->green) return FALSE; + + return TRUE; } -// Allocate a colour, or nearest colour, using the given display. -// If realloc is TRUE, ignore the existing pixel, otherwise just return -// the existing one. -// Returns the old or allocated pixel. +wxObjectRefData *wxColour::CreateRefData() const +{ + return new wxColourRefData; +} -// TODO: can this handle mono displays? If not, we should have an extra -// flag to specify whether this should be black or white by default. +wxObjectRefData *wxColour::CloneRefData(const wxObjectRefData *data) const +{ + return new wxColourRefData(*(wxColourRefData *)data); +} -int wxColour::AllocColour(WXDisplay* display, bool realloc) +void wxColour::Set( unsigned char red, unsigned char green, unsigned char blue ) { - if ((m_pixel != -1) && !realloc) - return m_pixel; - - XColor color; - color.red = (unsigned short) Red (); - color.red |= color.red << 8; - color.green = (unsigned short) Green (); - color.green |= color.green << 8; - color.blue = (unsigned short) Blue (); - color.blue |= color.blue << 8; - - color.flags = DoRed | DoGreen | DoBlue; + AllocExclusive(); - WXColormap cmap = wxTheApp->GetMainColormap(display); - - if (!XAllocColor ((Display*) display, (Colormap) cmap, &color)) - { - m_pixel = wxGetBestMatchingPixel((Display*) display, &color,(Colormap) cmap); - return m_pixel; - } - else - { - m_pixel = (int) color.pixel; - return m_pixel; - } + m_refData = new wxColourRefData(); + M_COLDATA->m_color.red = ((unsigned short)red) << SHIFT; + M_COLDATA->m_color.green = ((unsigned short)green) << SHIFT; + M_COLDATA->m_color.blue = ((unsigned short)blue) << SHIFT; + M_COLDATA->m_color.pixel = 0; } -/*------------------------------------------- -Markus Emmenegger -Find the pixel value with an assigned color closest to the desired color -Used if color cell allocation fails -As the returned pixel value may be in use by another application, -the color might change anytime. -But in many cases, that is still better than always using black. --- -Chris Breeze -Improvements: -1) More efficient calculation of RGB distance of colour cell from -the desired colour. There is no need to take the sqrt of 'dist', and -since we are only interested in the top 8-bits of R, G and B we -can perform integer arithmetic. -2) Attempt to allocate a read-only colour when a close match is found. -A read-only colour will not change. -3) Fall back to the closest match if no read-only colours are available. - - Possible further improvements: - 1) Scan the lookup table and sort the colour cells in order of - increasing - distance from the desired colour. Then attempt to allocate a - read-only - colour starting from the nearest match. - 2) Linear RGB distance is not a particularly good method of colour - matching - (though it is quick). Converting the colour to HLS and then comparing - may give better matching. --------------------------------------------*/ - -int wxGetBestMatchingPixel(Display *display, XColor *desiredColor, Colormap cmap) -{ - if (cmap == (Colormap) NULL) - cmap = (Colormap) wxTheApp->GetMainColormap(display); - - int numPixVals = XDisplayCells(display, DefaultScreen (display)); - int mindist = 256 * 256 * 3; - int bestpixel = (int) BlackPixel (display, DefaultScreen (display)); - int red = desiredColor->red >> 8; - int green = desiredColor->green >> 8; - int blue = desiredColor->blue >> 8; - const int threshold = 2 * 2 * 3; // allow an error of up to 2 in R,G & B - - for (int pixelcount = 0; pixelcount < numPixVals; pixelcount++) - { - XColor matching_color; - matching_color.pixel = pixelcount; - XQueryColor(display,cmap,&matching_color); - - int delta_red = red - (matching_color.red >> 8); - int delta_green = green - (matching_color.green >> 8); - int delta_blue = blue - (matching_color.blue >> 8); - - int dist = delta_red * delta_red + - delta_green * delta_green + - delta_blue * delta_blue; - - if (dist <= threshold) - { - // try to allocate a read-only colour... - if (XAllocColor (display, cmap, &matching_color)) - { - return matching_color.pixel; - } - } - if (dist < mindist) - { - bestpixel = pixelcount; - mindist = dist; - } - } - return bestpixel; +unsigned char wxColour::Red() const +{ + wxCHECK_MSG( Ok(), 0, wxT("invalid colour") ); + + return (unsigned char)(M_COLDATA->m_color.red >> SHIFT); +} + +unsigned char wxColour::Green() const +{ + wxCHECK_MSG( Ok(), 0, wxT("invalid colour") ); + + return (unsigned char)(M_COLDATA->m_color.green >> SHIFT); +} + +unsigned char wxColour::Blue() const +{ + wxCHECK_MSG( Ok(), 0, wxT("invalid colour") ); + + return (unsigned char)(M_COLDATA->m_color.blue >> SHIFT); +} + +void wxColour::CalcPixel( WXColormap cmap ) +{ + if (!Ok()) return; + + M_COLDATA->AllocColour( cmap ); +} + +unsigned long wxColour::GetPixel() const +{ + wxCHECK_MSG( Ok(), 0, wxT("invalid colour") ); + + return M_COLDATA->m_color.pixel; +} + +WXColor *wxColour::GetColor() const +{ + wxCHECK_MSG( Ok(), (WXColor *) NULL, wxT("invalid colour") ); + + return (WXColor*) &M_COLDATA->m_color; } diff --git a/src/x11/dc.cpp b/src/x11/dc.cpp index c66c5f4797..aeef76c8fd 100644 --- a/src/x11/dc.cpp +++ b/src/x11/dc.cpp @@ -38,44 +38,28 @@ wxDC::wxDC() { m_ok = FALSE; +#if 1 m_mm_to_pix_x = 1.0; m_mm_to_pix_y = 1.0; +#else + m_mm_to_pix_x = (double)wxGetDisplaySize().GetWidth() / + (double)wxGetDisplaySizeMM().GetWidth(); + m_mm_to_pix_y = (double)wxGetDisplaySize().GetHeight() / + (double)wxGetDisplaySizeMM().GetHeight(); +#endif - m_backgroundMode = wxTRANSPARENT; - - m_isInteractive = FALSE; -} - -void wxDC::DoDrawIcon( const wxIcon &icon, wxCoord x, wxCoord y) -{ - wxCHECK_RET( Ok(), "invalid dc" ); - wxCHECK_RET( icon.Ok(), "invalid icon" ); - - DoDrawBitmap(icon, x, y, TRUE); -} - -void wxDC::DoDrawBitmap( const wxBitmap& bitmap, wxCoord x, wxCoord y, bool useMask ) -{ - wxCHECK_RET( bitmap.Ok(), "invalid bitmap" ); + m_needComputeScaleX = FALSE; /* not used yet */ + m_needComputeScaleY = FALSE; /* not used yet */ - wxMemoryDC memDC; - memDC.SelectObject(bitmap); + m_logicalFunction = wxCOPY; -#if 0 - // Not sure if we need this. The mask should leave the masked areas as per - // the original background of this DC. - if (useMask) - { - // There might be transparent areas, so make these the same colour as this - // DC - memDC.SetBackground(* GetBackground()); - memDC.Clear(); - } -#endif // 0 + m_pen = *wxBLACK_PEN; + m_font = *wxNORMAL_FONT; + m_brush = *wxWHITE_BRUSH; - Blit(x, y, bitmap.GetWidth(), bitmap.GetHeight(), &memDC, 0, 0, wxCOPY, useMask); + m_backgroundMode = wxTRANSPARENT; - memDC.SelectObject(wxNullBitmap); + m_isInteractive = FALSE; // ??? } void wxDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) @@ -92,14 +76,6 @@ void wxDC::DestroyClippingRegion() m_clipping = FALSE; } -void wxDC::DoGetSize( int* width, int* height ) const -{ - if ( width ) - *width = m_maxX - m_minX; - if ( height ) - *height = m_maxY - m_minY; -} - void wxDC::DoGetSizeMM( int* width, int* height ) const { int w, h; diff --git a/src/x11/dcclient.cpp b/src/x11/dcclient.cpp index 20875caf01..44b06b29b7 100644 --- a/src/x11/dcclient.cpp +++ b/src/x11/dcclient.cpp @@ -1,41 +1,14 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: dcclient.cpp +// Name: x11/dcclient.cpp // Purpose: wxClientDC class -// Author: Julian Smart +// Author: Julian Smart, Robert Roebling // Modified by: // Created: 01/02/97 // RCS-ID: $Id$ -// Copyright: (c) Julian Smart +// Copyright: (c) Julian Smart, Robert Roebling // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -/* - About pens, brushes, and the autoSetting flag: - - Under X, pens and brushes control some of the same X drawing parameters. - Therefore, it is impossible to independently maintain the current pen and the - current brush. Also, some settings depend on the current logical function. The - m_currentFill, etc. instance variables remember state across the brush and - pen. - - Since pens are used more than brushes, the autoSetting flag is used to - indicate that a brush was recently used, and SetPen must be called to - reinstall the current pen's parameters. If autoSetting includes 0x2, then the - pens color may need to be set based on XOR. - - There is, unfortunately, some confusion between setting the current pen/brush - and actually installing the brush/pen parameters. Both functionalies are - perform by SetPen and SetBrush. C'est la vie. -*/ - -// ============================================================================ -// declarations -// ============================================================================ - -// ---------------------------------------------------------------------------- -// headers -// ---------------------------------------------------------------------------- - #ifdef __GNUG__ #pragma implementation "dcclient.h" #endif @@ -46,22 +19,19 @@ #include "wx/app.h" #include "wx/image.h" +#include "wx/x11/private.h" + #include -#ifdef __VMS__ -#pragma message disable nosimpint -#endif -#include "X11/Xlib.h" -#include "X11/Xutil.h" -#ifdef __VMS__ -#pragma message enable nosimpint -#endif +//----------------------------------------------------------------------------- +// local defines +//----------------------------------------------------------------------------- -#include "wx/x11/private.h" +#define USE_PAINT_REGION 1 -#ifdef __EMX__ - #include // for M_PI -#endif // __EMX__ +//----------------------------------------------------------------------------- +// local data +//----------------------------------------------------------------------------- #include "bdiag.xbm" #include "fdiag.xbm" @@ -69,155 +39,272 @@ #include "horiz.xbm" #include "verti.xbm" #include "cross.xbm" +#define num_hatches 6 -static Pixmap bdiag, cdiag, fdiag, cross, horiz, verti; +#define IS_15_PIX_HATCH(s) ((s)==wxCROSSDIAG_HATCH || (s)==wxHORIZONTAL_HATCH || (s)==wxVERTICAL_HATCH) +#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; + +//----------------------------------------------------------------------------- // constants -// ---------------------------------------------------------------------------- +//----------------------------------------------------------------------------- -// Fudge factor (VZ: what??) -#define WX_GC_CF 1 +const double RAD2DEG = 180.0 / M_PI; // ---------------------------------------------------------------------------- -// macros +// private functions // ---------------------------------------------------------------------------- - IMPLEMENT_DYNAMIC_CLASS(wxClientDC, wxWindowDC) - IMPLEMENT_DYNAMIC_CLASS(wxPaintDC, wxWindowDC) - IMPLEMENT_DYNAMIC_CLASS(wxWindowDC, wxDC) +static inline double dmax(double a, double b) { return a > b ? a : b; } +static inline double dmin(double a, double b) { return a < b ? a : b; } -// ---------------------------------------------------------------------------- -// prototypes -// ---------------------------------------------------------------------------- +static inline double DegToRad(double deg) { return (deg * M_PI) / 180.0; } + +//----------------------------------------------------------------------------- +// Implement Pool of Graphic contexts. Creating them takes too much time. +//----------------------------------------------------------------------------- + +#define GC_POOL_SIZE 200 + +enum wxPoolGCType +{ + wxGC_ERROR = 0, + wxTEXT_MONO, + wxBG_MONO, + wxPEN_MONO, + wxBRUSH_MONO, + wxTEXT_COLOUR, + wxBG_COLOUR, + wxPEN_COLOUR, + wxBRUSH_COLOUR, + wxTEXT_SCREEN, + wxBG_SCREEN, + wxPEN_SCREEN, + wxBRUSH_SCREEN +}; + +struct wxGC +{ + GC m_gc; + wxPoolGCType m_type; + bool m_used; +}; + +static wxGC wxGCPool[GC_POOL_SIZE]; + +static void wxInitGCPool() +{ + memset( wxGCPool, 0, GC_POOL_SIZE*sizeof(wxGC) ); +} -static void XCopyRemote(Display *src_display, Display *dest_display, - Drawable src, Drawable dest, - GC destgc, - int srcx, int srcy, - unsigned int w, unsigned int h, - int destx, int desty, - bool more, XImage **cache); - -// ============================================================================ -// implementation -// ============================================================================ - -/* - * compare two doubles and return the larger rounded - * to the nearest int - */ -static int roundmax(double a, double b) +static void wxCleanUpGCPool() { - return (int)((a > b ? a : b) + 0.5); + for (int i = 0; i < GC_POOL_SIZE; i++) + { + if (wxGCPool[i].m_gc) + XFreeGC( wxGlobalDisplay(), wxGCPool[i].m_gc ); + } } -/* - * compare two doubles and return the smaller rounded - * to the nearest int - */ -static int roundmin(double a, double b) +static GC wxGetPoolGC( Window window, wxPoolGCType type ) { - return (int)((a < b ? a : b) - 0.5); + for (int i = 0; i < GC_POOL_SIZE; i++) + { + if (!wxGCPool[i].m_gc) + { + 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; + } + if ((!wxGCPool[i].m_used) && (wxGCPool[i].m_type == type)) + { + wxGCPool[i].m_used = TRUE; + return wxGCPool[i].m_gc; + } + } + + wxFAIL_MSG( wxT("No GC available") ); + + return (GC) NULL; } +static void wxFreePoolGC( GC gc ) +{ + for (int i = 0; i < GC_POOL_SIZE; i++) + { + if (wxGCPool[i].m_gc == gc) + { + wxGCPool[i].m_used = FALSE; + return; + } + } + + wxFAIL_MSG( wxT("Wrong GC") ); +} // ---------------------------------------------------------------------------- // wxWindowDC // ---------------------------------------------------------------------------- +IMPLEMENT_DYNAMIC_CLASS(wxWindowDC, wxDC) + wxWindowDC::wxWindowDC() { - m_gc = (WXGC) 0; - m_gcBacking = (WXGC) 0; - m_window = NULL; - m_backgroundPixel = -1; - m_currentPenWidth = 1; - m_currentPenJoin = -1; - m_currentPenDashCount = -1; - m_currentPenDash = (wxX11Dash*) NULL; - m_currentStyle = -1; - m_currentFill = -1; - // m_currentBkMode = wxTRANSPARENT; - m_colour = wxColourDisplay(); - m_display = (WXDisplay*) NULL; - m_currentRegion = (WXRegion) 0; - m_userRegion = (WXRegion) 0; - m_pixmap = (WXPixmap) 0; - m_autoSetting = 0; - m_oldFont = (WXFont) 0; + 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_isMemDC = FALSE; + m_isScreenDC = FALSE; + m_owner = (wxWindow *)NULL; } wxWindowDC::wxWindowDC( wxWindow *window ) { - wxASSERT_MSG( (window != (wxWindow*) NULL), "You must pass a valid wxWindow to wxWindowDC/wxClientDC/wxPaintDC constructor." ); - - m_window = 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; m_font = window->GetFont(); - m_gc = (WXGC) 0; - m_gcBacking = (WXGC) 0; - m_backgroundPixel = -1; - m_currentPenWidth = 1; - m_currentPenJoin = -1; - m_currentPenDashCount = -1; - m_currentPenDash = (wxX11Dash*) NULL; - m_currentStyle = -1; - m_currentFill = -1; - // m_currentBkMode = wxTRANSPARENT; - m_colour = wxColourDisplay(); - m_currentRegion = (WXRegion) 0; - m_userRegion = (WXRegion) 0; - m_ok = TRUE; - m_autoSetting = 0; - m_display = window->GetXDisplay(); - m_pixmap = window->GetXWindow(); - Display* display = (Display*) m_display; + m_window = (WXWindow*) window->GetMainWindow(); - XSetWindowColormap (display, (Pixmap) m_pixmap, (Colormap) wxTheApp->GetMainColormap(m_display)); + // not realized ? + if (!m_window) + { + // don't report problems + m_ok = TRUE; + + return; + } - XGCValues gcvalues; - gcvalues.foreground = BlackPixel (display, DefaultScreen (display)); - gcvalues.background = WhitePixel (display, DefaultScreen (display)); - gcvalues.graphics_exposures = False; - gcvalues.subwindow_mode = IncludeInferiors; - gcvalues.line_width = 1; - m_gc = (WXGC) XCreateGC (display, RootWindow (display, DefaultScreen (display)), - GCForeground | GCBackground | GCGraphicsExposures | GCLineWidth | GCSubwindowMode, - &gcvalues); + m_display = (WXDisplay *) wxGlobalDisplay(); + + int screen = DefaultScreen( (Display*) m_display ); + m_cmap = (WXColormap) DefaultColormap( (Display*) m_display, screen ); - m_backgroundPixel = (int) gcvalues.background; + SetUpDC(); - // Get the current Font so we can set it back later - XGCValues valReturn; - XGetGCValues((Display*) m_display, (GC) m_gc, GCFont, &valReturn); - m_oldFont = (WXFont) valReturn.font; + /* this must be done after SetUpDC, bacause SetUpDC calls the + repective SetBrush, SetPen, SetBackground etc functions + to set up the DC. SetBackground call m_owner->SetBackground + and this might not be desired as the standard dc background + is white whereas a window might assume gray to be the + standard (as e.g. wxStatusBar) */ - SetBackground(wxBrush(m_window->GetBackgroundColour(), wxSOLID)); + m_owner = window; } wxWindowDC::~wxWindowDC() { - if (m_gc && (m_oldFont != (WXFont) 0) && ((long) m_oldFont != -1)) + Destroy(); +} + +void wxWindowDC::SetUpDC() +{ + m_ok = TRUE; + + wxASSERT_MSG( !m_penGC, wxT("GCs already created") ); + + if (m_isScreenDC) + { + m_penGC = (WXGC*) wxGetPoolGC( (Window) m_window, wxPEN_SCREEN ); + m_brushGC = (WXGC*) wxGetPoolGC( (Window) m_window, wxBRUSH_SCREEN ); + m_textGC = (WXGC*) wxGetPoolGC( (Window) m_window, wxTEXT_SCREEN ); + m_bgGC = (WXGC*) wxGetPoolGC( (Window) m_window, wxBG_SCREEN ); + } +#if 0 + else + if (m_isMemDC && (((wxMemoryDC*)this)->m_selected.GetDepth() == 1)) + { + m_penGC = (WXGC*) wxGetPoolGC( (Window) m_window, wxPEN_MONO ); + m_brushGC = (WXGC*) wxGetPoolGC( (Window) m_window, wxBRUSH_MONO ); + m_textGC = (WXGC*) wxGetPoolGC( (Window) m_window, wxTEXT_MONO ); + m_bgGC = (WXGC*) wxGetPoolGC( (Window) m_window, wxBG_MONO ); + } +#endif + else { - XSetFont ((Display*) m_display, (GC) m_gc, (Font) m_oldFont); + m_penGC = (WXGC*) wxGetPoolGC( (Window) m_window, wxPEN_COLOUR ); + m_brushGC = (WXGC*) wxGetPoolGC( (Window) m_window, wxBRUSH_COLOUR ); + m_textGC = (WXGC*) wxGetPoolGC( (Window) m_window, wxTEXT_COLOUR ); + m_bgGC = (WXGC*) wxGetPoolGC( (Window) m_window, wxBG_COLOUR ); } - if (m_gc) - XFreeGC ((Display*) m_display, (GC) m_gc); - m_gc = (WXGC) 0; + /* background colour */ + m_backgroundBrush = *wxWHITE_BRUSH; + m_backgroundBrush.GetColour().CalcPixel( m_cmap ); + unsigned long bg_col = m_backgroundBrush.GetColour().GetPixel(); + + /* m_textGC */ + m_textForegroundColour.CalcPixel( m_cmap ); + XSetForeground( (Display*) m_display, (GC) m_textGC, m_textForegroundColour.GetPixel() ); + + m_textBackgroundColour.CalcPixel( m_cmap ); + XSetBackground( (Display*) m_display, (GC) m_textGC, m_textBackgroundColour.GetPixel() ); + + XSetFillStyle( (Display*) m_display, (GC) m_textGC, FillSolid ); + + /* m_penGC */ + m_pen.GetColour().CalcPixel( m_cmap ); + XSetForeground( (Display*) m_display, (GC) m_penGC, m_pen.GetColour().GetPixel() ); + XSetBackground( (Display*) m_display, (GC) m_penGC, bg_col ); + + XSetLineAttributes( (Display*) m_display, (GC) m_penGC, 0, LineSolid, CapNotLast, JoinRound ); + + /* m_brushGC */ + m_brush.GetColour().CalcPixel( m_cmap ); + XSetForeground( (Display*) m_display, (GC) m_brushGC, m_brush.GetColour().GetPixel() ); + XSetBackground( (Display*) m_display, (GC) m_brushGC, bg_col ); + + XSetFillStyle( (Display*) m_display, (GC) m_brushGC, FillSolid ); + + /* 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 */ + XSetFunction( (Display*) m_display, (GC) m_textGC, GXcopy ); + XSetFunction( (Display*) m_display, (GC) m_brushGC, GXcopy ); + XSetFunction( (Display*) m_display, (GC)m_penGC, GXcopy ); + + /* clipping */ + XSetClipMask( (Display*) m_display, (GC) m_penGC, None ); + XSetClipMask( (Display*) m_display, (GC) m_brushGC, None ); + XSetClipMask( (Display*) m_display, (GC) m_textGC, None ); + XSetClipMask( (Display*) m_display, (GC) m_bgGC, None ); - if (m_gcBacking) - XFreeGC ((Display*) m_display, (GC) m_gcBacking); - m_gcBacking = (WXGC) 0; + if (!hatch_bitmap) + { + hatch_bitmap = hatches; + hatch_bitmap[0] = XCreateBitmapFromData( (Display*) m_display, None, bdiag_bits, bdiag_width, bdiag_height ); + hatch_bitmap[1] = XCreateBitmapFromData( (Display*) m_display, None, cdiag_bits, cdiag_width, cdiag_height ); + hatch_bitmap[2] = XCreateBitmapFromData( (Display*) m_display, None, fdiag_bits, fdiag_width, fdiag_height ); + hatch_bitmap[3] = XCreateBitmapFromData( (Display*) m_display, None, cross_bits, cross_width, cross_height ); + hatch_bitmap[4] = XCreateBitmapFromData( (Display*) m_display, None, horiz_bits, horiz_width, horiz_height ); + hatch_bitmap[5] = XCreateBitmapFromData( (Display*) m_display, None, verti_bits, verti_width, verti_height ); + } +} - if (m_currentRegion) - XDestroyRegion ((Region) m_currentRegion); - m_currentRegion = (WXRegion) 0; +void wxWindowDC::DoGetSize( int* width, int* height ) const +{ + wxCHECK_RET( m_owner, _T("GetSize() doesn't work without window") ); - if (m_userRegion) - XDestroyRegion ((Region) m_userRegion); - m_userRegion = (WXRegion) 0; + m_owner->GetSize(width, height); } void wxWindowDC::DoFloodFill( wxCoord WXUNUSED(x1), wxCoord WXUNUSED(y1), @@ -242,63 +329,54 @@ bool wxWindowDC::DoGetPixel( wxCoord x1, wxCoord y1, wxColour *col ) const void wxWindowDC::DoDrawLine( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2 ) { - wxCHECK_RET( Ok(), "invalid dc" ); - - int x1d, y1d, x2d, y2d; - - // FreeGetPixelCache(); + wxCHECK_RET( Ok(), wxT("invalid window dc") ); - x1d = XLOG2DEV(x1); - y1d = YLOG2DEV(y1); - x2d = XLOG2DEV(x2); - y2d = YLOG2DEV(y2); - - if (m_autoSetting) - SetPen (m_pen); - - XDrawLine ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, x1d, y1d, x2d, y2d); + 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) ); - CalcBoundingBox(x1, y1); - CalcBoundingBox(x2, y2); + CalcBoundingBox(x1, y1); + CalcBoundingBox(x2, y2); + } } void wxWindowDC::DoCrossHair( wxCoord x, wxCoord y ) { - wxCHECK_RET( Ok(), "invalid dc" ); + wxCHECK_RET( Ok(), wxT("invalid window dc") ); - if (m_autoSetting) - SetPen (m_pen); - - int xx = XLOG2DEV (x); - int yy = YLOG2DEV (y); - int ww, hh; - wxDisplaySize (&ww, &hh); - XDrawLine ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, 0, yy, - ww, yy); - XDrawLine ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, xx, 0, - xx, hh); + if (m_pen.GetStyle() != wxTRANSPARENT) + { + int w = 0; + int h = 0; + GetSize( &w, &h ); + wxCoord xx = XLOG2DEV(x); + wxCoord yy = YLOG2DEV(y); + if (m_window) + { + XDrawLine( (Display*) m_display, (Window) m_window, + (GC) m_penGC, 0, yy, XLOG2DEVREL(w), yy ); + XDrawLine( (Display*) m_display, (Window) m_window, + (GC) m_penGC, xx, 0, xx, YLOG2DEVREL(h) ); + } + } } void wxWindowDC::DoDrawArc( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, wxCoord xc, wxCoord yc ) { - wxCHECK_RET( Ok(), "invalid dc" ); - - // FreeGetPixelCache(); - - int xx1 = XLOG2DEV (x1); - int yy1 = YLOG2DEV (y1); - int xx2 = XLOG2DEV (x2); - int yy2 = YLOG2DEV (y2); - int xxc = XLOG2DEV (xc); - int yyc = YLOG2DEV (yc); - int xxc_2 = XLOG2DEV_2 (xc); - int yyc_2 = YLOG2DEV_2 (yc); - - wxCoord dx = xx1 - xxc; - wxCoord dy = yy1 - yyc; - double radius = sqrt ((double)(dx * dx + dy * dy)); - wxCoord r = (wxCoord) radius; - + wxCHECK_RET( Ok(), wxT("invalid window dc") ); + + wxCoord xx1 = XLOG2DEV(x1); + wxCoord yy1 = YLOG2DEV(y1); + wxCoord xx2 = XLOG2DEV(x2); + wxCoord yy2 = YLOG2DEV(y2); + wxCoord xxc = XLOG2DEV(xc); + wxCoord yyc = YLOG2DEV(yc); + double dx = xx1 - xxc; + double dy = yy1 - yyc; + double radius = sqrt((double)(dx*dx+dy*dy)); + wxCoord r = (wxCoord)radius; double radius1, radius2; if (xx1 == xx2 && yy1 == yy2) @@ -306,444 +384,606 @@ void wxWindowDC::DoDrawArc( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, wxCo radius1 = 0.0; radius2 = 360.0; } - else if (radius == 0.0) - radius1 = radius2 = 0.0; else + if (radius == 0.0) { - if (xx1 - xxc == 0) - if (yy1 - yyc < 0) - radius1 = 90.0; - else - radius1 = -90.0; - else - radius1 = -atan2 ((double) (yy1 - yyc), (double) (xx1 - xxc)) * 360.0 / (2 * M_PI); - - if (xx2 - xxc == 0) - if (yy2 - yyc < 0) - radius2 = 90.0; - else - radius2 = -90.0; - else - radius2 = -atan2 ((double) (yy2 - yyc), (double) (xx2 - xxc)) * 360.0 / (2 * M_PI); + radius1 = radius2 = 0.0; } - radius1 *= 64.0; - radius2 *= 64.0; - int alpha1 = (int) radius1; - int alpha2 = (int) (radius2 - radius1); - while (alpha2 <= 0) - alpha2 += 360 * 64; - while (alpha2 > 360 * 64) - alpha2 -= 360 * 64; - - if (m_brush.Ok() && m_brush.GetStyle () != wxTRANSPARENT) + else { - SetBrush (m_brush); - XFillArc ((Display*) m_display, (Pixmap) m_pixmap, (GC) (GC) m_gc, - xxc - r, yyc - r, 2 * r, 2 * r, alpha1, alpha2); - + radius1 = (xx1 - xxc == 0) ? + (yy1 - yyc < 0) ? 90.0 : -90.0 : + -atan2(double(yy1-yyc), double(xx1-xxc)) * RAD2DEG; + radius2 = (xx2 - xxc == 0) ? + (yy2 - yyc < 0) ? 90.0 : -90.0 : + -atan2(double(yy2-yyc), double(xx2-xxc)) * RAD2DEG; } + wxCoord alpha1 = wxCoord(radius1 * 64.0); + wxCoord alpha2 = wxCoord((radius2 - radius1) * 64.0); + while (alpha2 <= 0) alpha2 += 360*64; + while (alpha1 > 360*64) alpha1 -= 360*64; - if (m_pen.Ok() && m_pen.GetStyle () != wxTRANSPARENT) + if (m_window) { - if (m_autoSetting) - SetPen (m_pen); - XDrawArc ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, - xxc - r, yyc - r, 2 * r, 2 * r, alpha1, alpha2); + 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() ); + + 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) + { + 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 + { + XFillArc( (Display*) m_display, (Window) m_window, + (GC) m_brushGC, xxc-r, yyc-r, 2*r,2*r, alpha1, alpha2 ); + } + } + + if (m_pen.GetStyle() != wxTRANSPARENT) + { + 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 ); + } } + CalcBoundingBox (x1, y1); CalcBoundingBox (x2, y2); } void wxWindowDC::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord width, wxCoord height, double sa, double ea ) { - wxCHECK_RET( Ok(), "invalid dc" ); - - int xd, yd, wd, hd; + wxCHECK_RET( Ok(), wxT("invalid window dc") ); - xd = XLOG2DEV(x); - yd = YLOG2DEV(y); - wd = XLOG2DEVREL(width); - hd = YLOG2DEVREL(height); + wxCoord xx = XLOG2DEV(x); + wxCoord yy = YLOG2DEV(y); + wxCoord ww = m_signX * XLOG2DEVREL(width); + wxCoord hh = m_signY * YLOG2DEVREL(height); - if (sa>=360 || sa<=-360) sa=sa-int(sa/360)*360; - if (ea>=360 || ea<=-360) ea=ea-int(ea/360)*360; - int start = int(sa*64); - int end = int(ea*64); - if (start<0) start+=360*64; - if (end <0) end +=360*64; - if (end>start) end-=start; - else end+=360*64-start; + // 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_brush.Ok() && m_brush.GetStyle () != wxTRANSPARENT) + if (m_window) { - m_autoSetting = TRUE; // must be reset + wxCoord start = wxCoord(sa * 64.0); + wxCoord end = wxCoord((ea-sa) * 64.0); - SetBrush (m_brush); - XFillArc ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, xd, yd, wd, hd, start, end); - } + 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() ); + + 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) + { + 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 + { + XFillArc( (Display*) m_display, (Window) m_window, + (GC) m_brushGC, xx, yy, ww, hh, start, end ); + } + } - if (m_pen.Ok() && m_pen.GetStyle () != wxTRANSPARENT) - { - if (m_autoSetting) - SetPen (m_pen); - XDrawArc ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, xd, yd, wd, hd, start,end); + if (m_pen.GetStyle() != wxTRANSPARENT) + { + XDrawArc( (Display*) m_display, (Window) m_window, + (GC) m_penGC, xx, yy, ww, hh, start, end ); + } } - + CalcBoundingBox (x, y); CalcBoundingBox (x + width, y + height); } void wxWindowDC::DoDrawPoint( wxCoord x, wxCoord y ) { - wxCHECK_RET( Ok(), "invalid dc" ); + wxCHECK_RET( Ok(), wxT("invalid window dc") ); - // FreeGetPixelCache(); + if ((m_pen.GetStyle() != wxTRANSPARENT) && m_window) + XDrawPoint( (Display*) m_display, (Window) m_window, + (GC) m_penGC, XLOG2DEV(x), YLOG2DEV(y) ); - if (m_pen.Ok() && m_autoSetting) - SetPen (m_pen); - - XDrawPoint ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, XLOG2DEV (x), YLOG2DEV (y)); - CalcBoundingBox (x, y); } void wxWindowDC::DoDrawLines( int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset ) { - wxCHECK_RET( Ok(), "invalid dc" ); + wxCHECK_RET( Ok(), wxT("invalid window dc") ); - // FreeGetPixelCache(); + if (m_pen.GetStyle() == wxTRANSPARENT) return; + if (n <= 0) return; - if (m_pen.Ok() && m_pen.GetStyle () != wxTRANSPARENT) + XPoint *xpoints = new XPoint[n]; + for (int i = 0; i < n; i++) { - if (m_autoSetting) - SetPen (m_pen); - - XPoint *xpoints = new XPoint[n]; - int i; - - for (i = 0; i < n; i++) - { - xpoints[i].x = XLOG2DEV (points[i].x + xoffset); - xpoints[i].y = YLOG2DEV (points[i].y + yoffset); - } - XDrawLines ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, xpoints, n, 0); - - delete[]xpoints; + 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 ); + + delete[] xpoints; } void wxWindowDC::DoDrawPolygon( int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset, int fillStyle ) { - wxCHECK_RET( Ok(), "invalid dc" ); + wxCHECK_RET( Ok(), wxT("invalid window dc") ); - // FreeGetPixelCache(); + if (n <= 0) return; - XPoint *xpoints1 = new XPoint[n + 1]; - XPoint *xpoints2 = new XPoint[n + 1]; + XPoint *xpoints = new XPoint[n + 1]; int i; for (i = 0; i < n; i++) { - xpoints1[i].x = XLOG2DEV (points[i].x + xoffset); - xpoints1[i].y = YLOG2DEV (points[i].y + yoffset); - xpoints2[i].x = XLOG2DEV_2 (points[i].x + xoffset); - xpoints2[i].y = YLOG2DEV_2 (points[i].y + yoffset); + 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); } - // Close figure for XDrawLines (not needed for XFillPolygon) - xpoints1[i].x = xpoints1[0].x; - xpoints1[i].y = xpoints1[0].y; - xpoints2[i].x = xpoints2[0].x; - xpoints2[i].y = xpoints2[0].y; - - if (m_brush.Ok() && m_brush.GetStyle () != wxTRANSPARENT) + if (m_window) { - SetBrush (m_brush); - XSetFillRule ((Display*) m_display, (GC) m_gc, fillStyle == wxODDEVEN_RULE ? EvenOddRule : WindingRule); - XFillPolygon ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, xpoints1, n, Complex, 0); - XSetFillRule ((Display*) m_display, (GC) m_gc, EvenOddRule); // default mode - } + 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) + { + 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 + { + XFillPolygon( (Display*) m_display, (Window) m_window, + (GC) m_brushGC, xpoints, n, Complex, 0); + } + } - if (m_pen.Ok() && m_pen.GetStyle () != wxTRANSPARENT) - { - if (m_autoSetting) - SetPen (m_pen); - XDrawLines ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, xpoints1, n + 1, 0); + if (m_pen.GetStyle () != wxTRANSPARENT) + { + // Close figure for XDrawLines + xpoints[i].x = xpoints[0].x; + xpoints[i].y = xpoints[0].y; + + XDrawLines( (Display*) m_display, (Window) m_window, (GC) m_penGC, xpoints, n + 1, 0); + } } - delete[]xpoints1; - delete[]xpoints2; + delete[] xpoints; } void wxWindowDC::DoDrawRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) { - wxCHECK_RET( Ok(), "invalid dc" ); + wxCHECK_RET( Ok(), wxT("invalid window dc") ); - // FreeGetPixelCache(); + wxCoord xx = XLOG2DEV(x); + wxCoord yy = YLOG2DEV(y); + wxCoord ww = m_signX * XLOG2DEVREL(width); + wxCoord hh = m_signY * YLOG2DEVREL(height); - int xd, yd, wfd, hfd, wd, hd; + // CMB: draw nothing if transformed w or h is 0 + if (ww == 0 || hh == 0) return; - xd = XLOG2DEV(x); - yd = YLOG2DEV(y); - wfd = XLOG2DEVREL(width); - wd = wfd - WX_GC_CF; - hfd = YLOG2DEVREL(height); - hd = hfd - WX_GC_CF; - - if (wfd == 0 || hfd == 0) return; - if (wd < 0) { wd = - wd; xd = xd - wd; } - if (hd < 0) { hd = - hd; yd = yd - hd; } - - if (m_brush.Ok() && m_brush.GetStyle () != wxTRANSPARENT) + // 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) { - SetBrush (m_brush); - XFillRectangle ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, xd, yd, wfd, hfd); - } + 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, 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) + { + 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 + { + XFillRectangle( (Display*) m_display, (Window) m_window, + (GC) m_brushGC, xx, yy, ww, hh ); + } + } - if (m_pen.Ok() && m_pen.GetStyle () != wxTRANSPARENT) - { - if (m_autoSetting) - SetPen (m_pen); - XDrawRectangle ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, xd, yd, wd, hd); + if (m_pen.GetStyle () != wxTRANSPARENT) + { + XDrawRectangle( (Display*) m_display, (Window) m_window, + (GC) m_penGC, xx, yy, ww, hh ); + } } - - CalcBoundingBox (x, y); - CalcBoundingBox (x + width, y + height); + + CalcBoundingBox( x, y ); + CalcBoundingBox( x + width, y + height ); } void wxWindowDC::DoDrawRoundedRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoord height, double radius ) { - wxCHECK_RET( Ok(), "invalid dc" ); - - // FreeGetPixelCache(); - - // If radius is negative, it's a proportion of the smaller dimension. - - if (radius < 0.0) radius = - radius * ((width < height) ? width : height); - - int xd = XLOG2DEV (x); - int yd = YLOG2DEV (y); - int rd = XLOG2DEVREL ((long) radius); - int wd = XLOG2DEVREL (width) - WX_GC_CF; - int hd = YLOG2DEVREL (height) - WX_GC_CF; - - int rw_d = rd * 2; - int rh_d = rw_d; - - // If radius is zero use DrawRectangle() instead to avoid - // X drawing errors with small radii - if (rd == 0) - { - DrawRectangle( x, y, width, height ); - return; - } - - // Draw nothing if transformed w or h is 0 - if (wd == 0 || hd == 0) return; - - // CMB: adjust size if outline is drawn otherwise the result is - // 1 pixel too wide and high - if (m_pen.GetStyle() != wxTRANSPARENT) - { - wd--; - hd--; - } + // later +} - // CMB: ensure dd is not larger than rectangle otherwise we - // get an hour glass shape - if (rw_d > wd) rw_d = wd; - if (rw_d > hd) rw_d = hd; - rd = rw_d / 2; +void wxWindowDC::DoDrawEllipse( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) +{ + wxCHECK_RET( Ok(), wxT("invalid window dc") ); - // For backing pixmap - int xd2 = XLOG2DEV_2 (x); - int yd2 = YLOG2DEV_2 (y); - int rd2 = XLOG2DEVREL ((long) radius); - int wd2 = XLOG2DEVREL (width) ; - int hd2 = YLOG2DEVREL (height) ; + wxCoord xx = XLOG2DEV(x); + wxCoord yy = YLOG2DEV(y); + wxCoord ww = m_signX * XLOG2DEVREL(width); + wxCoord hh = m_signY * YLOG2DEVREL(height); - int rw_d2 = rd2 * 2; - int rh_d2 = rw_d2; + // 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_brush.Ok() && m_brush.GetStyle () != wxTRANSPARENT) + if (m_window) { - SetBrush (m_brush); - - XFillRectangle ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, xd + rd, yd, - wd - rw_d, hd); - XFillRectangle ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, xd, yd + rd, - wd, hd - rh_d); - - // Arcs start from 3 o'clock, positive angles anticlockwise - // Top-left - XFillArc ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, xd, yd, - rw_d, rh_d, 90 * 64, 90 * 64); - // Top-right - XFillArc ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, xd + wd - rw_d, yd, - // rw_d, rh_d, 0, 90 * 64); - rw_d, rh_d, 0, 91 * 64); - // Bottom-right - XFillArc ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, xd + wd - rw_d, - yd + hd - rh_d, - // rw_d, rh_d, 270 * 64, 90 * 64); - rw_d, rh_d, 269 * 64, 92 * 64); - // Bottom-left - XFillArc ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, xd, yd + hd - rh_d, - rw_d, rh_d, 180 * 64, 90 * 64); - } + 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() ); + + 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) + { + 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 + { + XFillArc( (Display*) m_display, (Window) m_window, + (GC) m_brushGC, xx, yy, ww, hh, 0, 360*64 ); + } + } - if (m_pen.Ok() && m_pen.GetStyle () != wxTRANSPARENT) - { - SetPen (m_pen); - XDrawLine ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, xd + rd, yd, - xd + wd - rd + 1, yd); - XDrawLine ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, xd + rd, yd + hd, - xd + wd - rd, yd + hd); - - XDrawLine ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, xd, yd + rd, - xd, yd + hd - rd); - XDrawLine ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, xd + wd, yd + rd, - xd + wd, yd + hd - rd + 1); - XDrawArc ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, xd, yd, - rw_d, rh_d, 90 * 64, 90 * 64); - XDrawArc ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, xd + wd - rw_d, yd, - // rw_d, rh_d, 0, 90 * 64); - rw_d, rh_d, 0, 91 * 64); - XDrawArc ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, xd + wd - rw_d, - yd + hd - rh_d, - rw_d, rh_d, 269 * 64, 92 * 64); - XDrawArc ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, xd, yd + hd - rh_d, - rw_d, rh_d, 180 * 64, 90 * 64); + if (m_pen.GetStyle () != wxTRANSPARENT) + { + XDrawArc( (Display*) m_display, (Window) m_window, + (GC) m_penGC, xx, yy, ww, hh, 0, 360*64 ); + } } - CalcBoundingBox (x, y); - CalcBoundingBox (x + width, y + height); + CalcBoundingBox( x, y ); + CalcBoundingBox( x + width, y + height ); +} +void wxWindowDC::DoDrawIcon( const wxIcon &icon, wxCoord x, wxCoord y) +{ } -void wxWindowDC::DoDrawEllipse( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) +void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, + wxCoord x, wxCoord y, + bool useMask ) { - wxCHECK_RET( Ok(), "invalid dc" ); + wxCHECK_RET( Ok(), wxT("invalid window dc") ); - // Check for negative width and height - if (height < 0) - { - y = y + height; - height = - height ; - } + wxCHECK_RET( bitmap.Ok(), wxT("invalid bitmap") ); + +#if 0 + bool is_mono = (bitmap.GetBitmap() != NULL); - if (width < 0) - { - x = x + width; - width = - width ; - } + /* scale/translate size and position */ + int xx = XLOG2DEV(x); + int yy = YLOG2DEV(y); - // FreeGetPixelCache(); + int w = bitmap.GetWidth(); + int h = bitmap.GetHeight(); - static const int angle = 23040; + CalcBoundingBox( x, y ); + CalcBoundingBox( x + w, y + h ); - int xd, yd, wd, hd; + if (!m_window) return; - xd = XLOG2DEV(x); - yd = YLOG2DEV(y); - wd = XLOG2DEVREL(width) ; - hd = YLOG2DEVREL(height) ; + int ww = XLOG2DEVREL(w); + int hh = YLOG2DEVREL(h); - if (m_brush.Ok() && m_brush.GetStyle () != wxTRANSPARENT) + /* compare to current clipping region */ + if (!m_currentClippingRegion.IsNull()) { - SetBrush (m_brush); - XFillArc ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, xd, yd, wd, hd, 0, angle); + wxRegion tmp( xx,yy,ww,hh ); + tmp.Intersect( m_currentClippingRegion ); + if (tmp.IsEmpty()) + return; } - if (m_pen.Ok() && m_pen.GetStyle () != wxTRANSPARENT) + /* scale bitmap if required */ + wxBitmap use_bitmap; + if ((w != ww) || (h != hh)) { - if (m_autoSetting) - SetPen (m_pen); - XDrawArc ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, xd, yd, wd, hd, 0, angle); + wxImage image( bitmap ); + image.Rescale( ww, hh ); + if (is_mono) + use_bitmap = image.ConvertToMonoBitmap(255,255,255); + else + use_bitmap = image.ConvertToBitmap(); + } + else + { + use_bitmap = bitmap; } - CalcBoundingBox (x, y); - CalcBoundingBox (x + width, y + height); -} + /* apply mask if any */ + GdkBitmap *mask = (GdkBitmap *) NULL; + if (use_bitmap.GetMask()) mask = use_bitmap.GetMask()->GetBitmap(); -bool wxWindowDC::CanDrawBitmap() const -{ - wxCHECK_MSG( Ok(), FALSE, "invalid dc" ); + if (useMask && mask) + { + GdkBitmap *new_mask = (GdkBitmap*) NULL; + 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 ); + } - return TRUE; -} + if (is_mono) + { + if (new_mask) + gdk_gc_set_clip_mask( m_textGC, new_mask ); + else + gdk_gc_set_clip_mask( m_textGC, mask ); + gdk_gc_set_clip_origin( m_textGC, xx, yy ); + } + else + { + if (new_mask) + gdk_gc_set_clip_mask( m_penGC, new_mask ); + else + gdk_gc_set_clip_mask( m_penGC, mask ); + gdk_gc_set_clip_origin( m_penGC, xx, yy ); + } + if (new_mask) + gdk_bitmap_unref( new_mask ); + } -#if 0 -void wxWindowDC::DoDrawIcon( const wxIcon &icon, wxCoord x, wxCoord y) -{ - // FreeGetPixelCache(); - - // Be sure that foreground pixels (1) of - // the Icon will be painted with pen colour. [m_pen.SetColour()] - // Background pixels (0) will be painted with - // last selected background color. [::SetBackground] - if (m_pen.Ok() && m_autoSetting) - SetPen (m_pen); - - int width, height; - Pixmap iconPixmap = (Pixmap) icon.GetPixmap(); - width = icon.GetWidth(); - height = icon.GetHeight(); - if (icon.GetDisplay() == m_display) + /* 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) + gdk_wx_draw_bitmap( m_window, m_textGC, use_bitmap.GetBitmap(), 0, 0, xx, yy, -1, -1 ); + else + gdk_draw_pixmap( m_window, m_penGC, use_bitmap.GetPixmap(), 0, 0, xx, yy, -1, -1 ); + + /* remove mask again if any */ + if (useMask && mask) { - if (icon.GetDepth() <= 1) + if (is_mono) { - XCopyPlane ((Display*) m_display, iconPixmap, (Pixmap) m_pixmap, (GC) m_gc, - 0, 0, width, height, - (int) XLOG2DEV (x), (int) YLOG2DEV (y), 1); + gdk_gc_set_clip_mask( m_textGC, (GdkBitmap *) NULL ); + gdk_gc_set_clip_origin( m_textGC, 0, 0 ); + if (!m_currentClippingRegion.IsNull()) + gdk_gc_set_clip_region( m_textGC, m_currentClippingRegion.GetRegion() ); } else { - XCopyArea ((Display*) m_display, iconPixmap, (Pixmap) m_pixmap, (GC) m_gc, - 0, 0, width, height, - (int) XLOG2DEV (x), (int) YLOG2DEV (y)); - } + gdk_gc_set_clip_mask( m_penGC, (GdkBitmap *) NULL ); + gdk_gc_set_clip_origin( m_penGC, 0, 0 ); + if (!m_currentClippingRegion.IsNull()) + gdk_gc_set_clip_region( m_penGC, m_currentClippingRegion.GetRegion() ); } - } else { /* Remote copy (different (Display*) m_displays) */ - XImage *cache = NULL; - if (m_window && m_window->GetBackingPixmap()) - XCopyRemote((Display*) icon.GetDisplay(), (Display*) m_display, iconPixmap, (Pixmap) m_window->GetBackingPixmap(), - (GC) m_gcBacking, 0, 0, width, height, - (int) XLOG2DEV_2 (x), (int) YLOG2DEV_2 (y), TRUE, &cache); - XCopyRemote((Display*) icon.GetDisplay(), (Display*) m_display, iconPixmap, (Pixmap) m_pixmap, (GC) m_gc, - 0, 0, width, height, - (int) XLOG2DEV (x), (int) YLOG2DEV (y), FALSE, &cache); } - CalcBoundingBox (x, y); +#endif } -#endif // 0 -// TODO: use scaled Blit e.g. as per John Price's implementation in Contrib/Utilities bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height, wxDC *source, wxCoord xsrc, wxCoord ysrc, int rop, bool useMask, wxCoord xsrcMask, wxCoord ysrcMask ) { - wxCHECK_MSG( Ok(), FALSE, "invalid dc" ); + /* this is the nth try to get this utterly useless function to + work. it now completely ignores the scaling or translation + of the source dc, but scales correctly on the target dc and + knows about possible mask information in a memory dc. */ - wxWindowDC* sourceDC = wxDynamicCast(source, wxWindowDC); + wxCHECK_MSG( Ok(), FALSE, wxT("invalid window dc") ); - wxASSERT_MSG( sourceDC, "Blit source DC must be wxWindowDC or derived class." ); + wxCHECK_MSG( source, FALSE, wxT("invalid source dc") ); - // FreeGetPixelCache(); + if (!m_window) return FALSE; - // Be sure that foreground pixels (1) of the Icon will be painted with pen - // colour. [m_pen.SetColour()] Background pixels (0) will be painted with - // last selected background color. [::SetBackground] - if (m_pen.Ok() && m_autoSetting) - SetPen (m_pen); + // transform the source DC coords to the device ones + xsrc = source->XLOG2DEV(xsrc); + ysrc = source->YLOG2DEV(ysrc); - // Do bitmap scaling if necessary + wxClientDC *srcDC = (wxClientDC*)source; + wxMemoryDC *memDC = (wxMemoryDC*)source; - wxBitmap *scaledBitmap = (wxBitmap*) NULL; - Pixmap sourcePixmap = (Pixmap) NULL; - double scaleX, scaleY; - GetUserScale(& scaleX, & scaleY); + bool use_bitmap_method = FALSE; + bool is_mono = FALSE; /* TODO: use the mask origin when drawing transparently */ if (xsrcMask == -1 && ysrcMask == -1) @@ -751,403 +991,279 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he xsrcMask = xsrc; ysrcMask = ysrc; } - // Sorry, can't scale masks just yet - if (!useMask && (scaleX != 1.0 || scaleY != 1.0) && sourceDC->IsKindOf(CLASSINFO(wxMemoryDC))) +#if 0 + if (srcDC->m_isMemDC) { - wxMemoryDC* memDC = (wxMemoryDC*) sourceDC; - wxBitmap& bitmap = memDC->GetBitmap(); + if (!memDC->m_selected.Ok()) return FALSE; - wxASSERT_MSG( (bitmap.Ok()), "Bad source bitmap in wxWindowDC::Blit"); + /* we use the "XCopyArea" way to copy a memory dc into + y different window if the memory dc BOTH + a) doesn't have any mask or its mask isn't used + b) it is clipped + c) is not 1-bit */ - wxImage image(bitmap); - if (!image.Ok()) + if (useMask && (memDC->m_selected.GetMask())) { - sourcePixmap = (Pixmap) bitmap.GetPixmap(); + /* 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; + } + 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; + } + else if ((xsrc == 0) && (ysrc == 0) && + (width == memDC->m_selected.GetWidth()) && + (height == memDC->m_selected.GetHeight())) + { + /* we SHOULD use the direct way if all of the bitmap + 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; } else { - int scaledW = (int) (bitmap.GetWidth() * scaleX); - int scaledH = (int) (bitmap.GetHeight() * scaleY); - - image = image.Scale(scaledW, scaledH); - scaledBitmap = new wxBitmap(image.ConvertToBitmap()); - sourcePixmap = (Pixmap) scaledBitmap->GetPixmap(); + use_bitmap_method = FALSE; } } - else - sourcePixmap = (Pixmap) sourceDC->m_pixmap; - if (m_pixmap && sourcePixmap) + CalcBoundingBox( xdest, ydest ); + CalcBoundingBox( xdest + width, ydest + height ); + + /* scale/translate size and position */ + wxCoord xx = XLOG2DEV(xdest); + wxCoord yy = YLOG2DEV(ydest); + + wxCoord ww = XLOG2DEVREL(width); + wxCoord hh = YLOG2DEVREL(height); + + /* compare to current clipping region */ + if (!m_currentClippingRegion.IsNull()) { - /* MATTHEW: [9] */ - int orig = m_logicalFunction; + wxRegion tmp( xx,yy,ww,hh ); + tmp.Intersect( m_currentClippingRegion ); + if (tmp.IsEmpty()) + return TRUE; + } - SetLogicalFunction (rop); + int old_logical_func = m_logicalFunction; + SetLogicalFunction( logical_func ); - if (m_display != sourceDC->m_display) - { - XImage *cache = NULL; + if (use_bitmap_method) + { + /* scale/translate bitmap size */ + wxCoord bm_width = memDC->m_selected.GetWidth(); + wxCoord bm_height = memDC->m_selected.GetHeight(); -#if 0 - if (m_window && m_window->GetBackingPixmap()) - XCopyRemote((Display*) sourceDC->m_display, (Display*) m_display, - (Pixmap) sourcePixmap, (Pixmap) m_window->GetBackingPixmap(), - (GC) m_gcBacking, - source->LogicalToDeviceX (xsrc), - source->LogicalToDeviceY (ysrc), - source->LogicalToDeviceXRel(width), - source->LogicalToDeviceYRel(height), - XLOG2DEV_2 (xdest), YLOG2DEV_2 (ydest), - TRUE, &cache); -#endif + wxCoord bm_ww = XLOG2DEVREL( bm_width ); + wxCoord bm_hh = YLOG2DEVREL( bm_height ); - if ( useMask && source->IsKindOf(CLASSINFO(wxMemoryDC)) ) - { - wxMemoryDC *memDC = (wxMemoryDC *)source; - wxBitmap& sel = memDC->GetBitmap(); - if ( sel.Ok() && sel.GetMask() && sel.GetMask()->GetPixmap() ) - { - XSetClipMask ((Display*) m_display, (GC) m_gc, (Pixmap) sel.GetMask()->GetPixmap()); - XSetClipOrigin ((Display*) m_display, (GC) m_gc, XLOG2DEV (xdest), YLOG2DEV (ydest)); - } - } + /* scale bitmap if required */ + wxBitmap use_bitmap; - XCopyRemote((Display*) sourceDC->m_display, (Display*) m_display, (Pixmap) sourcePixmap, (Pixmap) m_pixmap, (GC) m_gc, - source->LogicalToDeviceX (xsrc), - source->LogicalToDeviceY (ysrc), - source->LogicalToDeviceXRel(width), - source->LogicalToDeviceYRel(height), - XLOG2DEV (xdest), YLOG2DEV (ydest), - FALSE, &cache); + if ((bm_width != bm_ww) || (bm_height != bm_hh)) + { + wxImage image( memDC->m_selected ); + image = image.Scale( bm_ww, bm_hh ); - if ( useMask ) - { - XSetClipMask ((Display*) m_display, (GC) m_gc, None); - XSetClipOrigin ((Display*) m_display, (GC) m_gc, 0, 0); - } + if (is_mono) + use_bitmap = image.ConvertToMonoBitmap(255,255,255); + else + use_bitmap = image.ConvertToBitmap(); + } + else + { + use_bitmap = memDC->m_selected; + } + + /* apply mask if any */ + GdkBitmap *mask = (GdkBitmap *) NULL; + if (use_bitmap.GetMask()) mask = use_bitmap.GetMask()->GetBitmap(); - } else + if (useMask && mask) { - if ( useMask && source->IsKindOf(CLASSINFO(wxMemoryDC)) ) + GdkBitmap *new_mask = (GdkBitmap*) NULL; + if (!m_currentClippingRegion.IsNull()) { - wxMemoryDC *memDC = (wxMemoryDC *)source; - wxBitmap& sel = memDC->GetBitmap(); - if ( sel.Ok() && sel.GetMask() && sel.GetMask()->GetPixmap() ) - { - XSetClipMask ((Display*) m_display, (GC) m_gc, (Pixmap) sel.GetMask()->GetPixmap()); - XSetClipOrigin ((Display*) m_display, (GC) m_gc, XLOG2DEV (xdest), YLOG2DEV (ydest)); - } + GdkColor col; + new_mask = gdk_pixmap_new( wxGetRootWindow()->window, bm_ww, bm_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, bm_ww, bm_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, bm_ww, bm_hh ); + gdk_gc_unref( gc ); } - // Check if we're copying from a mono bitmap - if (source->IsKindOf(CLASSINFO(wxMemoryDC)) && - ((wxMemoryDC*)source)->GetBitmap().Ok() && (((wxMemoryDC*)source)->GetBitmap().GetDepth () == 1)) + if (is_mono) { - XCopyPlane ((Display*) m_display, (Pixmap) sourcePixmap, (Pixmap) m_pixmap, (GC) m_gc, - source->LogicalToDeviceX (xsrc), - source->LogicalToDeviceY (ysrc), - source->LogicalToDeviceXRel(width), - source->LogicalToDeviceYRel(height), - XLOG2DEV (xdest), YLOG2DEV (ydest), 1); + if (new_mask) + gdk_gc_set_clip_mask( m_textGC, new_mask ); + else + gdk_gc_set_clip_mask( m_textGC, mask ); + gdk_gc_set_clip_origin( m_textGC, xx, yy ); } else { - XCopyArea ((Display*) m_display, (Pixmap) sourcePixmap, (Pixmap) m_pixmap, (GC) m_gc, - source->LogicalToDeviceX (xsrc), - source->LogicalToDeviceY (ysrc), - source->LogicalToDeviceXRel(width), - source->LogicalToDeviceYRel(height), - XLOG2DEV (xdest), YLOG2DEV (ydest)); - - } - if ( useMask ) - { - XSetClipMask ((Display*) m_display, (GC) m_gc, None); - XSetClipOrigin ((Display*) m_display, (GC) m_gc, 0, 0); + if (new_mask) + gdk_gc_set_clip_mask( m_penGC, new_mask ); + else + gdk_gc_set_clip_mask( m_penGC, mask ); + gdk_gc_set_clip_origin( m_penGC, xx, yy ); } + if (new_mask) + gdk_bitmap_unref( new_mask ); + } - } /* Remote/local (Display*) m_display */ - CalcBoundingBox (xdest, ydest); - CalcBoundingBox (xdest + width, ydest + height); - - SetLogicalFunction(orig); - - if (scaledBitmap) delete scaledBitmap; - - return TRUE; - } - if (scaledBitmap) delete scaledBitmap; - - return FALSE; -} - -void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) -{ - wxCHECK_RET( Ok(), "invalid dc" ); - - // Since X draws from the baseline of the text, must add the text height - int cx = 0; - int cy = 0; - int ascent = 0; - int slen; - - slen = strlen(text); + /* Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For + drawing a mono-bitmap (XBitmap) we use the current text GC */ - if (m_font.Ok()) - { - WXFontStructPtr pFontStruct = m_font.GetFontStruct(m_userScaleY*m_logicalScaleY, m_display); - int direction, descent; - XCharStruct overall_return; -#if 0 - if (use16) - (void)XTextExtents16((XFontStruct*) pFontStruct, (XChar2b *)(const char*) text, slen, &direction, - &ascent, &descent, &overall_return); + if (is_mono) + gdk_wx_draw_bitmap( m_window, m_textGC, use_bitmap.GetBitmap(), xsrc, ysrc, xx, yy, ww, hh ); else -#endif // 0 - (void)XTextExtents((XFontStruct*) pFontStruct, (char*) (const char*) text, slen, &direction, - &ascent, &descent, &overall_return); + gdk_draw_pixmap( m_window, m_penGC, use_bitmap.GetPixmap(), xsrc, ysrc, xx, yy, ww, hh ); - cx = overall_return.width; - cy = ascent + descent; - } - - // First draw a rectangle representing the text background, if a text - // background is specified - if (m_textBackgroundColour.Ok () && (m_backgroundMode != wxTRANSPARENT)) - { - wxColour oldPenColour = m_currentColour; - m_currentColour = m_textBackgroundColour; - bool sameColour = (oldPenColour.Ok () && m_textBackgroundColour.Ok () && - (oldPenColour.Red () == m_textBackgroundColour.Red ()) && - (oldPenColour.Blue () == m_textBackgroundColour.Blue ()) && - (oldPenColour.Green () == m_textBackgroundColour.Green ())); - - // This separation of the big && test required for gcc2.7/HP UX 9.02 - // or pixel value can be corrupted! - sameColour = (sameColour && - (oldPenColour.GetPixel() == m_textBackgroundColour.GetPixel())); - - if (!sameColour || !GetOptimization()) + /* remove mask again if any */ + if (useMask && mask) { - int pixel = m_textBackgroundColour.AllocColour(m_display); - m_currentColour = m_textBackgroundColour; - - // Set the GC to the required colour - if (pixel > -1) + if (is_mono) + { + gdk_gc_set_clip_mask( m_textGC, (GdkBitmap *) NULL ); + gdk_gc_set_clip_origin( m_textGC, 0, 0 ); + if (!m_currentClippingRegion.IsNull()) + gdk_gc_set_clip_region( m_textGC, m_currentClippingRegion.GetRegion() ); + } + else { - XSetForeground ((Display*) m_display, (GC) m_gc, pixel); + gdk_gc_set_clip_mask( m_penGC, (GdkBitmap *) NULL ); + gdk_gc_set_clip_origin( m_penGC, 0, 0 ); + if (!m_currentClippingRegion.IsNull()) + gdk_gc_set_clip_region( m_penGC, m_currentClippingRegion.GetRegion() ); } } - else - m_textBackgroundColour = oldPenColour ; - - XFillRectangle ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, XLOG2DEV (x), YLOG2DEV (y), cx, cy); } - - // Now set the text foreground and draw the text - if (m_textForegroundColour.Ok ()) + else /* use_bitmap_method */ { - wxColour oldPenColour = m_currentColour; - m_currentColour = m_textForegroundColour; - bool sameColour = (oldPenColour.Ok () && m_currentColour.Ok () && - (oldPenColour.Red () == m_currentColour.Red ()) && - (oldPenColour.Blue () == m_currentColour.Blue ()) && - (oldPenColour.Green () == m_currentColour.Green ()) && - (oldPenColour.GetPixel() == m_currentColour.GetPixel())); - - if (!sameColour || !GetOptimization()) + if ((width != ww) || (height != hh)) { - int pixel = -1; - if (!m_colour) // Mono display - { - // Unless foreground is really white, draw it in black - unsigned char red = m_textForegroundColour.Red (); - unsigned char blue = m_textForegroundColour.Blue (); - unsigned char green = m_textForegroundColour.Green (); - if (red == (unsigned char) 255 && blue == (unsigned char) 255 - && green == (unsigned char) 255) - { - m_currentColour = *wxWHITE; - pixel = (int) WhitePixel ((Display*) m_display, DefaultScreen ((Display*) m_display)); - m_currentColour.SetPixel(pixel); - m_textForegroundColour.SetPixel(pixel); - } - else - { - m_currentColour = *wxBLACK; - pixel = (int) BlackPixel ((Display*) m_display, DefaultScreen ((Display*) m_display)); - m_currentColour.SetPixel(pixel); - m_textForegroundColour.SetPixel(pixel); - } - } - else - { - pixel = m_textForegroundColour.AllocColour((Display*) m_display); - m_currentColour.SetPixel(pixel); - } + /* draw source window into a bitmap as we cannot scale + a window in contrast to a bitmap. this would actually + work with memory dcs as well, but we'd lose the mask + information and waste one step in this process since + a memory already has a bitmap. all this is slightly + inefficient as we could take an XImage directly from + an X window, but we'd then also have to care that + the window is not outside the screen (in which case + we'd get a BadMatch or what not). + Is a double XGetImage and combined XGetPixel and + XPutPixel really faster? I'm not sure. look at wxXt + for a different implementation of the same problem. */ + + wxBitmap bitmap( width, height ); + + /* copy including child window contents */ + gdk_gc_set_subwindow( m_penGC, GDK_INCLUDE_INFERIORS ); + gdk_window_copy_area( bitmap.GetPixmap(), m_penGC, 0, 0, + srcDC->GetWindow(), + xsrc, ysrc, width, height ); + gdk_gc_set_subwindow( m_penGC, GDK_CLIP_BY_CHILDREN ); + + /* scale image */ + wxImage image( bitmap ); + image = image.Scale( ww, hh ); + + /* convert to bitmap */ + bitmap = image.ConvertToBitmap(); + + /* draw scaled bitmap */ + gdk_draw_pixmap( m_window, m_penGC, bitmap.GetPixmap(), 0, 0, xx, yy, -1, -1 ); - // Set the GC to the required colour - if (pixel > -1) - { - XSetForeground ((Display*) m_display, (GC) m_gc, pixel); - } } else - m_textForegroundColour = oldPenColour; + { + /* No scaling and not a memory dc with a mask either */ + + /* copy including child window contents */ + gdk_gc_set_subwindow( m_penGC, GDK_INCLUDE_INFERIORS ); + gdk_window_copy_area( m_window, m_penGC, xx, yy, + srcDC->GetWindow(), + xsrc, ysrc, width, height ); + gdk_gc_set_subwindow( m_penGC, GDK_CLIP_BY_CHILDREN ); + } } - // We need to add the ascent, not the whole height, since X draws at the - // point above the descender. -#if 0 - if (use16) - XDrawString16((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, XLOG2DEV (x), YLOG2DEV (y) + ascent, - (XChar2b *)(char*) (const char*) text, slen); - else -#endif // 0 - XDrawString((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, XLOG2DEV (x), YLOG2DEV (y) + ascent, text, slen); + SetLogicalFunction( old_logical_func ); + return TRUE; +#endif - wxCoord w, h; - GetTextExtent (text, &w, &h); - CalcBoundingBox (x + w, y + h); - CalcBoundingBox (x, y); + return FALSE; } -void wxWindowDC::DoDrawRotatedText( const wxString &text, wxCoord x, wxCoord y, double angle ) +void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) { - if (angle == 0.0) - { - DrawText(text, x, y); - return; - } + wxCHECK_RET( Ok(), wxT("invalid window dc") ); - wxCHECK_RET( Ok(), "invalid dc" ); + if (!m_window) return; - // Since X draws from the baseline of the text, must add the text height - int cx = 0; - int cy = 0; - int ascent = 0; - int slen; + XFontStruct *xfont = (XFontStruct*) m_font.GetFontStruct( m_scaleY, m_display ); - slen = strlen(text); + wxCHECK_RET( xfont, wxT("invalid font") ); - if (m_font.Ok()) - { - // Calculate text extent. - WXFontStructPtr pFontStruct = m_font.GetFontStruct(m_userScaleY*m_logicalScaleY, m_display); - int direction, descent; - XCharStruct overall_return; -#if 0 - if (use16) - (void)XTextExtents16((XFontStruct*) pFontStruct, (XChar2b *)(const char*) text, slen, &direction, - &ascent, &descent, &overall_return); - else -#endif // 0 - (void)XTextExtents((XFontStruct*) pFontStruct, (char*) (const char*) text, slen, &direction, - &ascent, &descent, &overall_return); + x = XLOG2DEV(x); + y = YLOG2DEV(y); - cx = overall_return.width; - cy = ascent + descent; - } +#if 0 + wxCoord width = gdk_string_width( font, text.mbc_str() ); + wxCoord height = font->ascent + font->descent; - wxBitmap src(cx, cy); - wxMemoryDC dc; - dc.SelectObject(src); - dc.SetFont(GetFont()); - dc.SetBackground(*wxWHITE_BRUSH); - dc.SetBrush(*wxBLACK_BRUSH); - dc.Clear(); - dc.DrawText(text, 0, 0); - dc.SetFont(wxNullFont); - - // Calculate the size of the rotated bounding box. - double dx = cos(angle / 180.0 * M_PI); - double dy = sin(angle / 180.0 * M_PI); - double x4 = -cy * dy; - double y4 = cy * dx; - double x3 = cx * dx; - double y3 = cx * dy; - double x2 = x3 + x4; - double y2 = y3 + y4; - double x1 = x; - double y1 = y; - - // Create image from the source bitmap after writing the text into it. - wxImage image(src); - - int minx = roundmin(0, roundmin(x4, roundmin(x2, x3))); - int miny = roundmin(0, roundmin(y4, roundmin(y2, y3))); - int maxx = roundmax(0, roundmax(x4, roundmax(x2, x3))); - int maxy = roundmax(0, roundmax(y4, roundmax(y2, y3))); - - // This rotates counterclockwise around the top left corner. - for (int rx = minx; rx < maxx; rx++) + if ( m_backgroundMode == wxSOLID ) { - for (int ry = miny; ry < maxy; ry++) - { - // transform dest coords to source coords - int sx = (int) (rx * dx + ry * dy + 0.5); - int sy = (int) (ry * dx - rx * dy + 0.5); - if (sx >= 0 && sx < cx && sy >= 0 && sy < cy) - { - // draw black pixels, ignore white ones (i.e. transparent b/g) - if (image.GetRed(sx, sy) == 0) - { - DrawPoint((wxCoord) (x1 + maxx - rx), (wxCoord) (cy + y1 - ry)); - } - else - { - // Background - //DrawPoint(x1 + maxx - rx, cy + y1 + maxy - ry); - } - } - } + gdk_gc_set_foreground( m_textGC, m_textBackgroundColour.GetColor() ); + gdk_draw_rectangle( m_window, m_textGC, TRUE, x, y, width, height ); + gdk_gc_set_foreground( m_textGC, m_textForegroundColour.GetColor() ); } +#endif + + XSetFont( (Display*) m_display, (GC) m_textGC, xfont->fid ); + if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0)) + { + XDrawString( (Display*) m_display, (Window) m_window, + (GC) m_textGC, x, y, text.c_str(), text.Len() ); + } #if 0 - // First draw a rectangle representing the text background, if a text - // background is specified - if (m_textBackgroundColour.Ok () && (m_backgroundMode != wxTRANSPARENT)) + if (m_font.GetUnderlined()) { - wxColour oldPenColour = m_currentColour; - m_currentColour = m_textBackgroundColour; - bool sameColour = (oldPenColour.Ok () && m_textBackgroundColour.Ok () && - (oldPenColour.Red () == m_textBackgroundColour.Red ()) && - (oldPenColour.Blue () == m_textBackgroundColour.Blue ()) && - (oldPenColour.Green () == m_textBackgroundColour.Green ())); - - // This separation of the big && test required for gcc2.7/HP UX 9.02 - // or pixel value can be corrupted! - sameColour = (sameColour && - (oldPenColour.GetPixel() == m_textBackgroundColour.GetPixel())); - - if (!sameColour || !GetOptimization()) - { - int pixel = m_textBackgroundColour.AllocColour(m_display); - m_currentColour = m_textBackgroundColour; - - // Set the GC to the required colour - if (pixel > -1) - { - XSetForeground ((Display*) m_display, (GC) m_gc, pixel); - } - } - else - m_textBackgroundColour = oldPenColour ; - - XFillRectangle ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, XLOG2DEV (x), YLOG2DEV (y), cx, cy); + wxCoord ul_y = y + font->ascent; + if (font->descent > 0) ul_y++; + gdk_draw_line( m_window, m_textGC, x, ul_y, x + width, ul_y); } -#endif - long w, h; - // XXX use pixmap size - GetTextExtent (text, &w, &h); - CalcBoundingBox (x + w, y + h); + width = wxCoord(width / m_scaleX); + height = wxCoord(height / m_scaleY); + + CalcBoundingBox (x + width, y + height); CalcBoundingBox (x, y); +#endif } -bool wxWindowDC::CanGetTextExtent() const +void wxWindowDC::DoDrawRotatedText( const wxString &text, wxCoord x, wxCoord y, double angle ) { - return TRUE; + // later } void wxWindowDC::DoGetTextExtent( const wxString &string, wxCoord *width, wxCoord *height, @@ -1156,121 +1272,95 @@ void wxWindowDC::DoGetTextExtent( const wxString &string, wxCoord *width, wxCoor { wxCHECK_RET( Ok(), "invalid dc" ); - wxFont* theFont = font; - if (!theFont) - theFont = (wxFont *)&m_font; // const_cast - - if (!theFont->Ok()) - { - // TODO: this should be an error log function - wxFAIL_MSG("set a valid font before calling GetTextExtent!"); + wxFont fontToUse = m_font; + if (font) fontToUse = *font; - if (width) *width = -1; - if (height) *height = -1; - return; - } + wxCHECK_RET( fontToUse.Ok(), "invalid font" ); - WXFontStructPtr pFontStruct = theFont->GetFontStruct(m_userScaleY*m_logicalScaleY, m_display); + XFontStruct *xfont = (XFontStruct*) fontToUse.GetFontStruct( m_scaleY, m_display ); + wxCHECK_RET( xfont, wxT("invalid font") ); + int direction, ascent, descent2; XCharStruct overall; - int slen; -#if 0 - if (use16) - slen = str16len(string); - else -#endif // 0 - slen = strlen(string); - -#if 0 - if (use16) - XTextExtents16((XFontStruct*) pFontStruct, (XChar2b *) (char*) (const char*) string, slen, &direction, - &ascent, &descent2, &overall); - else -#endif // 0 - XTextExtents((XFontStruct*) pFontStruct, (char*) (const char*) string, slen, &direction, + XTextExtents( xfont, string.c_str(), string.Len(), &direction, &ascent, &descent2, &overall); - if (width) *width = XDEV2LOGREL (overall.width); - if (height) *height = YDEV2LOGREL (ascent + descent2); + if (width) + *width = (wxCoord)( overall.width / m_scaleX ); + if (height) + *height = (wxCoord)((ascent + descent2) / m_scaleY ); if (descent) - *descent = descent2; + *descent = (wxCoord)(descent2 / m_scaleY ); if (externalLeading) - *externalLeading = 0; + *externalLeading = 0; // ?? } wxCoord wxWindowDC::GetCharWidth() const { wxCHECK_MSG( Ok(), 0, "invalid dc" ); + wxCHECK_MSG( m_font.Ok(), 0, "invalid font" ); - WXFontStructPtr pFontStruct = m_font.GetFontStruct(m_userScaleY * m_logicalScaleY, m_display); + XFontStruct *xfont = (XFontStruct*) m_font.GetFontStruct( m_scaleY, m_display ); + + wxCHECK_MSG( xfont, 0, wxT("invalid font") ); int direction, ascent, descent; XCharStruct overall; - XTextExtents ((XFontStruct*) pFontStruct, "x", 1, &direction, &ascent, - &descent, &overall); - return XDEV2LOGREL(overall.width); + + XTextExtents( xfont, "H", 1, &direction, &ascent, &descent, &overall ); + + return (wxCoord)(overall.width / m_scaleX); } wxCoord wxWindowDC::GetCharHeight() const { wxCHECK_MSG( Ok(), 0, "invalid dc" ); + wxCHECK_MSG( m_font.Ok(), 0, "invalid font" ); - WXFontStructPtr pFontStruct = m_font.GetFontStruct(m_userScaleY*m_logicalScaleY, m_display); + XFontStruct *xfont = (XFontStruct*) m_font.GetFontStruct( m_scaleY, m_display ); + + wxCHECK_MSG( xfont, 0, wxT("invalid font") ); int direction, ascent, descent; XCharStruct overall; - XTextExtents ((XFontStruct*) pFontStruct, "x", 1, &direction, &ascent, - &descent, &overall); - // return XDEV2LOGREL(overall.ascent + overall.descent); - return XDEV2LOGREL(ascent + descent); + + XTextExtents( xfont, "H", 1, &direction, &ascent, &descent, &overall ); + + return (wxCoord)((ascent+descent) / m_scaleY); } void wxWindowDC::Clear() { - wxCHECK_RET( Ok(), "invalid dc" ); + wxCHECK_RET( Ok(), wxT("invalid window dc") ); - int w, h; - if (m_window) - { - m_window->GetSize(&w, &h); - } - else - { - if (this->IsKindOf(CLASSINFO(wxMemoryDC))) - { - wxMemoryDC* memDC = (wxMemoryDC*) this; - w = memDC->GetBitmap().GetWidth(); - h = memDC->GetBitmap().GetHeight(); - } - else - return; - } + if (!m_window) return; - wxBrush saveBrush = m_brush; - SetBrush (m_backgroundBrush); + /* - we either are a memory dc or have a window as the + owner. anything else shouldn't happen. + - we don't use gdk_window_clear() as we don't set + the window's background colour anymore. it is too + much pain to keep the DC's and the window's back- + ground colour in synch. */ - XFillRectangle ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, 0, 0, w, h); - - m_brush = saveBrush; -} - -void wxWindowDC::Clear(const wxRect& rect) -{ - wxCHECK_RET( Ok(), "invalid dc" ); - - int x = rect.x; int y = rect.y; - int w = rect.width; int h = rect.height; - - wxBrush saveBrush = m_brush; - SetBrush (m_backgroundBrush); - - XFillRectangle ((Display*) m_display, (Pixmap) m_pixmap, (GC) m_gc, x, y, w, h); + if (m_owner) + { + int width,height; + m_owner->GetSize( &width, &height ); + XFillRectangle( (Display*) m_display, (Window) m_window, (GC) m_bgGC, 0, 0, width, height ); + return; + } - m_brush = saveBrush; + if (m_isMemDC) + { + int width,height; + GetSize( &width, &height ); + XFillRectangle( (Display*) m_display, (Window) m_window, (GC) m_bgGC, 0, 0, width, height ); + return; + } } void wxWindowDC::SetFont( const wxFont &font ) @@ -1278,496 +1368,223 @@ void wxWindowDC::SetFont( const wxFont &font ) wxCHECK_RET( Ok(), "invalid dc" ); m_font = font; - - if (!m_font.Ok()) - { - if ((m_oldFont != (WXFont) 0) && ((wxCoord) m_oldFont != -1)) - { - XSetFont ((Display*) m_display, (GC) m_gc, (Font) m_oldFont); - } - return; - } - - WXFontStructPtr pFontStruct = m_font.GetFontStruct(m_userScaleY*m_logicalScaleY, m_display); - - Font fontId = ((XFontStruct*)pFontStruct)->fid; - XSetFont ((Display*) m_display, (GC) m_gc, fontId); } void wxWindowDC::SetPen( const wxPen &pen ) { - wxCHECK_RET( Ok(), "invalid dc" ); + wxCHECK_RET( Ok(), wxT("invalid window dc") ); + + if (m_pen == pen) return; m_pen = pen; - if (!m_pen.Ok()) - return; - wxBitmap oldStipple = m_currentStipple; - int oldStyle = m_currentStyle; - int oldFill = m_currentFill; - int old_pen_width = m_currentPenWidth; - int old_pen_join = m_currentPenJoin; - int old_pen_cap = m_currentPenCap; - int old_pen_nb_dash = m_currentPenDashCount; - wxX11Dash *old_pen_dash = m_currentPenDash; - - wxColour oldPenColour = m_currentColour; - m_currentColour = m_pen.GetColour (); - m_currentStyle = m_pen.GetStyle (); - m_currentFill = m_pen.GetStyle (); // TODO? - m_currentPenWidth = m_pen.GetWidth (); - m_currentPenJoin = m_pen.GetJoin (); - m_currentPenCap = m_pen.GetCap (); - m_currentPenDashCount = m_pen.GetDashCount(); - m_currentPenDash = (wxX11Dash*)m_pen.GetDash(); + if (!m_pen.Ok()) return; -#if 0 - // TODO - if (m_currentStyle == wxSTIPPLE) - m_currentStipple = * m_pen.GetStipple (); -#endif + if (!m_window) return; - bool sameStyle = (oldStyle == m_currentStyle && - oldFill == m_currentFill && - old_pen_join == m_currentPenJoin && - old_pen_cap == m_currentPenCap && - old_pen_nb_dash == m_currentPenDashCount && - old_pen_dash == m_currentPenDash && - old_pen_width == m_currentPenWidth); - - bool sameColour = (oldPenColour.Ok () && - (oldPenColour.Red () == m_currentColour.Red ()) && - (oldPenColour.Blue () == m_currentColour.Blue ()) && - (oldPenColour.Green () == m_currentColour.Green ()) && - (oldPenColour.GetPixel() == m_currentColour.GetPixel())); - - if (!sameStyle || !GetOptimization()) + int width = m_pen.GetWidth(); + if (width <= 0) + { + // CMB: if width is non-zero scale it with the dc + width = 1; + } + else + { + // X doesn't allow different width in x and y and so we take + // the average + double w = 0.5 + + ( fabs((double) XLOG2DEVREL(width)) + + fabs((double) YLOG2DEVREL(width)) ) / 2.0; + width = (int)w; + } + + static const wxX11Dash dotted[] = {1, 1}; + static const wxX11Dash short_dashed[] = {2, 2}; + static const wxX11Dash long_dashed[] = {2, 4}; + static const wxX11Dash dotted_dashed[] = {3, 3, 1, 3}; + + // We express dash pattern in pen width unit, so we are + // independent of zoom factor and so on... + int req_nb_dash; + const wxX11Dash *req_dash; + + int lineStyle = LineSolid; + switch (m_pen.GetStyle()) { - int scaled_width = (int) XLOG2DEVREL (m_pen.GetWidth ()); - if (scaled_width < 0) - scaled_width = 0; - - int style; - int join; - int cap; - static const wxX11Dash dotted[] = {2, 5}; - static const wxX11Dash short_dashed[] = {4, 4}; - static const wxX11Dash long_dashed[] = {4, 8}; - static const wxX11Dash dotted_dashed[] = {6, 6, 2, 6}; - - // We express dash pattern in pen width unit, so we are - // independent of zoom factor and so on... - int req_nb_dash; - const wxX11Dash *req_dash; - - switch (m_pen.GetStyle ()) - { case wxUSER_DASH: - req_nb_dash = m_currentPenDashCount; - req_dash = m_currentPenDash; - style = LineOnOffDash; + { + lineStyle = LineOnOffDash; + req_nb_dash = m_pen.GetDashCount(); + req_dash = (wxX11Dash*)m_pen.GetDash(); break; + } case wxDOT: + { + lineStyle = LineOnOffDash; req_nb_dash = 2; req_dash = dotted; - style = LineOnOffDash; - break; - case wxSHORT_DASH: - req_nb_dash = 2; - req_dash = short_dashed; - style = LineOnOffDash; break; + } case wxLONG_DASH: + { + lineStyle = LineOnOffDash; req_nb_dash = 2; req_dash = long_dashed; - style = LineOnOffDash; break; + } + case wxSHORT_DASH: + { + lineStyle = LineOnOffDash; + req_nb_dash = 2; + req_dash = short_dashed; + break; + } case wxDOT_DASH: + { +// lineStyle = LineDoubleDash; + lineStyle = LineOnOffDash; req_nb_dash = 4; req_dash = dotted_dashed; - style = LineOnOffDash; break; + } + + case wxTRANSPARENT: + case wxSTIPPLE_MASK_OPAQUE: case wxSTIPPLE: case wxSOLID: - case wxTRANSPARENT: default: - style = LineSolid; + { + lineStyle = LineSolid; req_dash = (wxX11Dash*)NULL; req_nb_dash = 0; + break; } + } - if (req_dash && req_nb_dash) + int capStyle = CapRound; + switch (m_pen.GetCap()) + { + case wxCAP_PROJECTING: { capStyle = CapProjecting; break; } + case wxCAP_BUTT: { capStyle = CapButt; break; } + case wxCAP_ROUND: + default: { - wxX11Dash *real_req_dash = new wxX11Dash[req_nb_dash]; - if (real_req_dash) + if (width <= 1) { - int factor = scaled_width == 0 ? 1 : scaled_width; - for (int i = 0; i < req_nb_dash; i++) - real_req_dash[i] = req_dash[i] * factor; - XSetDashes ((Display*) m_display, (GC) m_gc, 0, real_req_dash, req_nb_dash); - delete[]real_req_dash; + width = 0; + capStyle = CapNotLast; } else { - // No Memory. We use non-scaled dash pattern... - XSetDashes ((Display*) m_display, (GC) m_gc, 0, req_dash, req_nb_dash); + capStyle = CapRound; } - } - - switch (m_pen.GetCap ()) - { - case wxCAP_PROJECTING: - cap = CapProjecting; - break; - case wxCAP_BUTT: - cap = CapButt; - break; - case wxCAP_ROUND: - default: - cap = (scaled_width <= 1) ? CapNotLast : CapRound; break; } + } - switch (m_pen.GetJoin ()) - { - case wxJOIN_BEVEL: - join = JoinBevel; - break; - case wxJOIN_MITER: - join = JoinMiter; - break; + int joinStyle = JoinRound; + switch (m_pen.GetJoin()) + { + case wxJOIN_BEVEL: { joinStyle = JoinBevel; break; } + case wxJOIN_MITER: { joinStyle = JoinMiter; break; } case wxJOIN_ROUND: - default: - join = JoinRound; - break; - } - - XSetLineAttributes ((Display*) m_display, (GC) m_gc, scaled_width, style, cap, join); + default: { joinStyle = JoinRound; break; } } - if (IS_HATCH(m_currentFill) && ((m_currentFill != oldFill) || !GetOptimization())) - { - Pixmap myStipple; + XSetLineAttributes( (Display*) m_display, (GC) m_penGC, width, lineStyle, capStyle, joinStyle ); - oldStipple = wxNullBitmap; // For later reset!! + m_pen.GetColour().CalcPixel( m_cmap ); + XSetForeground( (Display*) m_display, (GC) m_penGC, m_pen.GetColour().GetPixel() ); +} - switch (m_currentFill) - { - case wxBDIAGONAL_HATCH: - if (bdiag == (Pixmap) 0) - bdiag = XCreateBitmapFromData ((Display*) m_display, - RootWindow ((Display*) m_display, DefaultScreen ((Display*) m_display)), - bdiag_bits, bdiag_width, bdiag_height); - myStipple = bdiag; - break; - case wxFDIAGONAL_HATCH: - if (fdiag == (Pixmap) 0) - fdiag = XCreateBitmapFromData ((Display*) m_display, - RootWindow ((Display*) m_display, DefaultScreen ((Display*) m_display)), - fdiag_bits, fdiag_width, fdiag_height); - myStipple = fdiag; - break; - case wxCROSS_HATCH: - if (cross == (Pixmap) 0) - cross = XCreateBitmapFromData ((Display*) m_display, - RootWindow ((Display*) m_display, DefaultScreen ((Display*) m_display)), - cross_bits, cross_width, cross_height); - myStipple = cross; - break; - case wxHORIZONTAL_HATCH: - if (horiz == (Pixmap) 0) - horiz = XCreateBitmapFromData ((Display*) m_display, - RootWindow ((Display*) m_display, DefaultScreen ((Display*) m_display)), - horiz_bits, horiz_width, horiz_height); - myStipple = horiz; - break; - case wxVERTICAL_HATCH: - if (verti == (Pixmap) 0) - verti = XCreateBitmapFromData ((Display*) m_display, - RootWindow ((Display*) m_display, DefaultScreen ((Display*) m_display)), - verti_bits, verti_width, verti_height); - myStipple = verti; - break; - case wxCROSSDIAG_HATCH: - default: - if (cdiag == (Pixmap) 0) - cdiag = XCreateBitmapFromData ((Display*) m_display, - RootWindow ((Display*) m_display, DefaultScreen ((Display*) m_display)), - cdiag_bits, cdiag_width, cdiag_height); - myStipple = cdiag; - break; - } - XSetStipple ((Display*) m_display, (GC) m_gc, myStipple); - } - else if (m_currentStipple.Ok() - && ((m_currentStipple != oldStipple) || !GetOptimization())) - { - XSetStipple ((Display*) m_display, (GC) m_gc, (Pixmap) m_currentStipple.GetPixmap()); - } +void wxWindowDC::SetBrush( const wxBrush &brush ) +{ + wxCHECK_RET( Ok(), wxT("invalid window dc") ); - if ((m_currentFill != oldFill) || !GetOptimization()) - { - int fill_style; + if (m_brush == brush) return; - if (m_currentFill == wxSTIPPLE) - fill_style = FillStippled; - else if (IS_HATCH (m_currentFill)) - fill_style = FillStippled; - else - fill_style = FillSolid; - XSetFillStyle ((Display*) m_display, (GC) m_gc, fill_style); - } + m_brush = brush; + + if (!m_brush.Ok()) return; - // must test m_logicalFunction, because it involves background! - if (!sameColour || !GetOptimization() - || ((m_logicalFunction == wxXOR) || (m_autoSetting & 0x2))) + if (!m_window) return; + + 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())) { - int pixel = -1; - if (m_pen.GetStyle () == wxTRANSPARENT) - pixel = m_backgroundPixel; - else if (!m_colour) + if (m_brush.GetStipple()->GetPixmap()) { - unsigned char red = m_pen.GetColour ().Red (); - unsigned char blue = m_pen.GetColour ().Blue (); - unsigned char green = m_pen.GetColour ().Green (); - if (red == (unsigned char) 255 && blue == (unsigned char) 255 - && green == (unsigned char) 255) - { - pixel = (int) WhitePixel ((Display*) m_display, DefaultScreen ((Display*) m_display)); - m_currentColour = *wxWHITE; - m_pen.GetColour().SetPixel(pixel); - m_currentColour.SetPixel(pixel); - } - else - { - pixel = (int) BlackPixel ((Display*) m_display, DefaultScreen ((Display*) m_display)); - m_currentColour = *wxBLACK; - m_pen.GetColour().SetPixel(pixel); - } + XSetFillStyle( (Display*) m_display, (GC) m_brushGC, FillTiled ); + XSetTile( (Display*) m_display, (GC) m_brushGC, (Pixmap) m_brush.GetStipple()->GetPixmap() ); } else { - pixel = m_pen.GetColour ().AllocColour(m_display); - m_currentColour.SetPixel(pixel); + XSetFillStyle( (Display*) m_display, (GC) m_brushGC, FillStippled ); +// XSetStipple( (Display*) m_display, (GC) m_brushGC, (Pixmap) m_brush.GetStipple()->GetBitmap() ); } + } - // Finally, set the GC to the required colour - if (pixel > -1) - { - if (m_logicalFunction == wxXOR) - { - XGCValues values; - XGetGCValues ((Display*) m_display, (GC) m_gc, GCBackground, &values); - XSetForeground ((Display*) m_display, (GC) m_gc, pixel ^ values.background); - } - else - { - XSetForeground ((Display*) m_display, (GC) m_gc, pixel); - } - } + if ((m_brush.GetStyle() == wxSTIPPLE_MASK_OPAQUE) && (m_brush.GetStipple()->GetMask())) + { + XSetFillStyle( (Display*) m_display, (GC) m_textGC, FillOpaqueStippled ); +// XSetStipple( (Display*) m_display, (GC) m_textGC, (Pixmap) m_brush.GetStipple()->GetMask()->GetBitmap() ); } - else - m_pen.GetColour().SetPixel(oldPenColour.GetPixel()); - m_autoSetting = 0; + if (IS_HATCH(m_brush.GetStyle())) + { + XSetFillStyle( (Display*) m_display, (GC) m_brushGC, FillStippled ); + int num = m_brush.GetStyle() - wxBDIAGONAL_HATCH; + XSetStipple( (Display*) m_display, (GC) m_brushGC, hatches[num] ); + } } -void wxWindowDC::SetBrush( const wxBrush &brush ) +void wxWindowDC::SetBackground( const wxBrush &brush ) { - wxCHECK_RET( Ok(), "invalid dc" ); + /* CMB 21/7/98: Added SetBackground. Sets background brush + * for Clear() and bg colour for shapes filled with cross-hatch brush */ - m_brush = brush; + wxCHECK_RET( Ok(), wxT("invalid window dc") ); - if (!m_brush.Ok() || m_brush.GetStyle () == wxTRANSPARENT) - return; + if (m_backgroundBrush == brush) return; - int oldFill = m_currentFill; - wxBitmap oldStipple = m_currentStipple; + m_backgroundBrush = brush; - m_autoSetting |= 0x1; + if (!m_backgroundBrush.Ok()) return; - m_currentFill = m_brush.GetStyle (); - if (m_currentFill == wxSTIPPLE) - m_currentStipple = * m_brush.GetStipple (); + if (!m_window) return; - wxColour oldBrushColour(m_currentColour); - m_currentColour = m_brush.GetColour (); + m_backgroundBrush.GetColour().CalcPixel( m_cmap ); + XSetBackground( (Display*) m_display, (GC) m_brushGC, m_backgroundBrush.GetColour().GetPixel() ); + XSetBackground( (Display*) m_display, (GC) m_penGC, m_backgroundBrush.GetColour().GetPixel() ); + XSetBackground( (Display*) m_display, (GC) m_bgGC, m_backgroundBrush.GetColour().GetPixel() ); + XSetForeground( (Display*) m_display, (GC) m_bgGC, m_backgroundBrush.GetColour().GetPixel() ); - bool sameColour = (oldBrushColour.Ok () && - (oldBrushColour.Red () == m_currentColour.Red ()) && - (oldBrushColour.Blue () == m_currentColour.Blue ()) && - (oldBrushColour.Green () == m_currentColour.Green ()) && - (oldBrushColour.GetPixel() == m_currentColour.GetPixel())); + XSetFillStyle( (Display*) m_display, (GC) m_bgGC, FillSolid ); - if ((oldFill != m_brush.GetStyle ()) || !GetOptimization()) + if ((m_backgroundBrush.GetStyle() == wxSTIPPLE) && (m_backgroundBrush.GetStipple()->Ok())) { - switch (brush.GetStyle ()) + if (m_backgroundBrush.GetStipple()->GetPixmap()) { - case wxTRANSPARENT: - break; - case wxBDIAGONAL_HATCH: - case wxCROSSDIAG_HATCH: - case wxFDIAGONAL_HATCH: - case wxCROSS_HATCH: - case wxHORIZONTAL_HATCH: - case wxVERTICAL_HATCH: - case wxSTIPPLE: - { - // Chris Breeze 23/07/97: use background mode to determine whether - // fill style should be solid or transparent - int style = (m_backgroundMode == wxSOLID ? FillOpaqueStippled : FillStippled); - XSetFillStyle ((Display*) m_display, (GC) m_gc, style); - } - break; - case wxSOLID: - default: - XSetFillStyle ((Display*) m_display, (GC) m_gc, FillSolid); + XSetFillStyle( (Display*) m_display, (GC) m_bgGC, FillTiled ); + XSetTile( (Display*) m_display, (GC) m_bgGC, (Pixmap) m_backgroundBrush.GetStipple()->GetPixmap() ); } - } - - if (IS_HATCH(m_currentFill) && ((m_currentFill != oldFill) || !GetOptimization())) - { - Pixmap myStipple; - - switch (m_currentFill) + else { - case wxBDIAGONAL_HATCH: - if (bdiag == (Pixmap) 0) - bdiag = XCreateBitmapFromData ((Display*) m_display, - RootWindow ((Display*) m_display, DefaultScreen ((Display*) m_display)), - bdiag_bits, bdiag_width, bdiag_height); - myStipple = bdiag; - break; - case wxFDIAGONAL_HATCH: - if (fdiag == (Pixmap) 0) - fdiag = XCreateBitmapFromData ((Display*) m_display, - RootWindow ((Display*) m_display, DefaultScreen ((Display*) m_display)), - fdiag_bits, fdiag_width, fdiag_height); - myStipple = fdiag; - break; - case wxCROSS_HATCH: - if (cross == (Pixmap) 0) - cross = XCreateBitmapFromData ((Display*) m_display, - RootWindow ((Display*) m_display, DefaultScreen ((Display*) m_display)), - cross_bits, cross_width, cross_height); - myStipple = cross; - break; - case wxHORIZONTAL_HATCH: - if (horiz == (Pixmap) 0) - horiz = XCreateBitmapFromData ((Display*) m_display, - RootWindow ((Display*) m_display, DefaultScreen ((Display*) m_display)), - horiz_bits, horiz_width, horiz_height); - myStipple = horiz; - break; - case wxVERTICAL_HATCH: - if (verti == (Pixmap) 0) - verti = XCreateBitmapFromData ((Display*) m_display, - RootWindow ((Display*) m_display, DefaultScreen ((Display*) m_display)), - verti_bits, verti_width, verti_height); - myStipple = verti; - break; - case wxCROSSDIAG_HATCH: - default: - if (cdiag == (Pixmap) 0) - cdiag = XCreateBitmapFromData ((Display*) m_display, - RootWindow ((Display*) m_display, DefaultScreen ((Display*) m_display)), - cdiag_bits, cdiag_width, cdiag_height); - myStipple = cdiag; - break; + XSetFillStyle( (Display*) m_display, (GC) m_bgGC, FillStippled ); +// XSetStipple( (Display*) m_display, (GC) m_bgGC, (Pixmap) m_backgroundBrush.GetStipple()->GetBitmap() ); } - XSetStipple ((Display*) m_display, (GC) m_gc, myStipple); - } - // X can forget the stipple value when resizing a window (apparently) - // so always set the stipple. - else if (m_currentStipple.Ok()) // && m_currentStipple != oldStipple) - { - XSetStipple ((Display*) m_display, (GC) m_gc, (Pixmap) m_currentStipple.GetPixmap()); } - // must test m_logicalFunction, because it involves background! - if (!sameColour || !GetOptimization() || m_logicalFunction == wxXOR) + if (IS_HATCH(m_backgroundBrush.GetStyle())) { - int pixel = -1; - if (!m_colour) - { - // Policy - on a monochrome screen, all brushes are white, - // except when they're REALLY black!!! - unsigned char red = m_brush.GetColour ().Red (); - unsigned char blue = m_brush.GetColour ().Blue (); - unsigned char green = m_brush.GetColour ().Green (); - - if (red == (unsigned char) 0 && blue == (unsigned char) 0 - && green == (unsigned char) 0) - { - pixel = (int) BlackPixel ((Display*) m_display, DefaultScreen ((Display*) m_display)); - m_currentColour = *wxBLACK; - m_brush.GetColour().SetPixel(pixel); - m_currentColour.SetPixel(pixel); - } - else - { - pixel = (int) WhitePixel ((Display*) m_display, DefaultScreen ((Display*) m_display)); - m_currentColour = *wxWHITE; - m_brush.GetColour().SetPixel(pixel); - m_currentColour.SetPixel(pixel); - } - - // N.B. comment out the above line and uncomment the following lines - // if you want non-white colours to be black on a monochrome display. - /* - if (red == (unsigned char )255 && blue == (unsigned char)255 - && green == (unsigned char)255) - pixel = (int)WhitePixel((Display*) m_display, DefaultScreen((Display*) m_display)); - else - pixel = (int)BlackPixel((Display*) m_display, DefaultScreen((Display*) m_display)); - */ - } - else if (m_brush.GetStyle () != wxTRANSPARENT) - { - pixel = m_brush.GetColour().AllocColour(m_display); - m_currentColour.SetPixel(pixel); - } - if (pixel > -1) - { - // Finally, set the GC to the required colour - if (m_logicalFunction == wxXOR) - { - XGCValues values; - XGetGCValues ((Display*) m_display, (GC) m_gc, GCBackground, &values); - XSetForeground ((Display*) m_display, (GC) m_gc, pixel ^ values.background); - } - else - { - XSetForeground ((Display*) m_display, (GC) m_gc, pixel); - } - } + XSetFillStyle( (Display*) m_display, (GC) m_bgGC, FillStippled ); + int num = m_backgroundBrush.GetStyle() - wxBDIAGONAL_HATCH; + XSetStipple( (Display*) m_display, (GC) m_bgGC, hatches[num] ); } - else - m_brush.GetColour().SetPixel(oldBrushColour.GetPixel()); -} - -void wxWindowDC::SetBackground( const wxBrush &brush ) -{ - wxCHECK_RET( Ok(), "invalid dc" ); - - m_backgroundBrush = brush; - - if (!m_backgroundBrush.Ok()) - return; - - int pixel = m_backgroundBrush.GetColour().AllocColour(m_display); - - // New behaviour, 10/2/99: setting the background brush of a DC - // doesn't affect the window background colour. -/* - // XSetWindowBackground doesn't work for non-Window pixmaps - if (!this->IsKindOf(CLASSINFO(wxMemoryDC))) - XSetWindowBackground ((Display*) m_display, (Pixmap) m_pixmap, pixel); -*/ - - // Necessary for ::DrawIcon, which use fg/bg pixel or the GC. - // And Blit,... (Any fct that use XCopyPlane, in fact.) - XSetBackground ((Display*) m_display, (GC) m_gc, pixel); } void wxWindowDC::SetLogicalFunction( int function ) @@ -1776,10 +1593,13 @@ void wxWindowDC::SetLogicalFunction( int function ) int x_function; - /* MATTHEW: [9] */ if (m_logicalFunction == function) return; + // VZ: shouldn't this be a CHECK? + if (!m_window) + return; + switch (function) { case wxCLEAR: @@ -1833,46 +1653,74 @@ void wxWindowDC::SetLogicalFunction( int function ) break; } - XSetFunction((Display*) m_display, (GC) m_gc, x_function); - - if ((m_logicalFunction == wxXOR) != (function == wxXOR)) - /* MATTHEW: [9] Need to redo pen simply */ - m_autoSetting |= 0x2; + XSetFunction( (Display*) m_display, (GC) m_penGC, x_function ); + XSetFunction( (Display*) m_display, (GC) m_brushGC, x_function ); + // to stay compatible with wxMSW, we don't apply ROPs to the text + // 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; - } void wxWindowDC::SetTextForeground( const wxColour &col ) { - wxCHECK_RET( Ok(), "invalid dc" ); + wxCHECK_RET( Ok(), wxT("invalid window dc") ); - if (m_textForegroundColour == col) + // don't set m_textForegroundColour to an invalid colour as we'd crash + // later then (we use m_textForegroundColour.GetColor() without checking + // in a few places) + if ( !col.Ok() || (m_textForegroundColour == col) ) return; m_textForegroundColour = col; + if (m_window) + { + m_textForegroundColour.CalcPixel( m_cmap ); + XSetForeground( (Display*) m_display, (GC) m_textGC, m_textForegroundColour.GetPixel() ); + } } void wxWindowDC::SetTextBackground( const wxColour &col ) { - wxCHECK_RET( Ok(), "invalid dc" ); + wxCHECK_RET( Ok(), wxT("invalid window dc") ); - if (m_textBackgroundColour == col) + // same as above + if ( !col.Ok() || (m_textBackgroundColour == col) ) return; m_textBackgroundColour = col; - if (!m_textBackgroundColour.Ok()) - return; + + if (m_window) + { + m_textBackgroundColour.CalcPixel( m_cmap ); + XSetBackground( (Display*) m_display, (GC) m_textGC, m_textBackgroundColour.GetPixel() ); + } } void wxWindowDC::SetBackgroundMode( int mode ) { + wxCHECK_RET( Ok(), wxT("invalid window dc") ); + m_backgroundMode = mode; + + if (!m_window) return; + + // CMB 21/7/98: fill style of cross-hatch brushes is affected by + // transparent/solid background mode + + if (m_brush.GetStyle() != wxSOLID && m_brush.GetStyle() != wxTRANSPARENT) + { + XSetFillStyle( (Display*) m_display, (GC) m_brushGC, + (m_backgroundMode == wxTRANSPARENT) ? FillStippled : FillOpaqueStippled ); + } } void wxWindowDC::SetPalette( const wxPalette& palette ) { +#if 0 if (m_window) { if (palette.Ok()) @@ -1884,92 +1732,136 @@ void wxWindowDC::SetPalette( const wxPalette& palette ) XSetWindowColormap ((Display*) m_display, (Window) m_window->GetXWindow(), (Colormap) wxTheApp->GetMainColormap(m_display)); } +#endif } -// Helper function -void wxWindowDC::SetDCClipping() +void wxWindowDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) { - // m_userRegion is the region set by calling SetClippingRegion + wxCHECK_RET( Ok(), wxT("invalid window dc") ); - if (m_currentRegion) - XDestroyRegion ((Region) m_currentRegion); + if (!m_window) return; - // We need to take into account - // clipping imposed on a window by a repaint. - // We'll combine it with the user region. But for now, - // just use the currently-defined user clipping region. - if (m_userRegion || (m_window && m_window->GetUpdateRegion().Ok()) ) - m_currentRegion = (WXRegion) XCreateRegion (); + wxRect rect; + rect.x = XLOG2DEV(x); + rect.y = YLOG2DEV(y); + rect.width = XLOG2DEVREL(width); + rect.height = YLOG2DEVREL(height); + + if (!m_currentClippingRegion.IsNull()) + m_currentClippingRegion.Intersect( rect ); else - m_currentRegion = (WXRegion) NULL; + m_currentClippingRegion.Union( rect ); + +#if USE_PAINT_REGION + if (!m_paintClippingRegion.IsNull()) + m_currentClippingRegion.Intersect( m_paintClippingRegion ); +#endif + + wxCoord xx, yy, ww, hh; + m_currentClippingRegion.GetBox( xx, yy, ww, hh ); + wxDC::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() ); + XSetRegion( (Display*) m_display, (GC) m_textGC, (Region) m_currentClippingRegion.GetX11Region() ); + XSetRegion( (Display*) m_display, (GC) m_bgGC, (Region) m_currentClippingRegion.GetX11Region() ); +} - if ((m_window && m_window->GetUpdateRegion().Ok()) && m_userRegion) - XIntersectRegion ((Region) m_window->GetUpdateRegion().GetX11Region(), (Region) m_userRegion, (Region) m_currentRegion); - else if (m_userRegion) - XIntersectRegion ((Region) m_userRegion, (Region) m_userRegion, (Region) m_currentRegion); - else if (m_window && m_window->GetUpdateRegion().Ok()) - XIntersectRegion ((Region) m_window->GetUpdateRegion().GetX11Region(), (Region) m_window->GetUpdateRegion().GetX11Region(), - (Region) m_currentRegion); +void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion& region ) +{ + wxCHECK_RET( Ok(), wxT("invalid window dc") ); - if (m_currentRegion) + if (region.Empty()) { - XSetRegion ((Display*) m_display, (GC) m_gc, (Region) m_currentRegion); + DestroyClippingRegion(); + return; } + + if (!m_window) return; + + if (!m_currentClippingRegion.IsNull()) + m_currentClippingRegion.Intersect( region ); else - { - XSetClipMask ((Display*) m_display, (GC) m_gc, None); - } + m_currentClippingRegion.Union( region ); -} +#if USE_PAINT_REGION + if (!m_paintClippingRegion.IsNull()) + m_currentClippingRegion.Intersect( m_paintClippingRegion ); +#endif -void wxWindowDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) -{ - wxDC::DoSetClippingRegion( x, y, width, height ); - - if (m_userRegion) - XDestroyRegion ((Region) m_userRegion); - m_userRegion = (WXRegion) XCreateRegion (); - XRectangle r; - r.x = XLOG2DEV (x); - r.y = YLOG2DEV (y); - r.width = XLOG2DEVREL(width); - r.height = YLOG2DEVREL(height); - XUnionRectWithRegion (&r, (Region) m_userRegion, (Region) m_userRegion); - - SetDCClipping (); + wxCoord xx, yy, ww, hh; + m_currentClippingRegion.GetBox( xx, yy, ww, hh ); + wxDC::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() ); + XSetRegion( (Display*) m_display, (GC) m_textGC, (Region) m_currentClippingRegion.GetX11Region() ); + XSetRegion( (Display*) m_display, (GC) m_bgGC, (Region) m_currentClippingRegion.GetX11Region() ); } -void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion& region ) +void wxWindowDC::DestroyClippingRegion() { - wxRect box = region.GetBox(); + wxCHECK_RET( Ok(), wxT("invalid window dc") ); - wxDC::DoSetClippingRegion( box.x, box.y, box.width, box.height ); + wxDC::DestroyClippingRegion(); - if (m_userRegion) - XDestroyRegion ((Region) m_userRegion); - m_userRegion = (WXRegion) XCreateRegion (); + m_currentClippingRegion.Clear(); - XUnionRegion((Region) m_userRegion, (Region) region.GetX11Region(), (Region) m_userRegion); +#if USE_PAINT_REGION + if (!m_paintClippingRegion.IsEmpty()) + m_currentClippingRegion.Union( m_paintClippingRegion ); +#endif - SetDCClipping (); -} + if (!m_window) return; + if (m_currentClippingRegion.IsEmpty()) + { + XSetClipMask( (Display*) m_display, (GC) m_penGC, None ); + XSetClipMask( (Display*) m_display, (GC) m_brushGC, None ); + XSetClipMask( (Display*) m_display, (GC) m_textGC, None ); + XSetClipMask( (Display*) m_display, (GC) m_bgGC, None ); + } + else + { + XSetRegion( (Display*) m_display, (GC) m_penGC, (Region) m_currentClippingRegion.GetX11Region() ); + XSetRegion( (Display*) m_display, (GC) m_brushGC, (Region) m_currentClippingRegion.GetX11Region() ); + XSetRegion( (Display*) m_display, (GC) m_textGC, (Region) m_currentClippingRegion.GetX11Region() ); + XSetRegion( (Display*) m_display, (GC) m_bgGC, (Region) m_currentClippingRegion.GetX11Region() ); + } +} -void wxWindowDC::DestroyClippingRegion() +void wxWindowDC::Destroy() { - wxDC::DestroyClippingRegion(); + if (m_penGC) wxFreePoolGC( (GC) m_penGC ); + m_penGC = NULL; + if (m_brushGC) wxFreePoolGC( (GC) m_brushGC ); + m_brushGC = NULL; + if (m_textGC) wxFreePoolGC( (GC) m_textGC ); + m_textGC = NULL; + if (m_bgGC) wxFreePoolGC( (GC) m_bgGC ); + m_bgGC = NULL; +} - if (m_userRegion) - XDestroyRegion ((Region) m_userRegion); - m_userRegion = NULL; +void wxWindowDC::ComputeScaleAndOrigin() +{ + /* CMB: copy scale to see if it changes */ + double origScaleX = m_scaleX; + double origScaleY = m_scaleY; - SetDCClipping (); + wxDC::ComputeScaleAndOrigin(); - XGCValues gc_val; - gc_val.clip_mask = None; + /* CMB: if scale has changed call SetPen to recalulate the line width */ + if ((m_scaleX != origScaleX || m_scaleY != origScaleY) && + (m_pen.Ok())) + { + /* this is a bit artificial, but we need to force wxDC to think + the pen has changed */ + wxPen pen = m_pen; + m_pen = wxNullPen; + SetPen( pen ); + } } -// Resolution in pixels per logical inch wxSize wxWindowDC::GetPPI() const { return wxSize(100, 100); @@ -1977,120 +1869,85 @@ wxSize wxWindowDC::GetPPI() const int wxWindowDC::GetDepth() const { - // TODO - return 24; -} - - + wxFAIL_MSG(wxT("not implemented")); + return -1; +} // ---------------------------------------------------------------------------- // wxPaintDC // ---------------------------------------------------------------------------- +IMPLEMENT_DYNAMIC_CLASS(wxPaintDC, wxClientDC) + wxPaintDC::wxPaintDC(wxWindow* win) - : wxWindowDC(win) + : wxClientDC(win) +{ +#if USE_PAINT_REGION + if (!win->GetClipPaintRegion()) + return; + + m_paintClippingRegion = win->GetUpdateRegion(); + Region region = (Region) m_paintClippingRegion.GetX11Region(); + if (region) + { + m_paintClippingRegion = win->GetUpdateRegion(); + Region region2 = (Region) m_paintClippingRegion.GetX11Region(); + if (region2) + { + m_currentClippingRegion.Union( m_paintClippingRegion ); + + XSetRegion( (Display*) m_display, (GC) m_penGC, region2 ); + XSetRegion( (Display*) m_display, (GC) m_brushGC, region2 ); + XSetRegion( (Display*) m_display, (GC) m_textGC, region2 ); + XSetRegion( (Display*) m_display, (GC) m_bgGC, region2 ); + } + } +#endif // USE_PAINT_REGION +} + +//----------------------------------------------------------------------------- +// wxClientDC +//----------------------------------------------------------------------------- + +IMPLEMENT_DYNAMIC_CLASS(wxClientDC, wxWindowDC) + +wxClientDC::wxClientDC( wxWindow *win ) + : wxWindowDC( win ) { - // TODO clone GTK logic here + wxCHECK_RET( win, _T("NULL window in wxClientDC::wxClientDC") ); } -wxPaintDC::~wxPaintDC() +void wxClientDC::DoGetSize(int *width, int *height) const { + wxCHECK_RET( m_owner, _T("GetSize() doesn't work without window") ); + + m_owner->GetClientSize( width, height ); } // ---------------------------------------------------------------------------- -// private functions +// wxDCModule // ---------------------------------------------------------------------------- -/* - Used when copying between drawables on different (Display*) m_displays. Not - very fast, but better than giving up. -*/ - -static void XCopyRemote(Display *src_display, Display *dest_display, - Drawable src, Drawable dest, - GC destgc, - int srcx, int srcy, - unsigned int w, unsigned int h, - int destx, int desty, - bool more, XImage **cache) +class wxDCModule : public wxModule { - XImage *image, *destimage; - Colormap destcm, srccm; - static const int CACHE_SIZE = 256; +public: + bool OnInit(); + void OnExit(); - unsigned int i, j; - unsigned long cachesrc[CACHE_SIZE], cachedest[CACHE_SIZE]; - int k, cache_pos, all_cache; +private: + DECLARE_DYNAMIC_CLASS(wxDCModule) +}; - if (!cache || !*cache) - image = XGetImage(src_display, src, srcx, srcy, w, h, AllPlanes, ZPixmap); - else - image = *cache; - - destimage = XGetImage(dest_display, dest, destx, desty, w, h, AllPlanes, ZPixmap); - - srccm = (Colormap) wxTheApp->GetMainColormap((WXDisplay*) src_display); - destcm = (Colormap) wxTheApp->GetMainColormap((WXDisplay*) dest_display); - - cache_pos = 0; - all_cache = FALSE; - - for (i = 0; i < w; i++) - for (j = 0; j < h; j++) { - unsigned long pixel; - XColor xcol; - - pixel = XGetPixel(image, i, j); - for (k = cache_pos; k--; ) - if (cachesrc[k] == pixel) { - pixel = cachedest[k]; - goto install; - } - if (all_cache) - for (k = CACHE_SIZE; k-- > cache_pos; ) - if (cachesrc[k] == pixel) { - pixel = cachedest[k]; - goto install; - } - - cachesrc[cache_pos] = xcol.pixel = pixel; - XQueryColor(src_display, srccm, &xcol); - if (!XAllocColor(dest_display, destcm, &xcol)) - xcol.pixel = 0; - cachedest[cache_pos] = pixel = xcol.pixel; - - if (++cache_pos >= CACHE_SIZE) { - cache_pos = 0; - all_cache = TRUE; - } - -install: - XPutPixel(destimage, i, j, pixel); - } +IMPLEMENT_DYNAMIC_CLASS(wxDCModule, wxModule) - XPutImage(dest_display, dest, destgc, destimage, 0, 0, destx, desty, w, h); - XDestroyImage(destimage); - - if (more) - *cache = image; - else - XDestroyImage(image); +bool wxDCModule::OnInit() +{ + wxInitGCPool(); + return TRUE; } -#if 0 - -/* Helper function for 16-bit fonts */ -static int str16len(const char *s) +void wxDCModule::OnExit() { - int count = 0; - - while (s[0] && s[1]) { - count++; - s += 2; - } - - return count; + wxCleanUpGCPool(); } - -#endif // 0 diff --git a/src/x11/dcmemory.cpp b/src/x11/dcmemory.cpp index eb74c0e252..34cc5f0753 100644 --- a/src/x11/dcmemory.cpp +++ b/src/x11/dcmemory.cpp @@ -17,142 +17,72 @@ #include "wx/settings.h" #include "wx/utils.h" -#ifdef __VMS__ -#pragma message disable nosimpint -#endif -#ifdef __VMS__ -#pragma message enable nosimpint -#endif - #include "wx/x11/private.h" -//----------------------------------------------------------------------------- -// wxMemoryDC -//----------------------------------------------------------------------------- +IMPLEMENT_DYNAMIC_CLASS(wxMemoryDC,wxWindowDC) -IMPLEMENT_DYNAMIC_CLASS(wxMemoryDC, wxWindowDC) - -wxMemoryDC::wxMemoryDC(void) +wxMemoryDC::wxMemoryDC() : wxWindowDC() { - m_ok = TRUE; - m_display = wxGetDisplay(); - - Display* display = (Display*) m_display; + m_ok = FALSE; - XGCValues gcvalues; - gcvalues.foreground = BlackPixel (display, DefaultScreen (display)); - gcvalues.background = WhitePixel (display, DefaultScreen (display)); - gcvalues.graphics_exposures = False; - gcvalues.subwindow_mode = IncludeInferiors; - gcvalues.line_width = 1; - m_gc = (WXGC) XCreateGC (display, RootWindow (display, DefaultScreen (display)), - GCForeground | GCBackground | GCGraphicsExposures | GCLineWidth | GCSubwindowMode, - &gcvalues); - - m_backgroundPixel = (int) gcvalues.background; - - // Get the current Font so we can set it back later - XGCValues valReturn; - XGetGCValues((Display*) m_display, (GC) m_gc, GCFont, &valReturn); - m_oldFont = (WXFont) valReturn.font; - SetBrush (* wxWHITE_BRUSH); - SetPen (* wxBLACK_PEN); - SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); -}; + m_display = (WXDisplay *) wxGlobalDisplay(); + + int screen = DefaultScreen( wxGlobalDisplay() ); + m_cmap = (WXColormap) DefaultColormap( wxGlobalDisplay(), screen ); +} -wxMemoryDC::wxMemoryDC( wxDC* dc ) +wxMemoryDC::wxMemoryDC( wxDC *WXUNUSED(dc) ) + : wxWindowDC() { - m_ok = TRUE; - if (dc && dc->IsKindOf(CLASSINFO(wxWindowDC))) - m_display = ((wxWindowDC*)dc)->GetDisplay(); - else - m_display = wxGetDisplay(); - - Display* display = (Display*) m_display; - - XGCValues gcvalues; - gcvalues.foreground = BlackPixel (display, DefaultScreen (display)); - gcvalues.background = WhitePixel (display, DefaultScreen (display)); - gcvalues.graphics_exposures = False; - gcvalues.subwindow_mode = IncludeInferiors; - gcvalues.line_width = 1; - m_gc = (WXGC) XCreateGC (display, RootWindow (display, DefaultScreen (display)), - GCForeground | GCBackground | GCGraphicsExposures | GCLineWidth | GCSubwindowMode, - &gcvalues); - - m_backgroundPixel = (int) gcvalues.background; + m_ok = FALSE; + + m_display = (WXDisplay *) wxGlobalDisplay(); - // Get the current Font so we can set it back later - XGCValues valReturn; - XGetGCValues((Display*) m_display, (GC) m_gc, GCFont, &valReturn); - m_oldFont = (WXFont) valReturn.font; - SetBrush (* wxWHITE_BRUSH); - SetPen (* wxBLACK_PEN); -}; + int screen = DefaultScreen( wxGlobalDisplay() ); + m_cmap = (WXColormap) DefaultColormap( wxGlobalDisplay(), screen ); +} -wxMemoryDC::~wxMemoryDC(void) +wxMemoryDC::~wxMemoryDC() { -}; +} void wxMemoryDC::SelectObject( const wxBitmap& bitmap ) { - m_bitmap = bitmap; + Destroy(); - if (m_gc) - XFreeGC((Display*) m_display, (GC) m_gc); - m_gc = (WXGC) NULL; - - if (m_bitmap.Ok() && (bitmap.GetDisplay() == m_display)) + m_selected = bitmap; + if (m_selected.Ok()) { - m_pixmap = m_bitmap.GetPixmap(); - Display* display = (Display*) m_display; - - XGCValues gcvalues; - gcvalues.foreground = BlackPixel (display, DefaultScreen (display)); - gcvalues.background = WhitePixel (display, DefaultScreen (display)); - gcvalues.graphics_exposures = False; - gcvalues.subwindow_mode = IncludeInferiors; - gcvalues.line_width = 1; - m_gc = (WXGC) XCreateGC (display, RootWindow (display, DefaultScreen (display)), - GCForeground | GCBackground | GCGraphicsExposures | GCLineWidth | GCSubwindowMode, - &gcvalues); - - m_backgroundPixel = (int) gcvalues.background; - - // Get the current Font so we can set it back later - XGCValues valReturn; - XGetGCValues((Display*) m_display, (GC) m_gc, GCFont, &valReturn); - m_oldFont = (WXFont) valReturn.font; - - bool oldOpt = GetOptimization(); - SetOptimization(FALSE); - - SetBrush (* wxWHITE_BRUSH); - SetPen (* wxBLACK_PEN); - - SetOptimization(oldOpt); - - m_ok = TRUE; + if (m_selected.GetPixmap()) + { + m_window = (WXWindow) m_selected.GetPixmap(); + } + else + { +// m_window = m_selected.GetBitmap(); + } + + m_isMemDC = TRUE; + + SetUpDC(); } else { m_ok = FALSE; - m_pixmap = (WXPixmap) 0; - }; -}; + m_window = NULL; + } +} void wxMemoryDC::DoGetSize( int *width, int *height ) const { - if (m_bitmap.Ok()) + if (m_selected.Ok()) { - if (width) (*width) = m_bitmap.GetWidth(); - if (height) (*height) = m_bitmap.GetHeight(); + if (width) (*width) = m_selected.GetWidth(); + if (height) (*height) = m_selected.GetHeight(); } else { if (width) (*width) = 0; if (height) (*height) = 0; - }; -}; - - + } +} diff --git a/src/x11/dcscreen.cpp b/src/x11/dcscreen.cpp index 3be136b3c5..0efabc519c 100644 --- a/src/x11/dcscreen.cpp +++ b/src/x11/dcscreen.cpp @@ -1,11 +1,11 @@ ///////////////////////////////////////////////////////////////////////////// // Name: dcscreen.cpp // Purpose: wxScreenDC class -// Author: Julian Smart +// Author: Julian Smart, Robert Roebling // Modified by: // Created: 17/09/98 // RCS-ID: $Id$ -// Copyright: (c) Julian Smart +// Copyright: (c) Julian Smart, Robert Roebling // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -18,117 +18,102 @@ #include "wx/dcscreen.h" #include "wx/utils.h" -#ifdef __VMS__ -#pragma message disable nosimpint -#endif - -#ifdef __VMS__ -#pragma message enable nosimpint -#endif - #include "wx/x11/private.h" -IMPLEMENT_DYNAMIC_CLASS(wxScreenDC, wxWindowDC) +//----------------------------------------------------------------------------- +// global data initialization +//----------------------------------------------------------------------------- -WXWindow wxScreenDC::sm_overlayWindow = 0; +WXWindow *wxScreenDC::sm_overlayWindow = (WXWindow*) NULL; int wxScreenDC::sm_overlayWindowX = 0; int wxScreenDC::sm_overlayWindowY = 0; -// Create a DC representing the whole screen +//----------------------------------------------------------------------------- +// wxScreenDC +//----------------------------------------------------------------------------- + +IMPLEMENT_DYNAMIC_CLASS(wxScreenDC,wxPaintDC) + wxScreenDC::wxScreenDC() { - m_display = wxGetDisplay(); - Display* display = (Display*) m_display; + m_ok = FALSE; - if (sm_overlayWindow) - { - m_pixmap = sm_overlayWindow; - m_deviceOriginX = - sm_overlayWindowX; - m_deviceOriginY = - sm_overlayWindowY; - } - else - m_pixmap = (WXPixmap) RootWindow(display, DefaultScreen(display)); + m_display = (WXDisplay *) wxGlobalDisplay(); - XGCValues gcvalues; - gcvalues.foreground = BlackPixel (display, DefaultScreen (display)); - gcvalues.background = WhitePixel (display, DefaultScreen (display)); - gcvalues.graphics_exposures = False; - gcvalues.subwindow_mode = IncludeInferiors; - gcvalues.line_width = 1; - m_gc = XCreateGC (display, RootWindow (display, DefaultScreen (display)), - GCForeground | GCBackground | GCGraphicsExposures | GCLineWidth | GCSubwindowMode, - &gcvalues); + int screen = DefaultScreen( (Display*) m_display ); + m_cmap = (WXColormap) DefaultColormap( (Display*) m_display, screen ); - m_backgroundPixel = (int) gcvalues.background; - m_ok = TRUE; + m_window = (WXWindow) RootWindow( (Display*) m_display, screen ); + + m_isScreenDC = TRUE; + + SetUpDC(); + + XSetSubwindowMode( (Display*) m_display, (GC) m_penGC, IncludeInferiors ); + XSetSubwindowMode( (Display*) m_display, (GC) m_brushGC, IncludeInferiors ); + XSetSubwindowMode( (Display*) m_display, (GC) m_textGC, IncludeInferiors ); + XSetSubwindowMode( (Display*) m_display, (GC) m_bgGC, IncludeInferiors ); } wxScreenDC::~wxScreenDC() { + XSetSubwindowMode( (Display*) m_display, (GC) m_penGC, ClipByChildren ); + XSetSubwindowMode( (Display*) m_display, (GC) m_brushGC, ClipByChildren ); + XSetSubwindowMode( (Display*) m_display, (GC) m_textGC, ClipByChildren ); + XSetSubwindowMode( (Display*) m_display, (GC) m_bgGC, ClipByChildren ); + EndDrawingOnTop(); } -bool wxScreenDC::StartDrawingOnTop(wxWindow* window) +bool wxScreenDC::StartDrawingOnTop( wxWindow *window ) { + if (!window) return StartDrawingOnTop(); + + int x = 0; + int y = 0; + window->GetPosition( &x, &y ); + int w = 0; + int h = 0; + window->GetSize( &w, &h ); + window->ClientToScreen( &x, &y ); + wxRect rect; - int x, y, width, height; - window->GetPosition(& x, & y); - if (window->GetParent() && !window->IsKindOf(CLASSINFO(wxFrame))) - window->GetParent()->ClientToScreen(& x, & y); - window->GetSize(& width, & height); - rect.x = x; rect.y = y; - rect.width = width; rect.height = height; - - return StartDrawingOnTop(& rect); + rect.x = x; + rect.y = y; + rect.width = 0; + rect.height = 0; + + return StartDrawingOnTop( &rect ); } -bool wxScreenDC::StartDrawingOnTop(wxRect* rect) +bool wxScreenDC::StartDrawingOnTop( wxRect *rect ) { - if (sm_overlayWindow) - return FALSE; - - Display *dpy = (Display*) wxGetDisplay(); - Pixmap screenPixmap = RootWindow(dpy, DefaultScreen(dpy)); - int x = 0; int y = 0; - int width, height; - wxDisplaySize(&width, &height); - +#if 0 + int width = gdk_screen_width(); + int height = gdk_screen_height(); +#else + int width = 1024; + int height = 768; +#endif if (rect) { - x = rect->x; y = rect->y; - width = rect->width; height = rect->height; - } - sm_overlayWindowX = x; - sm_overlayWindowY = y; - - XSetWindowAttributes attributes; - attributes.override_redirect = True; - unsigned long valueMask = CWOverrideRedirect; - - sm_overlayWindow = (WXWindow) XCreateWindow(dpy, screenPixmap, x, y, width, height, 0, - wxDisplayDepth(), InputOutput, - DefaultVisual(dpy, 0), valueMask, - & attributes); - - if (sm_overlayWindow) - { - XMapWindow(dpy, (Window) sm_overlayWindow); - return TRUE; + x = rect->x; + y = rect->y; + width = rect->width; + height = rect->height; } - else - return FALSE; + + return TRUE; } bool wxScreenDC::EndDrawingOnTop() { - if (sm_overlayWindow) - { - XDestroyWindow((Display*) wxGetDisplay(), (Window) sm_overlayWindow); - sm_overlayWindow = 0; - return TRUE; - } - else - return FALSE; + return TRUE; +} + +void wxScreenDC::DoGetSize(int *width, int *height) const +{ + wxDisplaySize(width, height); } diff --git a/src/x11/window.cpp b/src/x11/window.cpp index 6914ada32d..17509fdf3b 100644 --- a/src/x11/window.cpp +++ b/src/x11/window.cpp @@ -121,11 +121,7 @@ bool wxWindowX11::Create(wxWindow *parent, wxWindowID id, CreateBase(parent, id, pos, size, style, wxDefaultValidator, name); - if (parent) - parent->AddChild(this); - - m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE); - m_foregroundColour = *wxBLACK; + parent->AddChild(this); int w = size.GetWidth(); int h = size.GetHeight(); @@ -136,18 +132,25 @@ bool wxWindowX11::Create(wxWindow *parent, wxWindowID id, if (x == -1) x = 0; if (y == -1) y = 0; - int screen = DefaultScreen(wxGlobalDisplay()); + Display *xdisplay = (Display*) wxGlobalDisplay(); + int xscreen = DefaultScreen( xdisplay ); + Colormap cm = DefaultColormap( xdisplay, xscreen ); - Window parentWindow; - if (parent) - parentWindow = (Window) parent->GetMainWindow(); - else - parentWindow = RootWindow(wxGlobalDisplay(), screen); + m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE); + m_backgroundColour.CalcPixel( (WXColormap) cm ); + + m_foregroundColour = *wxBLACK; + m_foregroundColour.CalcPixel( (WXColormap) cm ); + + + Window parentWindow = (Window) parent->GetMainWindow(); - Window window = XCreateSimpleWindow(wxGlobalDisplay(), parentWindow, - x, y, w, h, 0, - m_backgroundColour.AllocColour(wxGlobalDisplay()), - m_foregroundColour.AllocColour(wxGlobalDisplay())); + Window window = XCreateSimpleWindow( + xdisplay, parentWindow, + x, y, w, h, 0, + m_backgroundColour.GetPixel(), + m_foregroundColour.GetPixel() ); + m_mainWidget = (WXWindow) window; // Select event types wanted @@ -411,6 +414,7 @@ void wxWindowX11::WarpPointer (int x, int y) // Does a physical scroll void wxWindowX11::ScrollWindow(int dx, int dy, const wxRect *rect) { +#if 0 int x, y, w, h; if (rect) { @@ -573,10 +577,7 @@ void wxWindowX11::ScrollWindow(int dx, int dy, const wxRect *rect) delete rect; node = node->Next(); } - - // TODO - - // XmUpdateDisplay((Widget) GetMainWidget()); +#endif } // --------------------------------------------------------------------------- @@ -697,7 +698,7 @@ void wxWindowX11::DoGetClientSize(int *x, int *y) const if (window) { XWindowAttributes attr; - Status status = XGetWindowAttributes(wxGlobalDisplay(), window, & attr); + Status status = XGetWindowAttributes( wxGlobalDisplay(), window, &attr ); wxASSERT(status); if (status) @@ -972,9 +973,9 @@ void wxWindowX11::X11SendPaintEvents() m_clearRegion.Clear(); } - wxNcPaintEvent nc_paint_event( GetId() ); - nc_paint_event.SetEventObject( this ); - GetEventHandler()->ProcessEvent( nc_paint_event ); + // wxNcPaintEvent nc_paint_event( GetId() ); + // nc_paint_event.SetEventObject( this ); + // GetEventHandler()->ProcessEvent( nc_paint_event ); wxPaintEvent paint_event( GetId() ); paint_event.SetEventObject( this ); @@ -1314,9 +1315,15 @@ bool wxWindowX11::SetBackgroundColour(const wxColour& col) if (!GetMainWindow()) return FALSE; + Display *xdisplay = (Display*) wxGlobalDisplay(); + int xscreen = DefaultScreen( xdisplay ); + Colormap cm = DefaultColormap( xdisplay, xscreen ); + wxColour colour( col ); + colour.CalcPixel( (WXColormap) cm ); + XSetWindowAttributes attrib; - attrib.background_pixel = colour.AllocColour(wxGlobalDisplay()); + attrib.background_pixel = colour.GetPixel(); XChangeWindowAttributes(wxGlobalDisplay(), (Window) GetMainWindow(), -- 2.45.2