diff --git a/include/wx/dc.h b/include/wx/dc.h index 43e7c585bf..69adc1f414 100644 --- a/include/wx/dc.h +++ b/include/wx/dc.h @@ -30,6 +30,953 @@ #include "wx/dynarray.h" #include "wx/math.h" + // 1 if using the reorganized DC code +#define wxUSE_NEW_DC 0 + + +#if wxUSE_NEW_DC + +//----------------------------------------------------------------------------- +// wxDCFactory +//----------------------------------------------------------------------------- + +class WXDLLIMPEXP_CORE wxImplDC; + +class WXDLLIMPEXP_CORE wxDCFactory +{ +public: + wxDCFactory() {} + virtual ~wxDCFactory() {} + + virtual wxImplDC* CreateWindowDC() = 0; + virtual wxImplDC* CreateWindowDC( wxWindow *window ) = 0; + virtual wxImplDC* CreateClientDC() = 0; + virtual wxImplDC* CreateClientDC( wxWindow *window ) = 0; + virtual wxImplDC* CreatePaintDC() = 0; + virtual wxImplDC* CreatePaintDC( wxWindow *window ) = 0; + virtual wxImplDC* CreateMemoryDC() = 0; + virtual wxImplDC* CreateMemoryDC( wxBitmap &bitmap ) = 0; + virtual wxImplDC* CreateMemoryDC( wxDC *dc ) = 0; + + static void SetDCFactory( wxDCFactory *factory ); + static wxDCFactory *GetFactory(); +private: + static wxDCFactory *m_factory; +}; + +//----------------------------------------------------------------------------- +// wxNativeDCFactory +//----------------------------------------------------------------------------- + +class WXDLLIMPEXP_CORE wxDCFactory +{ +public: + wxNativeDCFactory() {} + + virtual wxImplDC* CreateWindowDC(); + virtual wxImplDC* CreateWindowDC( wxWindow *window ); + virtual wxImplDC* CreateClientDC(); + virtual wxImplDC* CreateClientDC( wxWindow *window ); + virtual wxImplDC* CreatePaintDC(); + virtual wxImplDC* CreatePaintDC( wxWindow *window ); + virtual wxImplDC* CreateMemoryDC(); + virtual wxImplDC* CreateMemoryDC( wxBitmap &bitmap ); + virtual wxImplDC* CreateMemoryDC( wxDC *dc ); +}; + +//----------------------------------------------------------------------------- +// wxWindowDC +//----------------------------------------------------------------------------- + +class WXDLLIMPEXP_CORE wxWindowDC : public wxDC +{ +public: + wxWindowDC(); + wxWindowDC( wxWindow *win ); + +private: + DECLARE_DYNAMIC_CLASS(wxWindowDC) +}; + +//----------------------------------------------------------------------------- +// wxClientDC +//----------------------------------------------------------------------------- + +class WXDLLIMPEXP_CORE wxClientDC : public wxDC +{ +public: + wxClientDC(); + wxClientDC( wxWindow *win ); + +private: + DECLARE_DYNAMIC_CLASS(wxClientDC) +}; + +//----------------------------------------------------------------------------- +// wxMemoryDC +//----------------------------------------------------------------------------- + +class WXDLLIMPEXP_CORE wxMemoryDC: public wxDC +{ +public: + wxMemoryDC(); + wxMemoryDC( wxBitmap& bitmap ); + wxMemoryDC( wxDC *dc ); + +private: + DECLARE_DYNAMIC_CLASS(wxMemoryDC) +}; + +//----------------------------------------------------------------------------- +// wxPaintDC +//----------------------------------------------------------------------------- + +class WXDLLIMPEXP_CORE wxPaintDC : public wxDC +{ +public: + wxPaintDC(); + wxPaintDC( wxWindow *win ); + +private: + DECLARE_DYNAMIC_CLASS(wxPaintDC) +}; + +//----------------------------------------------------------------------------- +// wxImplDC +//----------------------------------------------------------------------------- + +class WXDLLIMPEXP_CORE wxImplDC: public wxObject +{ +public: + wxImplDC( wxDC *owner ); + ~wxImplDC(); + + wxDC *GetOwner() { return m_owner; } + + virtual bool IsOk() const { return m_ok; } + + // query capabilities + + virtual bool CanDrawBitmap() const = 0; + virtual bool CanGetTextExtent() const = 0; + + // query dimension, colour deps, resolution + + virtual void DoGetSize(int *width, int *height) const = 0; + virtual void DoGetSizeMM(int* width, int* height) const = 0; + + virtual int GetDepth() const = 0; + virtual wxSize GetPPI() const = 0; + + // Right-To-Left (RTL) modes + + virtual void SetLayoutDirection(wxLayoutDirection WXUNUSED(dir)) { } + virtual wxLayoutDirection GetLayoutDirection() const { return wxLayout_Default; } + + // page and document + + virtual bool StartDoc(const wxString& WXUNUSED(message)) { return true; } + virtual void EndDoc() { } + + virtual void StartPage() { } + virtual void EndPage() { } + + // bounding box + + virtual void CalcBoundingBox(wxCoord x, wxCoord y); + { + if ( m_isBBoxValid ) + { + if ( x < m_minX ) m_minX = x; + if ( y < m_minY ) m_minY = y; + if ( x > m_maxX ) m_maxX = x; + if ( y > m_maxY ) m_maxY = y; + } + else + { + m_isBBoxValid = true; + + m_minX = x; + m_minY = y; + m_maxX = x; + m_maxY = y; + } + } + void ResetBoundingBox(); + { + m_isBBoxValid = false; + + m_minX = m_maxX = m_minY = m_maxY = 0; + } + + wxCoord MinX() const { return m_minX; } + wxCoord MaxX() const { return m_maxX; } + wxCoord MinY() const { return m_minY; } + wxCoord MaxY() const { return m_maxY; } + + // setters and getters + + virtual void SetFont(const wxFont& font) = 0; + virtual const wxFont& GetFont() const { return m_font; } + + virtual void SetPen(const wxPen& pen) = 0; + virtual const wxPen& GetPen() const { return m_pen; } + + virtual void SetBrush(const wxBrush& brush) = 0; + virtual const wxBrush& GetBrush() const { return m_brush; } + + virtual void SetBackground(const wxBrush& brush) = 0; + virtual const wxBrush& GetBackground() const { return m_backgroundBrush; } + + virtual void SetBackgroundMode(int mode) = 0; + virtual int GetBackgroundMode() const { return m_backgroundMode; } + + virtual void SetTextForeground(const wxColour& colour) + { m_textForegroundColour = colour; } + virtual const wxColour& GetTextForeground() const { return m_textForegroundColour; } + + virtual void SetTextBackground(const wxColour& colour) + { m_textBackgroundColour = colour; } + virtual const wxColour& GetTextBackground() const { return m_textBackgroundColour; } + +#if wxUSE_PALETTE + virtual void SetPalette(const wxPalette& palette) = 0; +#endif // wxUSE_PALETTE + + // logical functions + + virtual void SetLogicalFunction(int function) = 0; + virtual int GetLogicalFunction() const { return m_logicalFunction; } + + // text measurement + + virtual wxCoord GetCharHeight() const = 0; + virtual wxCoord GetCharWidth() const = 0; + virtual void DoGetTextExtent(const wxString& string, + wxCoord *x, wxCoord *y, + wxCoord *descent = NULL, + wxCoord *externalLeading = NULL, + const wxFont *theFont = NULL) const = 0; + virtual void GetMultiLineTextExtent(const wxString& string, + wxCoord *width, + wxCoord *height, + wxCoord *heightLine = NULL, + const wxFont *font = NULL) const; + virtual bool DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths) const; + + // clearing + + virtual void Clear() = 0; + + // clipping + + virtual void DoSetClippingRegion(wxCoord x, wxCoord y, + wxCoord width, wxCoord height) = 0; + virtual void DoSetClippingRegionAsRegion(const wxRegion& region) = 0; + + virtual void DoGetClippingBox(wxCoord *x, wxCoord *y, + wxCoord *w, wxCoord *h) const + { + if ( x ) + *x = m_clipX1; + if ( y ) + *y = m_clipY1; + if ( w ) + *w = m_clipX2 - m_clipX1; + if ( h ) + *h = m_clipY2 - m_clipY1; + } + + virtual void DestroyClippingRegion() { ResetClipping(); } + + + // coordinates conversions and transforms + + virtual wxCoord DeviceToLogicalX(wxCoord x) const; + virtual wxCoord DeviceToLogicalY(wxCoord y) const; + virtual wxCoord DeviceToLogicalXRel(wxCoord x) const; + virtual wxCoord DeviceToLogicalYRel(wxCoord y) const; + virtual wxCoord LogicalToDeviceX(wxCoord x) const; + virtual wxCoord LogicalToDeviceY(wxCoord y) const; + virtual wxCoord LogicalToDeviceXRel(wxCoord x) const; + virtual wxCoord LogicalToDeviceYRel(wxCoord y) const; + + virtual void SetMapMode(int mode); + virtual int GetMapMode() const { return m_mappingMode; } + + virtual void SetUserScale(double x, double y); + virtual void GetUserScale(double *x, double *y) const + { + if ( x ) *x = m_userScaleX; + if ( y ) *y = m_userScaleY; + } + + virtual void SetLogicalScale(double x, double y); + virtual void GetLogicalScale(double *x, double *y) + { + if ( x ) *x = m_logicalScaleX; + if ( y ) *y = m_logicalScaleY; + } + + virtual void SetLogicalOrigin(wxCoord x, wxCoord y); + virtual void DoGetLogicalOrigin(wxCoord *x, wxCoord *y) const + { + if ( x ) *x = m_logicalOriginX; + if ( y ) *y = m_logicalOriginY; + } + + virtual void SetDeviceOrigin(wxCoord x, wxCoord y); + virtual void DoGetDeviceOrigin(wxCoord *x, wxCoord *y) const + { + if ( x ) *x = m_deviceOriginX; + if ( y ) *y = m_deviceOriginY; + } + + virtual void SetDeviceLocalOrigin( wxCoord x, wxCoord y ); + + virtual void ComputeScaleAndOrigin(); + + // this needs to overidden if the axis is inverted + virtual void SetAxisOrientation(bool xLeftRight, bool yBottomUp); + + // --------------------------------------------------------- + // the actual drawing API + + virtual bool DoFloodFill(wxCoord x, wxCoord y, const wxColour& col, + int style = wxFLOOD_SURFACE) = 0; + + virtual void DoGradientFillLinear(const wxRect& rect, + const wxColour& initialColour, + const wxColour& destColour, + wxDirection nDirection = wxEAST); + + virtual void DoGradientFillConcentric(const wxRect& rect, + const wxColour& initialColour, + const wxColour& destColour, + const wxPoint& circleCenter); + + virtual bool DoGetPixel(wxCoord x, wxCoord y, wxColour *col) const = 0; + + virtual void DoDrawPoint(wxCoord x, wxCoord y) = 0; + virtual void DoDrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2) = 0; + + virtual void DoDrawArc(wxCoord x1, wxCoord y1, + wxCoord x2, wxCoord y2, + wxCoord xc, wxCoord yc) = 0; + virtual void DoDrawCheckMark(wxCoord x, wxCoord y, + wxCoord width, wxCoord height); + virtual void DoDrawEllipticArc(wxCoord x, wxCoord y, wxCoord w, wxCoord h, + double sa, double ea) = 0; + + virtual void DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height) = 0; + virtual void DoDrawRoundedRectangle(wxCoord x, wxCoord y, + wxCoord width, wxCoord height, + double radius) = 0; + virtual void DoDrawEllipse(wxCoord x, wxCoord y, + wxCoord width, wxCoord height) = 0; + + virtual void DoCrossHair(wxCoord x, wxCoord y) = 0; + + virtual void DoDrawIcon(const wxIcon& icon, wxCoord x, wxCoord y) = 0; + virtual void DoDrawBitmap(const wxBitmap &bmp, wxCoord x, wxCoord y, + bool useMask = false) = 0; + + virtual void DoDrawText(const wxString& text, wxCoord x, wxCoord y) = 0; + virtual void DoDrawRotatedText(const wxString& text, + wxCoord x, wxCoord y, double angle) = 0; + + virtual bool DoBlit(wxCoord xdest, wxCoord ydest, + wxCoord width, wxCoord height, + wxDC *source, + wxCoord xsrc, wxCoord ysrc, + int rop = wxCOPY, + bool useMask = false, + wxCoord xsrcMask = wxDefaultCoord, + wxCoord ysrcMask = wxDefaultCoord) = 0; + + virtual bool DoStretchBlit(wxCoord xdest, wxCoord ydest, + wxCoord dstWidth, wxCoord dstHeight, + wxDC *source, + wxCoord xsrc, wxCoord ysrc, + wxCoord srcWidth, wxCoord srcHeight, + int rop = wxCOPY, + bool useMask = false, + wxCoord xsrcMask = wxDefaultCoord, + wxCoord ysrcMask = wxDefaultCoord); + + virtual wxBitmap DoGetAsBitmap(const wxRect *WXUNUSED(subrect)) const + { return wxNullBitmap; } + + + virtual void DoDrawLines(int n, wxPoint points[], + wxCoord xoffset, wxCoord yoffset) = 0; + virtual void DoDrawPolygon(int n, wxPoint points[], + wxCoord xoffset, wxCoord yoffset, + int fillStyle = wxODDEVEN_RULE) = 0; + virtual void DoDrawPolyPolygon(int n, int count[], wxPoint points[], + wxCoord xoffset, wxCoord yoffset, + int fillStyle); + + + +#if wxUSE_SPLINES + virtual void DoDrawSpline(wxList *points); +#endif + +private: + wxDC *m_owner; + +protected: + // unset clipping variables (after clipping region was destroyed) + void ResetClipping() + { + m_clipping = false; + + m_clipX1 = m_clipX2 = m_clipY1 = m_clipY2 = 0; + } + + // flags + bool m_colour:1; + bool m_ok:1; + bool m_clipping:1; + bool m_isInteractive:1; + bool m_isBBoxValid:1; + + // coordinate system variables + + wxCoord m_logicalOriginX, m_logicalOriginY; + wxCoord m_deviceOriginX, m_deviceOriginY; // Usually 0,0, can be change by user + + wxCoord m_deviceLocalOriginX, m_deviceLocalOriginY; // non-zero if native top-left corner + // is not at 0,0. This was the case under + // Mac's GrafPorts (coordinate system + // used toplevel window's origin) and + // e.g. for Postscript, where the native + // origin in the bottom left corner. + double m_logicalScaleX, m_logicalScaleY; + double m_userScaleX, m_userScaleY; + double m_scaleX, m_scaleY; // calculated from logical scale and user scale + + int m_signX, m_signY; // Used by SetAxisOrientation() to invert the axes + + // what is a mm on a screen you don't know the size of? + double m_mm_to_pix_x, + m_mm_to_pix_y; + + // bounding and clipping boxes + wxCoord m_minX, m_minY, m_maxX, m_maxY; + wxCoord m_clipX1, m_clipY1, m_clipX2, m_clipY2; + + int m_logicalFunction; + int m_backgroundMode; + int m_mappingMode; + + wxPen m_pen; + wxBrush m_brush; + wxBrush m_backgroundBrush; + wxColour m_textForegroundColour; + wxColour m_textBackgroundColour; + wxFont m_font; + +#if wxUSE_PALETTE + wxPalette m_palette; + bool m_hasCustomPalette; +#endif // wxUSE_PALETTE + +private: + DECLARE_ABSTRACT_CLASS(wxImplDC) +} + + +class wxDC: public wxObject +{ +public: + wxDC() { m_pimpl = NULL; } + + bool IsOk() const + { return m_pimpl && m_pimpl->IsOk(); } + + // query capabilities + + bool CanDrawBitmap() const + { return m_pimpl->CanDrawBitmap(); } + bool CanGetTextExtent() const + { return m_pimpl->CanGetTextExtent(); } + + // query dimension, colour deps, resolution + + void GetSize(int *width, int *height) const + { m_pimpl->DoGetSize(width, height); } + + wxSize GetSize() const + { + int w, h; + m_pimpl->DoGetSize(&w, &h); + return wxSize(w, h); + } + + void GetSizeMM(int* width, int* height) const + { m_pimpl->DoGetSizeMM(width, height); } + wxSize GetSizeMM() const + { + int w, h; + m_pimpl->DoGetSizeMM(&w, &h); + return wxSize(w, h); + } + + int GetDepth() const + { return m_pimpl->GetDepth(); } + wxSize GetPPI() const + { return m_pimpl->GetPPI(); } + + // Right-To-Left (RTL) modes + + void SetLayoutDirection(wxLayoutDirection dir) + { m_pimpl->SetLayoutDirection( dir ); } + wxLayoutDirection GetLayoutDirection() const + { return m_pimpl->GetLayoutDirection(); } + + // page and document + + bool StartDoc(const wxString& message) + { return m_pimpl->StartDoc(message); } + void EndDoc() + { m_pimpl->EndDoc(); } + + void StartPage() + { m_pimpl->StartPage(); } + void EndPage() + { m_pimpl->EndPage(); } + + // bounding box + + void CalcBoundingBox(wxCoord x, wxCoord y) + { m_pimpl->CalcBoundingBox(x,y); } + void ResetBoundingBox() + { m_pimpl->ResetBoundingBox(); } + + wxCoord MinX() const + { return m_pimpl->MinX(); } + wxCoord MaxX() const + { return m_pimpl->MaxX(); } + wxCoord MinY() const + { return m_pimpl->MinY(); } + wxCoord MaxY() const + { return m_pimpl->MaxY(); } + + // setters and getters + + void SetFont(const wxFont& font) + { m_pimpl->SetFont( font ); } + const wxFont& GetFont() const + { return m_pimpl->GetFont(); } + + void SetPen(const wxPen& pen) + { m_pimpl->SetPen( pen ); } + const wxPen& GetPen() const + { return m_pimpl->GetPen(); } + + void SetBrush(const wxBrush& brush) + { m_pimpl->SetBrush( brush ); } + const wxBrush& GetBrush() const + { return m_pimpl->GetBrush(); } + + void SetBackground(const wxBrush& brush) + { m_pimpl->SetBackground( brush ); } + const wxBrush& GetBackground() const + { return m_pimpl->GetBackground(); } + + void SetBackgroundMode(int mode) + { m_pimpl->SetBackground( mode ); } + int GetBackgroundMode() const + { return m_pimpl->GetBackground(); } + + void SetTextForeground(const wxColour& colour) + { m_pimpl->SetTextForeground(colour); } + const wxColour& GetTextForeground() const + { return m_pimpl->GetTextForeground(); } + + void SetTextBackground(const wxColour& colour) + { m_pimpl->SetTextBackground(colour); } + const wxColour& GetTextBackground() const + { return m_pimpl->GetTextBackground(); } + +#if wxUSE_PALETTE + void SetPalette(const wxPalette& palette) + { m_pimpl->SetPalette(palette); } +#endif // wxUSE_PALETTE + + // logical functions + + void SetLogicalFunction(int function) + { m_pimpl->SetLogicalFunction(function); } + int GetLogicalFunction() const + { return m_pimpl->GetLogicalFunction(); } + + // text measurement + + wxCoord GetCharHeight() const + { return m_pimpl->GetCharHeight(); } + wxCoord GetCharWidth() const + { return m_pimpl->GetCharWidth(); } + + void GetTextExtent(const wxString& string, + wxCoord *x, wxCoord *y, + wxCoord *descent = NULL, + wxCoord *externalLeading = NULL, + const wxFont *theFont = NULL) const + { m_pimpl->DoGetTextExtent(string, x, y, descent, externalLeading, theFont); } + + wxSize GetTextExtent(const wxString& string) const + { + wxCoord w, h; + m_pimpl->DoGetTextExtent(string, &w, &h); + return wxSize(w, h); + } + + void GetMultiLineTextExtent(const wxString& string, + wxCoord *width, + wxCoord *height, + wxCoord *heightLine = NULL, + const wxFont *font = NULL) const + { m_pimpl->GetMultiLineTextExtent( string, width, height, heightLine, font ); } + + wxSize GetMultiLineTextExtent(const wxString& string) const + { + wxCoord w, h; + m_pimpl->GetMultiLineTextExtent(string, &w, &h); + return wxSize(w, h); + } + + bool GetPartialTextExtents(const wxString& text, wxArrayInt& widths) const + { return m_pimpl->DoGetPartialTextExtents(text, widths); } + + // clearing + + void Clear() + { m_pimpl->Clear(); } + + // clipping + + void SetClippingRegion(wxCoord x, wxCoord y, wxCoord width, wxCoord height) + { m_pimpl->DoSetClippingRegion(x, y, width, height); } + void SetClippingRegion(const wxPoint& pt, const wxSize& sz) + { m_pimpl->DoSetClippingRegion(pt.x, pt.y, sz.x, sz.y); } + void SetClippingRegion(const wxRect& rect) + { m_pimpl->DoSetClippingRegion(rect.x, rect.y, rect.width, rect.height); } + void SetClippingRegion(const wxRegion& region) + { m_pimpl->DoSetClippingRegionAsRegion(region); } + + void DestroyClippingRegion() + { m_pimpl->DestroyClippingRegion(); } + + void GetClippingBox(wxCoord *x, wxCoord *y, wxCoord *w, wxCoord *h) const + { m_pimpl->DoGetClippingBox(x, y, w, h); } + void GetClippingBox(wxRect& rect) const + { m_pimpl->DoGetClippingBox(&rect.x, &rect.y, &rect.width, &rect.height); } + + // coordinates conversions and transforms + + wxCoord DeviceToLogicalX(wxCoord x) const + { return m_pimpl->DeviceToLogicalX(x); } + wxCoord DeviceToLogicalY(wxCoord y) const; + { return m_pimpl->DeviceToLogicalY(y); } + wxCoord DeviceToLogicalXRel(wxCoord x) const; + { return m_pimpl->DeviceToLogicalXRel(x); } + wxCoord DeviceToLogicalYRel(wxCoord y) const; + { return m_pimpl->DeviceToLogicalYRel(y); } + wxCoord LogicalToDeviceX(wxCoord x) const; + { return m_pimpl->LogicalToDeviceX(x); } + wxCoord LogicalToDeviceY(wxCoord y) const; + { return m_pimpl->LogicalToDeviceY(y); } + wxCoord LogicalToDeviceXRel(wxCoord x) const; + { return m_pimpl->LogicalToDeviceXRel(x); } + wxCoord LogicalToDeviceYRel(wxCoord y) const; + { return m_pimpl->LogicalToDeviceYRel(y); } + + void SetMapMode(int mode) + { m_pimpl->SetMapMode(mode); } + int GetMapMode() const + { return m_pimpl->GetMapMode(); } + + void SetUserScale(double x, double y) + { m_pimpl->SetUserScale(x,y); } + void GetUserScale(double *x, double *y) const + { m_pimpl->GetUserScale( x, y ); } + + void SetLogicalScale(double x, double y) + { m_pimpl->SetLogicalScale( x, y ); } + void GetLogicalScale(double *x, double *y) + { m_pimpl->GetLogicalScale( x, y ); } + + void SetLogicalOrigin(wxCoord x, wxCoord y) + { m_pimpl->SetLogicalOrigin(x,y); } + void GetLogicalOrigin(wxCoord *x, wxCoord *y) const + { m_pimpl->DoGetLogicalOrigin(x, y); } + wxPoint GetLogicalOrigin() const + { wxCoord x, y; m_pimpl->DoGetLogicalOrigin(&x, &y); return wxPoint(x, y); } + + void SetDeviceOrigin(wxCoord x, wxCoord y) + { m_pimpl->SetDeviceOrigin( x, y); } + void GetDeviceOrigin(wxCoord *x, wxCoord *y) const + { m_pimpl->DoGetDeviceOrigin(x, y); } + wxPoint GetDeviceOrigin() const + { wxCoord x, y; m_pimpl->DoGetDeviceOrigin(&x, &y); return wxPoint(x, y); } + + void SetAxisOrientation(bool xLeftRight, bool yBottomUp) + { m_pimpl->SetAxisOrientation(xLeftRight, yBottomUp); } + + // mostly internal + void SetDeviceLocalOrigin( wxCoord x, wxCoord y ) + { m_pimpl->SetDeviceLocalOrigin( x, y ); } + + + // draw generic object + + void DrawObject(wxDrawObject* drawobject) + { + drawobject->Draw(*this); + CalcBoundingBox(drawobject->MinX(),drawobject->MinY()); + CalcBoundingBox(drawobject->MaxX(),drawobject->MaxY()); + } + + // ----------------------------------------------- + // the actual drawing API + + bool FloodFill(wxCoord x, wxCoord y, const wxColour& col, + int style = wxFLOOD_SURFACE) + { return m_pimpl->DoFloodFill(x, y, col, style); } + bool FloodFill(const wxPoint& pt, const wxColour& col, + int style = wxFLOOD_SURFACE) + { return m_pimpl->DoFloodFill(pt.x, pt.y, col, style); } + + // fill the area specified by rect with a radial gradient, starting from + // initialColour in the centre of the cercle and fading to destColour. + void GradientFillConcentric(const wxRect& rect, + const wxColour& initialColour, + const wxColour& destColour) + { m_pimpl->GradientFillConcentric(rect, initialColour, destColour, + wxPoint(rect.GetWidth() / 2, + rect.GetHeight() / 2)); } + + void GradientFillConcentric(const wxRect& rect, + const wxColour& initialColour, + const wxColour& destColour, + const wxPoint& circleCenter) + { m_pimpl->DoGradientFillConcentric(rect, initialColour, destColour, circleCenter); } + + // fill the area specified by rect with a linear gradient + void GradientFillLinear(const wxRect& rect, + const wxColour& initialColour, + const wxColour& destColour, + wxDirection nDirection = wxEAST) + { m_pimpl->DoGradientFillLinear(rect, initialColour, destColour, nDirection); } + + bool GetPixel(wxCoord x, wxCoord y, wxColour *col) const + { return m_pimpl->DoGetPixel(x, y, col); } + bool GetPixel(const wxPoint& pt, wxColour *col) const + { return m_pimpl->DoGetPixel(pt.x, pt.y, col); } + + void DrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2) + { m_pimpl->DoDrawLine(x1, y1, x2, y2); } + void DrawLine(const wxPoint& pt1, const wxPoint& pt2) + { m_pimpl->DoDrawLine(pt1.x, pt1.y, pt2.x, pt2.y); } + + void CrossHair(wxCoord x, wxCoord y) + { m_pimpl->DoCrossHair(x, y); } + void CrossHair(const wxPoint& pt) + { m_pimpl->DoCrossHair(pt.x, pt.y); } + + void DrawArc(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, + wxCoord xc, wxCoord yc) + { m_pimpl->DoDrawArc(x1, y1, x2, y2, xc, yc); } + void DrawArc(const wxPoint& pt1, const wxPoint& pt2, const wxPoint& centre) + { m_pimpl->DoDrawArc(pt1.x, pt1.y, pt2.x, pt2.y, centre.x, centre.y); } + + void DrawCheckMark(wxCoord x, wxCoord y, + wxCoord width, wxCoord height) + { m_pimpl->DoDrawCheckMark(x, y, width, height); } + void DrawCheckMark(const wxRect& rect) + { m_pimpl->DoDrawCheckMark(rect.x, rect.y, rect.width, rect.height); } + + void DrawEllipticArc(wxCoord x, wxCoord y, wxCoord w, wxCoord h, + double sa, double ea) + { m_pimpl->DoDrawEllipticArc(x, y, w, h, sa, ea); } + void DrawEllipticArc(const wxPoint& pt, const wxSize& sz, + double sa, double ea) + { m_pimpl->DoDrawEllipticArc(pt.x, pt.y, sz.x, sz.y, sa, ea); } + + void DrawPoint(wxCoord x, wxCoord y) + { m_pimpl->DoDrawPoint(x, y); } + void DrawPoint(const wxPoint& pt) + { m_pimpl->DoDrawPoint(pt.x, pt.y); } + + void DrawLines(int n, wxPoint points[], + wxCoord xoffset = 0, wxCoord yoffset = 0) + { m_pimpl->DoDrawLines(n, points, xoffset, yoffset); } + void DrawLines(const wxList *list, + wxCoord xoffset = 0, wxCoord yoffset = 0) + { m_pimpl->DrawLines( list, xoffset, yoffset ); } + + void DrawPolygon(int n, wxPoint points[], + wxCoord xoffset = 0, wxCoord yoffset = 0, + int fillStyle = wxODDEVEN_RULE) + { m_pimpl->DoDrawPolygon(n, points, xoffset, yoffset, fillStyle); } + + void DrawPolygon(const wxList *list, + wxCoord xoffset = 0, wxCoord yoffset = 0, + int fillStyle = wxODDEVEN_RULE) + { m_pimpl->DrawPolygon( list, xoffset, yoffset, fillStyle ); } + + void DrawPolyPolygon(int n, int count[], wxPoint points[], + wxCoord xoffset = 0, wxCoord yoffset = 0, + int fillStyle = wxODDEVEN_RULE) + { m_pimpl->DoDrawPolyPolygon(n, count, points, xoffset, yoffset, fillStyle); } + + void DrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height) + { m_pimpl->DoDrawRectangle(x, y, width, height); } + void DrawRectangle(const wxPoint& pt, const wxSize& sz) + { m_pimpl->DoDrawRectangle(pt.x, pt.y, sz.x, sz.y); } + void DrawRectangle(const wxRect& rect) + { m_pimpl->DoDrawRectangle(rect.x, rect.y, rect.width, rect.height); } + + void DrawRoundedRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height, + double radius) + { m_pimpl->DoDrawRoundedRectangle(x, y, width, height, radius); } + void DrawRoundedRectangle(const wxPoint& pt, const wxSize& sz, + double radius) + { m_pimpl->DoDrawRoundedRectangle(pt.x, pt.y, sz.x, sz.y, radius); } + void DrawRoundedRectangle(const wxRect& r, double radius) + { m_pimpl->DoDrawRoundedRectangle(r.x, r.y, r.width, r.height, radius); } + + void DrawCircle(wxCoord x, wxCoord y, wxCoord radius) + { m_pimpl->DoDrawEllipse(x - radius, y - radius, 2*radius, 2*radius); } + void DrawCircle(const wxPoint& pt, wxCoord radius) + { m_pimpl->DrawCircle(pt.x, pt.y, radius); } + + void DrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height) + { m_pimpl->DoDrawEllipse(x, y, width, height); } + void DrawEllipse(const wxPoint& pt, const wxSize& sz) + { m_pimpl->DoDrawEllipse(pt.x, pt.y, sz.x, sz.y); } + void DrawEllipse(const wxRect& rect) + { m_pimpl->DoDrawEllipse(rect.x, rect.y, rect.width, rect.height); } + + void DrawIcon(const wxIcon& icon, wxCoord x, wxCoord y) + { m_pimpl->DoDrawIcon(icon, x, y); } + void DrawIcon(const wxIcon& icon, const wxPoint& pt) + { m_pimpl->DoDrawIcon(icon, pt.x, pt.y); } + + void DrawBitmap(const wxBitmap &bmp, wxCoord x, wxCoord y, + bool useMask = false) + { m_pimpl->DoDrawBitmap(bmp, x, y, useMask); } + void DrawBitmap(const wxBitmap &bmp, const wxPoint& pt, + bool useMask = false) + { m_pimpl->DoDrawBitmap(bmp, pt.x, pt.y, useMask); } + + void DrawText(const wxString& text, wxCoord x, wxCoord y) + { m_pimpl->DoDrawText(text, x, y); } + void DrawText(const wxString& text, const wxPoint& pt) + { m_pimpl->DoDrawText(text, pt.x, pt.y); } + + void DrawRotatedText(const wxString& text, wxCoord x, wxCoord y, double angle) + { m_pimpl->DoDrawRotatedText(text, x, y, angle); } + void DrawRotatedText(const wxString& text, const wxPoint& pt, double angle) + { m_pimpl->DoDrawRotatedText(text, pt.x, pt.y, angle); } + + // this version puts both optional bitmap and the text into the given + // rectangle and aligns is as specified by alignment parameter; it also + // will emphasize the character with the given index if it is != -1 and + // return the bounding rectangle if required + void DrawLabel(const wxString& text, + const wxBitmap& image, + const wxRect& rect, + int alignment = wxALIGN_LEFT | wxALIGN_TOP, + int indexAccel = -1, + wxRect *rectBounding = NULL) + { m_pimpl->DrawLabel( text, image, rect, alignment, indexAccel, rectBounding ); } + + void DrawLabel(const wxString& text, const wxRect& rect, + int alignment = wxALIGN_LEFT | wxALIGN_TOP, + int indexAccel = -1) + { m_pimpl->DrawLabel(text, wxNullBitmap, rect, alignment, indexAccel); } + + bool Blit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height, + wxDC *source, wxCoord xsrc, wxCoord ysrc, + int rop = wxCOPY, bool useMask = false, wxCoord xsrcMask = wxDefaultCoord, wxCoord ysrcMask = wxDefaultCoord) + { + return m_pimpl->DoBlit(xdest, ydest, width, height, + source, xsrc, ysrc, rop, useMask, xsrcMask, ysrcMask); + } + bool Blit(const wxPoint& destPt, const wxSize& sz, + wxDC *source, const wxPoint& srcPt, + int rop = wxCOPY, bool useMask = false, const wxPoint& srcPtMask = wxDefaultPosition) + { + return m_pimpl->DoBlit(destPt.x, destPt.y, sz.x, sz.y, + source, srcPt.x, srcPt.y, rop, useMask, srcPtMask.x, srcPtMask.y); + } + + bool StretchBlit(wxCoord dstX, wxCoord dstY, + wxCoord dstWidth, wxCoord dstHeight, + wxDC *source, + wxCoord srcX, wxCoord srcY, + wxCoord srcWidth, wxCoord srcHeight, + int rop = wxCOPY, bool useMask = false, + wxCoord srcMaskX = wxDefaultCoord, wxCoord srcMaskY = wxDefaultCoord) + { + return m_pimpl->DoStretchBlit(dstX, dstY, dstWidth, dstHeight, + source, srcX, srcY, srcWidth, srcHeight, rop, useMask, srcMaskX, srcMaskY); + } + bool StretchBlit(const wxPoint& dstPt, const wxSize& dstSize, + wxDC *source, const wxPoint& srcPt, const wxSize& srcSize, + int rop = wxCOPY, bool useMask = false, const wxPoint& srcMaskPt = wxDefaultPosition) + { + return m_pimpl->DoStretchBlit(dstPt.x, dstPt.y, dstSize.x, dstSize.y, + source, srcPt.x, srcPt.y, srcSize.x, srcSize.y, rop, useMask, srcMaskPt.x, srcMaskPt.y); + } + + wxBitmap GetAsBitmap(const wxRect *subrect = (const wxRect *) NULL) const + { + return m_pimpl->DoGetAsBitmap(subrect); + } + +#if wxUSE_SPLINES + // TODO: this API needs fixing (wxPointList, why (!const) "wxList *"?) + void DrawSpline(wxCoord x1, wxCoord y1, + wxCoord x2, wxCoord y2, + wxCoord x3, wxCoord y3) + { m_pimpl->DrawSpline(x1,y1,x2,y2,x3,y3); } + void DrawSpline(int n, wxPoint points[]) + { m_pimpl->DrawSpline(n,points); } + + void DrawSpline(wxList *points) + { m_pimpl->DoDrawSpline(points); } +#endif // wxUSE_SPLINES + + +#if WXWIN_COMPATIBILITY_2_8 + // for compatibility with the old code when wxCoord was long everywhere + wxDEPRECATED( void GetTextExtent(const wxString& string, + long *x, long *y, + long *descent = NULL, + long *externalLeading = NULL, + const wxFont *theFont = NULL) const ); + wxDEPRECATED( void GetLogicalOrigin(long *x, long *y) const ); + wxDEPRECATED( void GetDeviceOrigin(long *x, long *y) const ); + wxDEPRECATED( void GetClippingBox(long *x, long *y, long *w, long *h) const ); +#endif // WXWIN_COMPATIBILITY_2_8 + + +protected: + wxImplDC *m_pimpl; + +private: + DECLARE_ABSTRACT_CLASS(wxImplDC) +} + + +#else // wxUSE_NEW_DC + + class WXDLLEXPORT wxDC; class WXDLLEXPORT wxDCBase; @@ -815,6 +1762,8 @@ private: DECLARE_ABSTRACT_CLASS(wxDCBase) }; +#endif // wxUSE_NEW_DC + // ---------------------------------------------------------------------------- // now include the declaration of wxDC class // ---------------------------------------------------------------------------- diff --git a/include/wx/gtk/dc.h b/include/wx/gtk/dc.h index 38168bbc6c..07e9a26851 100644 --- a/include/wx/gtk/dc.h +++ b/include/wx/gtk/dc.h @@ -10,896 +10,22 @@ #ifndef __GTKDCH__ #define __GTKDCH__ -#define wxUSE_NEW_DC 0 - -#if wxUSE_NEW_DC - -//----------------------------------------------------------------------------- -// wxDCFactory -//----------------------------------------------------------------------------- - -class WXDLLIMPEXP_CORE wxImplDC; - -class WXDLLIMPEXP_CORE wxDCFactory -{ -public: - wxDCFactory() {} - virtual ~wxDCFactory() {} - - virtual wxImplDC* CreateWindowDC( wxWindow *window ) = 0; - virtual wxImplDC* CreateClientDC( wxWindow *window ) = 0; - virtual wxImplDC* CreatePaintDC( wxWindow *window ) = 0; - virtual wxImplDC* CreateMemoryDC() = 0; - virtual wxImplDC* CreateMemoryDC( wxBitmap &bitmap ) = 0; - virtual wxImplDC* CreateMemoryDC( wxDC *dc ) = 0; - - static void SetDCFactory( wxDCFactory *factory ); - static wxDCFactory *GetFactory(); -private: - static wxDCFactory *m_factory; -}; - -//----------------------------------------------------------------------------- -// wxNativeDCFactory -//----------------------------------------------------------------------------- - -class WXDLLIMPEXP_CORE wxDCFactory -{ -public: - wxNativeDCFactory() {} - - virtual wxImplDC* CreateWindowDC( wxWindow *window ); - virtual wxImplDC* CreateClientDC( wxWindow *window ); - virtual wxImplDC* CreatePaintDC( wxWindow *window ); - virtual wxImplDC* CreateMemoryDC(); - virtual wxImplDC* CreateMemoryDC( wxBitmap &bitmap ); - virtual wxImplDC* CreateMemoryDC( wxDC *dc ); -}; - -//----------------------------------------------------------------------------- -// wxImplDC -//----------------------------------------------------------------------------- - -class WXDLLIMPEXP_CORE wxImplDC: public wxObject -{ -public: - wxImplDC( wxDC *owner ); - ~wxImplDC(); - - wxDC *GetOwner() { return m_owner; } - - virtual bool IsOk() const { return m_ok; } - - // query capabilities - - virtual bool CanDrawBitmap() const = 0; - virtual bool CanGetTextExtent() const = 0; - - // query dimension, colour deps, resolution - - virtual void DoGetSize(int *width, int *height) const = 0; - virtual void DoGetSizeMM(int* width, int* height) const = 0; - - virtual int GetDepth() const = 0; - virtual wxSize GetPPI() const = 0; - - // Right-To-Left (RTL) modes - - virtual void SetLayoutDirection(wxLayoutDirection WXUNUSED(dir)) { } - virtual wxLayoutDirection GetLayoutDirection() const { return wxLayout_Default; } - - // page and document - - virtual bool StartDoc(const wxString& WXUNUSED(message)) { return true; } - virtual void EndDoc() { } - - virtual void StartPage() { } - virtual void EndPage() { } - - // bounding box - - virtual void CalcBoundingBox(wxCoord x, wxCoord y); - { - if ( m_isBBoxValid ) - { - if ( x < m_minX ) m_minX = x; - if ( y < m_minY ) m_minY = y; - if ( x > m_maxX ) m_maxX = x; - if ( y > m_maxY ) m_maxY = y; - } - else - { - m_isBBoxValid = true; - - m_minX = x; - m_minY = y; - m_maxX = x; - m_maxY = y; - } - } - void ResetBoundingBox(); - { - m_isBBoxValid = false; - - m_minX = m_maxX = m_minY = m_maxY = 0; - } - - wxCoord MinX() const { return m_minX; } - wxCoord MaxX() const { return m_maxX; } - wxCoord MinY() const { return m_minY; } - wxCoord MaxY() const { return m_maxY; } - - // setters and getters - - virtual void SetFont(const wxFont& font) = 0; - virtual const wxFont& GetFont() const { return m_font; } - - virtual void SetPen(const wxPen& pen) = 0; - virtual const wxPen& GetPen() const { return m_pen; } - - virtual void SetBrush(const wxBrush& brush) = 0; - virtual const wxBrush& GetBrush() const { return m_brush; } - - virtual void SetBackground(const wxBrush& brush) = 0; - virtual const wxBrush& GetBackground() const { return m_backgroundBrush; } - - virtual void SetBackgroundMode(int mode) = 0; - virtual int GetBackgroundMode() const { return m_backgroundMode; } - - virtual void SetTextForeground(const wxColour& colour) - { m_textForegroundColour = colour; } - virtual const wxColour& GetTextForeground() const { return m_textForegroundColour; } - - virtual void SetTextBackground(const wxColour& colour) - { m_textBackgroundColour = colour; } - virtual const wxColour& GetTextBackground() const { return m_textBackgroundColour; } - -#if wxUSE_PALETTE - virtual void SetPalette(const wxPalette& palette) = 0; -#endif // wxUSE_PALETTE - - // logical functions - - virtual void SetLogicalFunction(int function) = 0; - virtual int GetLogicalFunction() const { return m_logicalFunction; } - - // text measurement - - virtual wxCoord GetCharHeight() const = 0; - virtual wxCoord GetCharWidth() const = 0; - virtual void DoGetTextExtent(const wxString& string, - wxCoord *x, wxCoord *y, - wxCoord *descent = NULL, - wxCoord *externalLeading = NULL, - const wxFont *theFont = NULL) const = 0; - virtual void GetMultiLineTextExtent(const wxString& string, - wxCoord *width, - wxCoord *height, - wxCoord *heightLine = NULL, - const wxFont *font = NULL) const; - virtual bool DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths) const; - - // clearing - - virtual void Clear() = 0; - - // clipping - - virtual void DoSetClippingRegion(wxCoord x, wxCoord y, - wxCoord width, wxCoord height) = 0; - virtual void DoSetClippingRegionAsRegion(const wxRegion& region) = 0; - - virtual void DoGetClippingBox(wxCoord *x, wxCoord *y, - wxCoord *w, wxCoord *h) const - { - if ( x ) - *x = m_clipX1; - if ( y ) - *y = m_clipY1; - if ( w ) - *w = m_clipX2 - m_clipX1; - if ( h ) - *h = m_clipY2 - m_clipY1; - } - - virtual void DestroyClippingRegion() { ResetClipping(); } - - - // coordinates conversions and transforms - - virtual wxCoord DeviceToLogicalX(wxCoord x) const; - virtual wxCoord DeviceToLogicalY(wxCoord y) const; - virtual wxCoord DeviceToLogicalXRel(wxCoord x) const; - virtual wxCoord DeviceToLogicalYRel(wxCoord y) const; - virtual wxCoord LogicalToDeviceX(wxCoord x) const; - virtual wxCoord LogicalToDeviceY(wxCoord y) const; - virtual wxCoord LogicalToDeviceXRel(wxCoord x) const; - virtual wxCoord LogicalToDeviceYRel(wxCoord y) const; - - virtual void SetMapMode(int mode); - virtual int GetMapMode() const { return m_mappingMode; } - - virtual void SetUserScale(double x, double y); - virtual void GetUserScale(double *x, double *y) const - { - if ( x ) *x = m_userScaleX; - if ( y ) *y = m_userScaleY; - } - - virtual void SetLogicalScale(double x, double y); - virtual void GetLogicalScale(double *x, double *y) - { - if ( x ) *x = m_logicalScaleX; - if ( y ) *y = m_logicalScaleY; - } - - virtual void SetLogicalOrigin(wxCoord x, wxCoord y); - virtual void DoGetLogicalOrigin(wxCoord *x, wxCoord *y) const - { - if ( x ) *x = m_logicalOriginX; - if ( y ) *y = m_logicalOriginY; - } - - virtual void SetDeviceOrigin(wxCoord x, wxCoord y); - virtual void DoGetDeviceOrigin(wxCoord *x, wxCoord *y) const - { - if ( x ) *x = m_deviceOriginX; - if ( y ) *y = m_deviceOriginY; - } - - virtual void SetDeviceLocalOrigin( wxCoord x, wxCoord y ); - - virtual void ComputeScaleAndOrigin(); - - // this needs to overidden if the axis is inverted - virtual void SetAxisOrientation(bool xLeftRight, bool yBottomUp); - - // --------------------------------------------------------- - // the actual drawing API - - virtual bool DoFloodFill(wxCoord x, wxCoord y, const wxColour& col, - int style = wxFLOOD_SURFACE) = 0; - - virtual void DoGradientFillLinear(const wxRect& rect, - const wxColour& initialColour, - const wxColour& destColour, - wxDirection nDirection = wxEAST); - - virtual void DoGradientFillConcentric(const wxRect& rect, - const wxColour& initialColour, - const wxColour& destColour, - const wxPoint& circleCenter); - - virtual bool DoGetPixel(wxCoord x, wxCoord y, wxColour *col) const = 0; - - virtual void DoDrawPoint(wxCoord x, wxCoord y) = 0; - virtual void DoDrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2) = 0; - - virtual void DoDrawArc(wxCoord x1, wxCoord y1, - wxCoord x2, wxCoord y2, - wxCoord xc, wxCoord yc) = 0; - virtual void DoDrawCheckMark(wxCoord x, wxCoord y, - wxCoord width, wxCoord height); - virtual void DoDrawEllipticArc(wxCoord x, wxCoord y, wxCoord w, wxCoord h, - double sa, double ea) = 0; - - virtual void DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height) = 0; - virtual void DoDrawRoundedRectangle(wxCoord x, wxCoord y, - wxCoord width, wxCoord height, - double radius) = 0; - virtual void DoDrawEllipse(wxCoord x, wxCoord y, - wxCoord width, wxCoord height) = 0; - - virtual void DoCrossHair(wxCoord x, wxCoord y) = 0; - - virtual void DoDrawIcon(const wxIcon& icon, wxCoord x, wxCoord y) = 0; - virtual void DoDrawBitmap(const wxBitmap &bmp, wxCoord x, wxCoord y, - bool useMask = false) = 0; - - virtual void DoDrawText(const wxString& text, wxCoord x, wxCoord y) = 0; - virtual void DoDrawRotatedText(const wxString& text, - wxCoord x, wxCoord y, double angle) = 0; - - virtual bool DoBlit(wxCoord xdest, wxCoord ydest, - wxCoord width, wxCoord height, - wxDC *source, - wxCoord xsrc, wxCoord ysrc, - int rop = wxCOPY, - bool useMask = false, - wxCoord xsrcMask = wxDefaultCoord, - wxCoord ysrcMask = wxDefaultCoord) = 0; - - virtual bool DoStretchBlit(wxCoord xdest, wxCoord ydest, - wxCoord dstWidth, wxCoord dstHeight, - wxDC *source, - wxCoord xsrc, wxCoord ysrc, - wxCoord srcWidth, wxCoord srcHeight, - int rop = wxCOPY, - bool useMask = false, - wxCoord xsrcMask = wxDefaultCoord, - wxCoord ysrcMask = wxDefaultCoord); - - virtual wxBitmap DoGetAsBitmap(const wxRect *WXUNUSED(subrect)) const - { return wxNullBitmap; } - - - virtual void DoDrawLines(int n, wxPoint points[], - wxCoord xoffset, wxCoord yoffset) = 0; - virtual void DoDrawPolygon(int n, wxPoint points[], - wxCoord xoffset, wxCoord yoffset, - int fillStyle = wxODDEVEN_RULE) = 0; - virtual void DoDrawPolyPolygon(int n, int count[], wxPoint points[], - wxCoord xoffset, wxCoord yoffset, - int fillStyle); - - - -#if wxUSE_SPLINES - virtual void DoDrawSpline(wxList *points); -#endif - -private: - wxDC *m_owner; - -protected: - // unset clipping variables (after clipping region was destroyed) - void ResetClipping() - { - m_clipping = false; - - m_clipX1 = m_clipX2 = m_clipY1 = m_clipY2 = 0; - } - - // flags - bool m_colour:1; - bool m_ok:1; - bool m_clipping:1; - bool m_isInteractive:1; - bool m_isBBoxValid:1; - - // coordinate system variables - - wxCoord m_logicalOriginX, m_logicalOriginY; - wxCoord m_deviceOriginX, m_deviceOriginY; // Usually 0,0, can be change by user - - wxCoord m_deviceLocalOriginX, m_deviceLocalOriginY; // non-zero if native top-left corner - // is not at 0,0. This was the case under - // Mac's GrafPorts (coordinate system - // used toplevel window's origin) and - // e.g. for Postscript, where the native - // origin in the bottom left corner. - double m_logicalScaleX, m_logicalScaleY; - double m_userScaleX, m_userScaleY; - double m_scaleX, m_scaleY; // calculated from logical scale and user scale - - int m_signX, m_signY; // Used by SetAxisOrientation() to invert the axes - - // what is a mm on a screen you don't know the size of? - double m_mm_to_pix_x, - m_mm_to_pix_y; - - // bounding and clipping boxes - wxCoord m_minX, m_minY, m_maxX, m_maxY; - wxCoord m_clipX1, m_clipY1, m_clipX2, m_clipY2; - - int m_logicalFunction; - int m_backgroundMode; - int m_mappingMode; - - wxPen m_pen; - wxBrush m_brush; - wxBrush m_backgroundBrush; - wxColour m_textForegroundColour; - wxColour m_textBackgroundColour; - wxFont m_font; - -#if wxUSE_PALETTE - wxPalette m_palette; - bool m_hasCustomPalette; -#endif // wxUSE_PALETTE - -private: - DECLARE_ABSTRACT_CLASS(wxImplDC) -} - - -class wxDC: public wxObject -{ -public: - wxDC() { m_pimpl = NULL; } - - bool IsOk() const - { return m_pimpl && m_pimpl->IsOk(); } - - // query capabilities - - bool CanDrawBitmap() const - { return m_pimpl->CanDrawBitmap(); } - bool CanGetTextExtent() const - { return m_pimpl->CanGetTextExtent(); } - - // query dimension, colour deps, resolution - - void GetSize(int *width, int *height) const - { m_pimpl->DoGetSize(width, height); } - - wxSize GetSize() const - { - int w, h; - m_pimpl->DoGetSize(&w, &h); - return wxSize(w, h); - } - - void GetSizeMM(int* width, int* height) const - { m_pimpl->DoGetSizeMM(width, height); } - wxSize GetSizeMM() const - { - int w, h; - m_pimpl->DoGetSizeMM(&w, &h); - return wxSize(w, h); - } - - int GetDepth() const - { return m_pimpl->GetDepth(); } - wxSize GetPPI() const - { return m_pimpl->GetPPI(); } - - // Right-To-Left (RTL) modes - - void SetLayoutDirection(wxLayoutDirection dir) - { m_pimpl->SetLayoutDirection( dir ); } - wxLayoutDirection GetLayoutDirection() const - { return m_pimpl->GetLayoutDirection(); } - - // page and document - - bool StartDoc(const wxString& message) - { return m_pimpl->StartDoc(message); } - void EndDoc() - { m_pimpl->EndDoc(); } - - void StartPage() - { m_pimpl->StartPage(); } - void EndPage() - { m_pimpl->EndPage(); } - - // bounding box - - void CalcBoundingBox(wxCoord x, wxCoord y) - { m_pimpl->CalcBoundingBox(x,y); } - void ResetBoundingBox() - { m_pimpl->ResetBoundingBox(); } - - wxCoord MinX() const - { return m_pimpl->MinX(); } - wxCoord MaxX() const - { return m_pimpl->MaxX(); } - wxCoord MinY() const - { return m_pimpl->MinY(); } - wxCoord MaxY() const - { return m_pimpl->MaxY(); } - - // setters and getters - - void SetFont(const wxFont& font) - { m_pimpl->SetFont( font ); } - const wxFont& GetFont() const - { return m_pimpl->GetFont(); } - - void SetPen(const wxPen& pen) - { m_pimpl->SetPen( pen ); } - const wxPen& GetPen() const - { return m_pimpl->GetPen(); } - - void SetBrush(const wxBrush& brush) - { m_pimpl->SetBrush( brush ); } - const wxBrush& GetBrush() const - { return m_pimpl->GetBrush(); } - - void SetBackground(const wxBrush& brush) - { m_pimpl->SetBackground( brush ); } - const wxBrush& GetBackground() const - { return m_pimpl->GetBackground(); } - - void SetBackgroundMode(int mode) - { m_pimpl->SetBackground( mode ); } - int GetBackgroundMode() const - { return m_pimpl->GetBackground(); } - - void SetTextForeground(const wxColour& colour) - { m_pimpl->SetTextForeground(colour); } - const wxColour& GetTextForeground() const - { return m_pimpl->GetTextForeground(); } - - void SetTextBackground(const wxColour& colour) - { m_pimpl->SetTextBackground(colour); } - const wxColour& GetTextBackground() const - { return m_pimpl->GetTextBackground(); } - -#if wxUSE_PALETTE - void SetPalette(const wxPalette& palette) - { m_pimpl->SetPalette(palette); } -#endif // wxUSE_PALETTE - - // logical functions - - void SetLogicalFunction(int function) - { m_pimpl->SetLogicalFunction(function); } - int GetLogicalFunction() const - { return m_pimpl->GetLogicalFunction(); } - - // text measurement - - wxCoord GetCharHeight() const - { return m_pimpl->GetCharHeight(); } - wxCoord GetCharWidth() const - { return m_pimpl->GetCharWidth(); } - - void GetTextExtent(const wxString& string, - wxCoord *x, wxCoord *y, - wxCoord *descent = NULL, - wxCoord *externalLeading = NULL, - const wxFont *theFont = NULL) const - { m_pimpl->DoGetTextExtent(string, x, y, descent, externalLeading, theFont); } - - wxSize GetTextExtent(const wxString& string) const - { - wxCoord w, h; - m_pimpl->DoGetTextExtent(string, &w, &h); - return wxSize(w, h); - } - - void GetMultiLineTextExtent(const wxString& string, - wxCoord *width, - wxCoord *height, - wxCoord *heightLine = NULL, - const wxFont *font = NULL) const - { m_pimpl->GetMultiLineTextExtent( string, width, height, heightLine, font ); } - - wxSize GetMultiLineTextExtent(const wxString& string) const - { - wxCoord w, h; - m_pimpl->GetMultiLineTextExtent(string, &w, &h); - return wxSize(w, h); - } - - bool GetPartialTextExtents(const wxString& text, wxArrayInt& widths) const - { return m_pimpl->DoGetPartialTextExtents(text, widths); } - - // clearing - - void Clear() - { m_pimpl->Clear(); } - - // clipping - - void SetClippingRegion(wxCoord x, wxCoord y, wxCoord width, wxCoord height) - { m_pimpl->DoSetClippingRegion(x, y, width, height); } - void SetClippingRegion(const wxPoint& pt, const wxSize& sz) - { m_pimpl->DoSetClippingRegion(pt.x, pt.y, sz.x, sz.y); } - void SetClippingRegion(const wxRect& rect) - { m_pimpl->DoSetClippingRegion(rect.x, rect.y, rect.width, rect.height); } - void SetClippingRegion(const wxRegion& region) - { m_pimpl->DoSetClippingRegionAsRegion(region); } - - void DestroyClippingRegion() - { m_pimpl->DestroyClippingRegion(); } - - void GetClippingBox(wxCoord *x, wxCoord *y, wxCoord *w, wxCoord *h) const - { m_pimpl->DoGetClippingBox(x, y, w, h); } - void GetClippingBox(wxRect& rect) const - { m_pimpl->DoGetClippingBox(&rect.x, &rect.y, &rect.width, &rect.height); } - - // coordinates conversions and transforms - - wxCoord DeviceToLogicalX(wxCoord x) const - { return m_pimpl->DeviceToLogicalX(x); } - wxCoord DeviceToLogicalY(wxCoord y) const; - { return m_pimpl->DeviceToLogicalY(y); } - wxCoord DeviceToLogicalXRel(wxCoord x) const; - { return m_pimpl->DeviceToLogicalXRel(x); } - wxCoord DeviceToLogicalYRel(wxCoord y) const; - { return m_pimpl->DeviceToLogicalYRel(y); } - wxCoord LogicalToDeviceX(wxCoord x) const; - { return m_pimpl->LogicalToDeviceX(x); } - wxCoord LogicalToDeviceY(wxCoord y) const; - { return m_pimpl->LogicalToDeviceY(y); } - wxCoord LogicalToDeviceXRel(wxCoord x) const; - { return m_pimpl->LogicalToDeviceXRel(x); } - wxCoord LogicalToDeviceYRel(wxCoord y) const; - { return m_pimpl->LogicalToDeviceYRel(y); } - - void SetMapMode(int mode) - { m_pimpl->SetMapMode(mode); } - int GetMapMode() const - { return m_pimpl->GetMapMode(); } - - void SetUserScale(double x, double y) - { m_pimpl->SetUserScale(x,y); } - void GetUserScale(double *x, double *y) const - { m_pimpl->GetUserScale( x, y ); } - - void SetLogicalScale(double x, double y) - { m_pimpl->SetLogicalScale( x, y ); } - void GetLogicalScale(double *x, double *y) - { m_pimpl->GetLogicalScale( x, y ); } - - void SetLogicalOrigin(wxCoord x, wxCoord y) - { m_pimpl->SetLogicalOrigin(x,y); } - void GetLogicalOrigin(wxCoord *x, wxCoord *y) const - { m_pimpl->DoGetLogicalOrigin(x, y); } - wxPoint GetLogicalOrigin() const - { wxCoord x, y; m_pimpl->DoGetLogicalOrigin(&x, &y); return wxPoint(x, y); } - - void SetDeviceOrigin(wxCoord x, wxCoord y) - { m_pimpl->SetDeviceOrigin( x, y); } - void GetDeviceOrigin(wxCoord *x, wxCoord *y) const - { m_pimpl->DoGetDeviceOrigin(x, y); } - wxPoint GetDeviceOrigin() const - { wxCoord x, y; m_pimpl->DoGetDeviceOrigin(&x, &y); return wxPoint(x, y); } - - void SetAxisOrientation(bool xLeftRight, bool yBottomUp) - { m_pimpl->SetAxisOrientation(xLeftRight, yBottomUp); } - - // mostly internal - void SetDeviceLocalOrigin( wxCoord x, wxCoord y ) - { m_pimpl->SetDeviceLocalOrigin( x, y ); } - - - // draw generic object - - void DrawObject(wxDrawObject* drawobject) - { - drawobject->Draw(*this); - CalcBoundingBox(drawobject->MinX(),drawobject->MinY()); - CalcBoundingBox(drawobject->MaxX(),drawobject->MaxY()); - } - - // ----------------------------------------------- - // the actual drawing API - - bool FloodFill(wxCoord x, wxCoord y, const wxColour& col, - int style = wxFLOOD_SURFACE) - { return m_pimpl->DoFloodFill(x, y, col, style); } - bool FloodFill(const wxPoint& pt, const wxColour& col, - int style = wxFLOOD_SURFACE) - { return m_pimpl->DoFloodFill(pt.x, pt.y, col, style); } - - // fill the area specified by rect with a radial gradient, starting from - // initialColour in the centre of the cercle and fading to destColour. - void GradientFillConcentric(const wxRect& rect, - const wxColour& initialColour, - const wxColour& destColour) - { m_pimpl->GradientFillConcentric(rect, initialColour, destColour, - wxPoint(rect.GetWidth() / 2, - rect.GetHeight() / 2)); } - - void GradientFillConcentric(const wxRect& rect, - const wxColour& initialColour, - const wxColour& destColour, - const wxPoint& circleCenter) - { m_pimpl->DoGradientFillConcentric(rect, initialColour, destColour, circleCenter); } - - // fill the area specified by rect with a linear gradient - void GradientFillLinear(const wxRect& rect, - const wxColour& initialColour, - const wxColour& destColour, - wxDirection nDirection = wxEAST) - { m_pimpl->DoGradientFillLinear(rect, initialColour, destColour, nDirection); } - - bool GetPixel(wxCoord x, wxCoord y, wxColour *col) const - { return m_pimpl->DoGetPixel(x, y, col); } - bool GetPixel(const wxPoint& pt, wxColour *col) const - { return m_pimpl->DoGetPixel(pt.x, pt.y, col); } - - void DrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2) - { m_pimpl->DoDrawLine(x1, y1, x2, y2); } - void DrawLine(const wxPoint& pt1, const wxPoint& pt2) - { m_pimpl->DoDrawLine(pt1.x, pt1.y, pt2.x, pt2.y); } - - void CrossHair(wxCoord x, wxCoord y) - { m_pimpl->DoCrossHair(x, y); } - void CrossHair(const wxPoint& pt) - { m_pimpl->DoCrossHair(pt.x, pt.y); } - - void DrawArc(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, - wxCoord xc, wxCoord yc) - { m_pimpl->DoDrawArc(x1, y1, x2, y2, xc, yc); } - void DrawArc(const wxPoint& pt1, const wxPoint& pt2, const wxPoint& centre) - { m_pimpl->DoDrawArc(pt1.x, pt1.y, pt2.x, pt2.y, centre.x, centre.y); } - - void DrawCheckMark(wxCoord x, wxCoord y, - wxCoord width, wxCoord height) - { m_pimpl->DoDrawCheckMark(x, y, width, height); } - void DrawCheckMark(const wxRect& rect) - { m_pimpl->DoDrawCheckMark(rect.x, rect.y, rect.width, rect.height); } - - void DrawEllipticArc(wxCoord x, wxCoord y, wxCoord w, wxCoord h, - double sa, double ea) - { m_pimpl->DoDrawEllipticArc(x, y, w, h, sa, ea); } - void DrawEllipticArc(const wxPoint& pt, const wxSize& sz, - double sa, double ea) - { m_pimpl->DoDrawEllipticArc(pt.x, pt.y, sz.x, sz.y, sa, ea); } - - void DrawPoint(wxCoord x, wxCoord y) - { m_pimpl->DoDrawPoint(x, y); } - void DrawPoint(const wxPoint& pt) - { m_pimpl->DoDrawPoint(pt.x, pt.y); } - - void DrawLines(int n, wxPoint points[], - wxCoord xoffset = 0, wxCoord yoffset = 0) - { m_pimpl->DoDrawLines(n, points, xoffset, yoffset); } - void DrawLines(const wxList *list, - wxCoord xoffset = 0, wxCoord yoffset = 0) - { m_pimpl->DrawLines( list, xoffset, yoffset ); } - - void DrawPolygon(int n, wxPoint points[], - wxCoord xoffset = 0, wxCoord yoffset = 0, - int fillStyle = wxODDEVEN_RULE) - { m_pimpl->DoDrawPolygon(n, points, xoffset, yoffset, fillStyle); } - - void DrawPolygon(const wxList *list, - wxCoord xoffset = 0, wxCoord yoffset = 0, - int fillStyle = wxODDEVEN_RULE) - { m_pimpl->DrawPolygon( list, xoffset, yoffset, fillStyle ); } - - void DrawPolyPolygon(int n, int count[], wxPoint points[], - wxCoord xoffset = 0, wxCoord yoffset = 0, - int fillStyle = wxODDEVEN_RULE) - { m_pimpl->DoDrawPolyPolygon(n, count, points, xoffset, yoffset, fillStyle); } - - void DrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height) - { m_pimpl->DoDrawRectangle(x, y, width, height); } - void DrawRectangle(const wxPoint& pt, const wxSize& sz) - { m_pimpl->DoDrawRectangle(pt.x, pt.y, sz.x, sz.y); } - void DrawRectangle(const wxRect& rect) - { m_pimpl->DoDrawRectangle(rect.x, rect.y, rect.width, rect.height); } - - void DrawRoundedRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height, - double radius) - { m_pimpl->DoDrawRoundedRectangle(x, y, width, height, radius); } - void DrawRoundedRectangle(const wxPoint& pt, const wxSize& sz, - double radius) - { m_pimpl->DoDrawRoundedRectangle(pt.x, pt.y, sz.x, sz.y, radius); } - void DrawRoundedRectangle(const wxRect& r, double radius) - { m_pimpl->DoDrawRoundedRectangle(r.x, r.y, r.width, r.height, radius); } - - void DrawCircle(wxCoord x, wxCoord y, wxCoord radius) - { m_pimpl->DoDrawEllipse(x - radius, y - radius, 2*radius, 2*radius); } - void DrawCircle(const wxPoint& pt, wxCoord radius) - { m_pimpl->DrawCircle(pt.x, pt.y, radius); } - - void DrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height) - { m_pimpl->DoDrawEllipse(x, y, width, height); } - void DrawEllipse(const wxPoint& pt, const wxSize& sz) - { m_pimpl->DoDrawEllipse(pt.x, pt.y, sz.x, sz.y); } - void DrawEllipse(const wxRect& rect) - { m_pimpl->DoDrawEllipse(rect.x, rect.y, rect.width, rect.height); } - - void DrawIcon(const wxIcon& icon, wxCoord x, wxCoord y) - { m_pimpl->DoDrawIcon(icon, x, y); } - void DrawIcon(const wxIcon& icon, const wxPoint& pt) - { m_pimpl->DoDrawIcon(icon, pt.x, pt.y); } - - void DrawBitmap(const wxBitmap &bmp, wxCoord x, wxCoord y, - bool useMask = false) - { m_pimpl->DoDrawBitmap(bmp, x, y, useMask); } - void DrawBitmap(const wxBitmap &bmp, const wxPoint& pt, - bool useMask = false) - { m_pimpl->DoDrawBitmap(bmp, pt.x, pt.y, useMask); } - - void DrawText(const wxString& text, wxCoord x, wxCoord y) - { m_pimpl->DoDrawText(text, x, y); } - void DrawText(const wxString& text, const wxPoint& pt) - { m_pimpl->DoDrawText(text, pt.x, pt.y); } - - void DrawRotatedText(const wxString& text, wxCoord x, wxCoord y, double angle) - { m_pimpl->DoDrawRotatedText(text, x, y, angle); } - void DrawRotatedText(const wxString& text, const wxPoint& pt, double angle) - { m_pimpl->DoDrawRotatedText(text, pt.x, pt.y, angle); } - - // this version puts both optional bitmap and the text into the given - // rectangle and aligns is as specified by alignment parameter; it also - // will emphasize the character with the given index if it is != -1 and - // return the bounding rectangle if required - void DrawLabel(const wxString& text, - const wxBitmap& image, - const wxRect& rect, - int alignment = wxALIGN_LEFT | wxALIGN_TOP, - int indexAccel = -1, - wxRect *rectBounding = NULL) - { m_pimpl->DrawLabel( text, image, rect, alignment, indexAccel, rectBounding ); } - - void DrawLabel(const wxString& text, const wxRect& rect, - int alignment = wxALIGN_LEFT | wxALIGN_TOP, - int indexAccel = -1) - { m_pimpl->DrawLabel(text, wxNullBitmap, rect, alignment, indexAccel); } - - bool Blit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height, - wxDC *source, wxCoord xsrc, wxCoord ysrc, - int rop = wxCOPY, bool useMask = false, wxCoord xsrcMask = wxDefaultCoord, wxCoord ysrcMask = wxDefaultCoord) - { - return m_pimpl->DoBlit(xdest, ydest, width, height, - source, xsrc, ysrc, rop, useMask, xsrcMask, ysrcMask); - } - bool Blit(const wxPoint& destPt, const wxSize& sz, - wxDC *source, const wxPoint& srcPt, - int rop = wxCOPY, bool useMask = false, const wxPoint& srcPtMask = wxDefaultPosition) - { - return m_pimpl->DoBlit(destPt.x, destPt.y, sz.x, sz.y, - source, srcPt.x, srcPt.y, rop, useMask, srcPtMask.x, srcPtMask.y); - } - - bool StretchBlit(wxCoord dstX, wxCoord dstY, - wxCoord dstWidth, wxCoord dstHeight, - wxDC *source, - wxCoord srcX, wxCoord srcY, - wxCoord srcWidth, wxCoord srcHeight, - int rop = wxCOPY, bool useMask = false, - wxCoord srcMaskX = wxDefaultCoord, wxCoord srcMaskY = wxDefaultCoord) - { - return m_pimpl->DoStretchBlit(dstX, dstY, dstWidth, dstHeight, - source, srcX, srcY, srcWidth, srcHeight, rop, useMask, srcMaskX, srcMaskY); - } - bool StretchBlit(const wxPoint& dstPt, const wxSize& dstSize, - wxDC *source, const wxPoint& srcPt, const wxSize& srcSize, - int rop = wxCOPY, bool useMask = false, const wxPoint& srcMaskPt = wxDefaultPosition) - { - return m_pimpl->DoStretchBlit(dstPt.x, dstPt.y, dstSize.x, dstSize.y, - source, srcPt.x, srcPt.y, srcSize.x, srcSize.y, rop, useMask, srcMaskPt.x, srcMaskPt.y); - } - - wxBitmap GetAsBitmap(const wxRect *subrect = (const wxRect *) NULL) const - { - return m_pimpl->DoGetAsBitmap(subrect); - } - -#if wxUSE_SPLINES - // TODO: this API needs fixing (wxPointList, why (!const) "wxList *"?) - void DrawSpline(wxCoord x1, wxCoord y1, - wxCoord x2, wxCoord y2, - wxCoord x3, wxCoord y3) - { m_pimpl->DrawSpline(x1,y1,x2,y2,x3,y3); } - void DrawSpline(int n, wxPoint points[]) - { m_pimpl->DrawSpline(n,points); } - - void DrawSpline(wxList *points) - { m_pimpl->DoDrawSpline(points); } -#endif // wxUSE_SPLINES - - -#if WXWIN_COMPATIBILITY_2_8 - // for compatibility with the old code when wxCoord was long everywhere - wxDEPRECATED( void GetTextExtent(const wxString& string, - long *x, long *y, - long *descent = NULL, - long *externalLeading = NULL, - const wxFont *theFont = NULL) const ); - wxDEPRECATED( void GetLogicalOrigin(long *x, long *y) const ); - wxDEPRECATED( void GetDeviceOrigin(long *x, long *y) const ); - wxDEPRECATED( void GetClippingBox(long *x, long *y, long *w, long *h) const ); -#endif // WXWIN_COMPATIBILITY_2_8 - - -protected: - wxImplDC *m_pimpl; - -private: - DECLARE_ABSTRACT_CLASS(wxImplDC) -} - - -#endif //----------------------------------------------------------------------------- // wxDC //----------------------------------------------------------------------------- -class WXDLLIMPEXP_CORE wxDC : public wxDCBase +#if wxUSE_NEW_DC +class WXDLLIMPEXP_CORE wxGTKImplDC : public wxDC +#else +#define wxGTKImplDC wxDC +class WXDLLIMPEXP_CORE wxGTKImplDC : public wxDCBase +#endif + { public: - wxDC(); - virtual ~wxDC() { } + wxGTKImplDC(); + virtual ~wxGTKImplDC() { } #if wxUSE_PALETTE void SetColourMap( const wxPalette& palette ) { SetPalette(palette); }; @@ -931,7 +57,7 @@ protected: virtual void DoGetSizeMM(int* width, int* height) const; private: - DECLARE_ABSTRACT_CLASS(wxDC) + DECLARE_ABSTRACT_CLASS(wxGTKImplDC) }; // this must be defined when wxDC::Blit() honours the DC origian and needed to diff --git a/include/wx/gtk/dcclient.h b/include/wx/gtk/dcclient.h index 3873241c17..1e1b37b956 100644 --- a/include/wx/gtk/dcclient.h +++ b/include/wx/gtk/dcclient.h @@ -19,13 +19,18 @@ class WXDLLIMPEXP_CORE wxWindow; // wxWindowDC //----------------------------------------------------------------------------- +#if wxUSE_NEW_DC +class WXDLLIMPEXP_CORE wxGTKWindowImplDC : public wxGTKImplDC +#else +#define wxGTKWindowImplDC wxWindowDC class WXDLLIMPEXP_CORE wxWindowDC : public wxDC +#endif { public: - wxWindowDC(); - wxWindowDC( wxWindow *win ); + wxGTKWindowImplDC(); + wxGTKWindowImplDC( wxWindow *win ); - virtual ~wxWindowDC(); + virtual ~wxGTKWindowImplDC(); virtual bool CanDrawBitmap() const { return true; } virtual bool CanGetTextExtent() const { return true; } @@ -129,38 +134,48 @@ public: virtual GdkWindow *GetGDKWindow() const { return m_window; } private: - DECLARE_DYNAMIC_CLASS(wxWindowDC) + DECLARE_DYNAMIC_CLASS(wxGTKWindowImplDC) }; //----------------------------------------------------------------------------- // wxClientDC //----------------------------------------------------------------------------- +#if wxUSE_NEW_DC +class WXDLLIMPEXP_CORE wxGTKClientImplDC : public wxGTKWindowImplDC +#else +#define wxGTKClientImplDC wxClientDC class WXDLLIMPEXP_CORE wxClientDC : public wxWindowDC +#endif { public: - wxClientDC() { } - wxClientDC( wxWindow *win ); + wxGTKClientImplDC() { } + wxGTKClientImplDC( wxWindow *win ); protected: virtual void DoGetSize(int *width, int *height) const; private: - DECLARE_DYNAMIC_CLASS(wxClientDC) + DECLARE_DYNAMIC_CLASS(wxGTKClientImplDC) }; //----------------------------------------------------------------------------- // wxPaintDC //----------------------------------------------------------------------------- +#if wxUSE_NEW_DC +class WXDLLIMPEXP_CORE wxGTKPaintImplDC : public wxGTKClientImplDC +#else +#define wxGTKPaintImplDC wxPaintDC class WXDLLIMPEXP_CORE wxPaintDC : public wxClientDC +#endif { public: - wxPaintDC() { } - wxPaintDC( wxWindow *win ); + wxGTKPaintImplDC() { } + wxGTKPaintImplDC( wxWindow *win ); private: - DECLARE_DYNAMIC_CLASS(wxPaintDC) + DECLARE_DYNAMIC_CLASS(wxGTKPaintImplDC) }; #endif // __GTKDCCLIENTH__ diff --git a/src/common/dcbase.cpp b/src/common/dcbase.cpp index 32a0d7cb5f..249af182a6 100644 --- a/src/common/dcbase.cpp +++ b/src/common/dcbase.cpp @@ -31,6 +31,1449 @@ #include "wx/math.h" #endif + + +#if wxUSE_NEW_DC + +//---------------------------------------------------------------------------- +// wxDCFactory +//---------------------------------------------------------------------------- + +wxDCFactory *wxDCFactory::m_factory = NULL; + +void wxDCFactory::SetDCFactory( wxDCFactory *factory ) +{ + if (wxDCFactory::m_factory) + delete wxDCFactory::m_factory; + + wxDCFactory::m_factory = factory; +} + +wxDCFactory *wxDCFactory::GetFactory() +{ + if (!wxDCFactory::m_factory) + wxDCFactory::m_factory = new wxNativeDCFactory; + + return wxDCFactory::m_factory; +} + +//----------------------------------------------------------------------------- +// wxNativeDCFactory +//----------------------------------------------------------------------------- + +wxImplDC* wxNativeDCFactory::CreateWindowDC() +{ +#if defined(__WXMSW__) + return new wxWindowsWindowImplDC(); +#elif defined(__WXGTK20__) + return new wxGTKWindowImplDC(); +#elif defined(__WXGTK__) + return new wxGTKWindowImplDC(); +#elif defined(__WXMAC__) + return new wxMacWindowImplDC(); +#elif defined(__WXCOCOA__) + return new wxCocoaWindowImplDC(); +#elif defined(__WXMOTIF__) + return new wxMotifWindowImplDC(); +#elif defined(__WXX11__) + return new wxX11WindowImplDC(); +#elif defined(__WXMGL__) + return new wxMGLWindowImplDC(); +#elif defined(__WXDFB__) + return new wxDFBWindowImplDC(); +#elif defined(__WXPM__) + return new wxPMWindowImplDC(); +#elif defined(__PALMOS__) + return new wxPalmWindowImplDC(); +#endif +} + +wxImplDC* wxNativeDCFactory::CreateWindowDC( wxWindow *window ) +{ +#if defined(__WXMSW__) + return new wxWindowsWindowImplDC( window ); +#elif defined(__WXGTK20__) + return new wxGTKWindowImplDC( window ); +#elif defined(__WXGTK__) + return new wxGTKWindowImplDC( window ); +#elif defined(__WXMAC__) + return new wxMacWindowImplDC( window ); +#elif defined(__WXCOCOA__) + return new wxCocoaWindowImplDC( window ); +#elif defined(__WXMOTIF__) + return new wxMotifWindowImplDC( window ); +#elif defined(__WXX11__) + return new wxX11WindowImplDC( window ); +#elif defined(__WXMGL__) + return new wxMGLWindowImplDC( window ); +#elif defined(__WXDFB__) + return new wxDFBWindowImplDC( window ); +#elif defined(__WXPM__) + return new wxPMWindowImplDC( window ); +#elif defined(__PALMOS__) + return new wxPalmWindowImplDC( window ); +#endif +} + +wxImplDC* wxNativeDCFactory::CreateClientDC() +{ +#if defined(__WXMSW__) + return new wxWindowsClientImplDC(); +#elif defined(__WXGTK20__) + return new wxGTKClientImplDC(); +#elif defined(__WXGTK__) + return new wxGTKClientImplDC(); +#elif defined(__WXMAC__) + return new wxMacClientImplDC(); +#elif defined(__WXCOCOA__) + return new wxCocoaClientImplDC(); +#elif defined(__WXMOTIF__) + return new wxMotifClientImplDC(); +#elif defined(__WXX11__) + return new wxX11ClientImplDC(); +#elif defined(__WXMGL__) + return new wxMGLClientImplDC(); +#elif defined(__WXDFB__) + return new wxDFBClientImplDC(); +#elif defined(__WXPM__) + return new wxPMClientImplDC(); +#elif defined(__PALMOS__) + return new wxPalmClientImplDC(); +#endif +} + +wxImplDC* wxNativeDCFactory::CreateClientDC( wxWindow *window ) +{ +#if defined(__WXMSW__) + return new wxWindowsClientImplDC( window ); +#elif defined(__WXGTK20__) + return new wxGTKClientImplDC( window ); +#elif defined(__WXGTK__) + return new wxGTKClientImplDC( window ); +#elif defined(__WXMAC__) + return new wxMacClientImplDC( window ); +#elif defined(__WXCOCOA__) + return new wxCocoaClientImplDC( window ); +#elif defined(__WXMOTIF__) + return new wxMotifClientImplDC( window ); +#elif defined(__WXX11__) + return new wxX11ClientImplDC( window ); +#elif defined(__WXMGL__) + return new wxMGLClientImplDC( window ); +#elif defined(__WXDFB__) + return new wxDFBClientImplDC( window ); +#elif defined(__WXPM__) + return new wxPMClientImplDC( window ); +#elif defined(__PALMOS__) + return new wxPalmClientImplDC( window ); +#endif +} + +wxImplDC* wxNativeDCFactory::CreatePaintDC() +{ +#if defined(__WXMSW__) + return new wxWindowsPaintImplDC(); +#elif defined(__WXGTK20__) + return new wxGTKPaintImplDC(); +#elif defined(__WXGTK__) + return new wxGTKPaintImplDC(); +#elif defined(__WXMAC__) + return new wxMacPaintImplDC(); +#elif defined(__WXCOCOA__) + return new wxCocoaPaintImplDC(); +#elif defined(__WXMOTIF__) + return new wxMotifPaintImplDC(); +#elif defined(__WXX11__) + return new wxX11PaintImplDC(); +#elif defined(__WXMGL__) + return new wxMGLPaintImplDC(); +#elif defined(__WXDFB__) + return new wxDFBPaintImplDC(); +#elif defined(__WXPM__) + return new wxPMPaintImplDC(); +#elif defined(__PALMOS__) + return new wxPalmPaintImplDC(); +#endif +} + +wxImplDC* wxNativeDCFactory::CreatePaintDC( wxWindow *window ) +{ +#if defined(__WXMSW__) + return new wxWindowsPaintImplDC( window ); +#elif defined(__WXGTK20__) + return new wxGTKPaintImplDC( window ); +#elif defined(__WXGTK__) + return new wxGTKPaintImplDC( window ); +#elif defined(__WXMAC__) + return new wxMacPaintImplDC( window ); +#elif defined(__WXCOCOA__) + return new wxCocoaPaintImplDC( window ); +#elif defined(__WXMOTIF__) + return new wxMotifPaintImplDC( window ); +#elif defined(__WXX11__) + return new wxX11PaintImplDC( window ); +#elif defined(__WXMGL__) + return new wxMGLPaintImplDC( window ); +#elif defined(__WXDFB__) + return new wxDFBPaintImplDC( window ); +#elif defined(__WXPM__) + return new wxPMPaintImplDC( window ); +#elif defined(__PALMOS__) + return new wxPalmPaintImplDC( window ); +#endif +} + +wxImplDC* wxNativeDCFactory::CreateMemoryDC() +{ +#if defined(__WXMSW__) + return new wxWindowsMemoryImplDC(); +#elif defined(__WXGTK20__) + return new wxGTKMemoryImplDC(); +#elif defined(__WXGTK__) + return new wxGTKMemoryImplDC(); +#elif defined(__WXMAC__) + return new wxMacMemoryImplDC(); +#elif defined(__WXCOCOA__) + return new wxCocoaMemoryImplDC(); +#elif defined(__WXMOTIF__) + return new wxMotifMemoryImplDC(); +#elif defined(__WXX11__) + return new wxX11MemoryImplDC(); +#elif defined(__WXMGL__) + return new wxMGLMemoryImplDC(); +#elif defined(__WXDFB__) + return new wxDFBMemoryImplDC(); +#elif defined(__WXPM__) + return new wxPMMemoryImplDC(); +#elif defined(__PALMOS__) + return new wxPalmMemoryImplDC(); +#endif +} + +wxImplDC* wxNativeDCFactory::CreateMemoryDC( wxBitmap &bitmap ) +{ +#if defined(__WXMSW__) + return new wxWindowsMemoryImplDC( bitmap ); +#elif defined(__WXGTK20__) + return new wxGTKMemoryImplDC( bitmap ); +#elif defined(__WXGTK__) + return new wxGTKMemoryImplDC( bitmap ); +#elif defined(__WXMAC__) + return new wxMacMemoryImplDC( bitmap ); +#elif defined(__WXCOCOA__) + return new wxCocoaMemoryImplDC( bitmap ); +#elif defined(__WXMOTIF__) + return new wxMotifMemoryImplDC( bitmap ); +#elif defined(__WXX11__) + return new wxX11MemoryImplDC( bitmap ); +#elif defined(__WXMGL__) + return new wxMGLMemoryImplDC( bitmap ); +#elif defined(__WXDFB__) + return new wxDFBMemoryImplDC( bitmap ); +#elif defined(__WXPM__) + return new wxPMMemoryImplDC( bitmap ); +#elif defined(__PALMOS__) + return new wxPalmMemoryImplDC( bitmap ); +#endif +} + +wxImplDC* wxNativeDCFactory::CreateMemoryDC( wxDC *dc ) +{ +#if defined(__WXMSW__) + return new wxWindowsMemoryImplDC( dc ); +#elif defined(__WXGTK20__) + return new wxGTKMemoryImplDC( dc ); +#elif defined(__WXGTK__) + return new wxGTKMemoryImplDC( dc ); +#elif defined(__WXMAC__) + return new wxMacMemoryImplDC( dc ); +#elif defined(__WXCOCOA__) + return new wxCocoaMemoryImplDC( dc ); +#elif defined(__WXMOTIF__) + return new wxMotifMemoryImplDC( dc ); +#elif defined(__WXX11__) + return new wxX11MemoryImplDC( dc ); +#elif defined(__WXMGL__) + return new wxMGLMemoryImplDC( dc ); +#elif defined(__WXDFB__) + return new wxDFBMemoryImplDC( dc ); +#elif defined(__WXPM__) + return new wxPMMemoryImplDC( dc ); +#elif defined(__PALMOS__) + return new wxPalmMemoryImplDC( dc ); +#endif +} + +//----------------------------------------------------------------------------- +// wxWindowDC +//----------------------------------------------------------------------------- + +IMPLEMENT_DYNAMIC_CLASS(wxWindowDC, wxDC) + +wxWindow::wxWindowDC() +{ + wxDCFactory *factory = wxDCFactory::GetFactory(); + m_pimpl = factory->CreateWindowDC(); +} + +wxWindow::wxWindowDC( wxWindow *win ) +{ + wxDCFactory *factory = wxDCFactory::GetFactory(); + m_pimpl = factory->CreateWindowDC( win ); +} + +//----------------------------------------------------------------------------- +// wxClientDC +//----------------------------------------------------------------------------- + +IMPLEMENT_DYNAMIC_CLASS(wxClientDC, wxDC) + +wxClientDC::wxClientDC() +{ + wxDCFactory *factory = wxDCFactory::GetFactory(); + m_pimpl = factory->CreateClientDC(); +} + +wxClientDC::wxClientDC( wxWindow *win ) +{ + wxDCFactory *factory = wxDCFactory::GetFactory(); + m_pimpl = factory->CreateClientDC( win ); +} + +//----------------------------------------------------------------------------- +// wxMemoryDC +//----------------------------------------------------------------------------- + +IMPLEMENT_DYNAMIC_CLASS(wxMemoryDC, wxDC) + +wxMemoryDC::wxMemoryDC() +{ + wxDCFactory *factory = wxDCFactory::GetFactory(); + m_pimpl = factory->CreateMemoryDC(); +} + +wxMemoryDC::wxMemoryDC( wxBitmap& bitmap ) +{ + wxDCFactory *factory = wxDCFactory::GetFactory(); + m_pimpl = factory->CreateMemoryDC( bitmap ); +} + +wxMemoryDC::wxMemoryDC( wxDC *dc ) +{ + wxDCFactory *factory = wxDCFactory::GetFactory(); + m_pimpl = factory->CreateMemoryDC( dc ); +} + +//----------------------------------------------------------------------------- +// wxPaintDC +//----------------------------------------------------------------------------- + +IMPLEMENT_DYNAMIC_CLASS(wxPaintDC, wxDC) + +wxPaintDC::wxPaintDC() +{ + wxDCFactory *factory = wxDCFactory::GetFactory(); + m_pimpl = factory->CreatePaintDC(); +} + +wxPaintDC::wxPaintDC( wxWindow *win ) +{ + wxDCFactory *factory = wxDCFactory::GetFactory(); + m_pimpl = factory->CreatePaintDC( win ); +} + +//----------------------------------------------------------------------------- +// wxImplDC +//----------------------------------------------------------------------------- + +IMPLEMENT_ABSTRACT_CLASS(wxImplDC, wxObject) + +wxImplDC::wxImplDC( wxDC *owner ) + : m_colour(wxColourDisplay()) + , m_ok(true) + , m_clipping(false) + , m_isInteractive(0) + , m_isBBoxValid(false) + , m_logicalOriginX(0), m_logicalOriginY(0) + , m_deviceOriginX(0), m_deviceOriginY(0) + , m_deviceLocalOriginX(0), m_deviceLocalOriginY(0) + , m_logicalScaleX(1.0), m_logicalScaleY(1.0) + , m_userScaleX(1.0), m_userScaleY(1.0) + , m_scaleX(1.0), m_scaleY(1.0) + , m_signX(1), m_signY(1) + , m_minX(0), m_minY(0), m_maxX(0), m_maxY(0) + , m_clipX1(0), m_clipY1(0), m_clipX2(0), m_clipY2(0) + , m_logicalFunction(wxCOPY) + , m_backgroundMode(wxTRANSPARENT) + , m_mappingMode(wxMM_TEXT) + , m_pen() + , m_brush() + , m_backgroundBrush(*wxTRANSPARENT_BRUSH) + , m_textForegroundColour(*wxBLACK) + , m_textBackgroundColour(*wxWHITE) + , m_font() +#if wxUSE_PALETTE + , m_palette() + , m_hasCustomPalette(false) +#endif // wxUSE_PALETTE +{ + m_owner = owner; + + m_mm_to_pix_x = (double)wxGetDisplaySize().GetWidth() / + (double)wxGetDisplaySizeMM().GetWidth(); + m_mm_to_pix_y = (double)wxGetDisplaySize().GetHeight() / + (double)wxGetDisplaySizeMM().GetHeight(); + + ResetBoundingBox(); + ResetClipping(); +} + +wxImplDC::~wxImplDC() +{ +} + +#if WXWIN_COMPATIBILITY_2_8 + // for compatibility with the old code when wxCoord was long everywhere +void wxImplDC::GetTextExtent(const wxString& string, + long *x, long *y, + long *descent, + long *externalLeading, + const wxFont *theFont) const + { + wxCoord x2, y2, descent2, externalLeading2; + DoGetTextExtent(string, &x2, &y2, + &descent2, &externalLeading2, + theFont); + if ( x ) + *x = x2; + if ( y ) + *y = y2; + if ( descent ) + *descent = descent2; + if ( externalLeading ) + *externalLeading = externalLeading2; + } + +void wxImplDC::GetLogicalOrigin(long *x, long *y) const + { + wxCoord x2, y2; + DoGetLogicalOrigin(&x2, &y2); + if ( x ) + *x = x2; + if ( y ) + *y = y2; + } + +void wxImplDC::GetDeviceOrigin(long *x, long *y) const + { + wxCoord x2, y2; + DoGetDeviceOrigin(&x2, &y2); + if ( x ) + *x = x2; + if ( y ) + *y = y2; + } + +void wxImplDC::GetClippingBox(long *x, long *y, long *w, long *h) const + { + wxCoord xx,yy,ww,hh; + DoGetClippingBox(&xx, &yy, &ww, &hh); + if (x) *x = xx; + if (y) *y = yy; + if (w) *w = ww; + if (h) *h = hh; + } +#endif // WXWIN_COMPATIBILITY_2_8 + + + +// ---------------------------------------------------------------------------- +// coordinate conversions and transforms +// ---------------------------------------------------------------------------- + +wxCoord wxImplDC::DeviceToLogicalX(wxCoord x) const +{ + return wxRound((double)(x - m_deviceOriginX - m_deviceLocalOriginX) / m_scaleX) * m_signX + m_logicalOriginX; +} + +wxCoord wxImplDC::DeviceToLogicalY(wxCoord y) const +{ + return wxRound((double)(y - m_deviceOriginY - m_deviceLocalOriginY) / m_scaleY) * m_signY + m_logicalOriginY; +} + +wxCoord wxImplDC::DeviceToLogicalXRel(wxCoord x) const +{ + return wxRound((double)(x) / m_scaleX); +} + +wxCoord wxImplDC::DeviceToLogicalYRel(wxCoord y) const +{ + return wxRound((double)(y) / m_scaleY); +} + +wxCoord wxImplDC::LogicalToDeviceX(wxCoord x) const +{ + return wxRound((double)(x - m_logicalOriginX) * m_scaleX) * m_signX + m_deviceOriginX + m_deviceLocalOriginX; +} + +wxCoord wxImplDC::LogicalToDeviceY(wxCoord y) const +{ + return wxRound((double)(y - m_logicalOriginY) * m_scaleY) * m_signY + m_deviceOriginY + m_deviceLocalOriginY; +} + +wxCoord wxImplDC::LogicalToDeviceXRel(wxCoord x) const +{ + return wxRound((double)(x) * m_scaleX); +} + +wxCoord wxImplDC::LogicalToDeviceYRel(wxCoord y) const +{ + return wxRound((double)(y) * m_scaleY); +} + +void wxImplDC::ComputeScaleAndOrigin() +{ + m_scaleX = m_logicalScaleX * m_userScaleX; + m_scaleY = m_logicalScaleY * m_userScaleY; +} + +void wxImplDC::SetMapMode( int mode ) +{ + switch (mode) + { + case wxMM_TWIPS: + SetLogicalScale( twips2mm*m_mm_to_pix_x, twips2mm*m_mm_to_pix_y ); + break; + case wxMM_POINTS: + SetLogicalScale( pt2mm*m_mm_to_pix_x, pt2mm*m_mm_to_pix_y ); + break; + case wxMM_METRIC: + SetLogicalScale( m_mm_to_pix_x, m_mm_to_pix_y ); + break; + case wxMM_LOMETRIC: + SetLogicalScale( m_mm_to_pix_x/10.0, m_mm_to_pix_y/10.0 ); + break; + default: + case wxMM_TEXT: + SetLogicalScale( 1.0, 1.0 ); + break; + } + m_mappingMode = mode; +} + +void wxImplDC::SetUserScale( double x, double y ) +{ + // allow negative ? -> no + m_userScaleX = x; + m_userScaleY = y; + ComputeScaleAndOrigin(); +} + +void wxImplDC::SetLogicalScale( double x, double y ) +{ + // allow negative ? + m_logicalScaleX = x; + m_logicalScaleY = y; + ComputeScaleAndOrigin(); +} + +void wxImplDC::SetLogicalOrigin( wxCoord x, wxCoord y ) +{ + m_logicalOriginX = x * m_signX; + m_logicalOriginY = y * m_signY; + ComputeScaleAndOrigin(); +} + +void wxImplDC::SetDeviceOrigin( wxCoord x, wxCoord y ) +{ + m_deviceOriginX = x; + m_deviceOriginY = y; + ComputeScaleAndOrigin(); +} + +void wxImplDC::SetDeviceLocalOrigin( wxCoord x, wxCoord y ) +{ + m_deviceLocalOriginX = x; + m_deviceLocalOriginY = y; + ComputeScaleAndOrigin(); +} + +void wxImplDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp ) +{ + // only wxPostScripDC has m_signX = -1, we override SetAxisOrientation there + m_signX = (xLeftRight ? 1 : -1); + m_signY = (yBottomUp ? -1 : 1); + ComputeScaleAndOrigin(); +} + + +// Each element of the widths array will be the width of the string up to and +// including the corresponding character in text. This is the generic +// implementation, the port-specific classes should do this with native APIs +// if available and if faster. Note: pango_layout_index_to_pos is much slower +// than calling GetTextExtent!! + +#define FWC_SIZE 256 + +class FontWidthCache +{ +public: + FontWidthCache() : m_scaleX(1), m_widths(NULL) { } + ~FontWidthCache() { delete []m_widths; } + + void Reset() + { + if (!m_widths) + m_widths = new int[FWC_SIZE]; + + memset(m_widths, 0, sizeof(int)*FWC_SIZE); + } + + wxFont m_font; + double m_scaleX; + int *m_widths; +}; + +static FontWidthCache s_fontWidthCache; + +bool wxImplDC::DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths) const +{ + int totalWidth = 0; + + const size_t len = text.length(); + widths.Empty(); + widths.Add(0, len); + + // reset the cache if font or horizontal scale have changed + if ( !s_fontWidthCache.m_widths || + !wxIsSameDouble(s_fontWidthCache.m_scaleX, m_scaleX) || + (s_fontWidthCache.m_font != GetFont()) ) + { + s_fontWidthCache.Reset(); + s_fontWidthCache.m_font = GetFont(); + s_fontWidthCache.m_scaleX = m_scaleX; + } + + // Calculate the position of each character based on the widths of + // the previous characters + int w, h; + for ( size_t i = 0; i < len; i++ ) + { + const wxChar c = text[i]; + unsigned int c_int = (unsigned int)c; + + if ((c_int < FWC_SIZE) && (s_fontWidthCache.m_widths[c_int] != 0)) + { + w = s_fontWidthCache.m_widths[c_int]; + } + else + { + GetTextExtent(c, &w, &h); + if (c_int < FWC_SIZE) + s_fontWidthCache.m_widths[c_int] = w; + } + + totalWidth += w; + widths[i] = totalWidth; + } + + return true; +} + +void wxImplDC::GetMultiLineTextExtent(const wxString& text, + wxCoord *x, + wxCoord *y, + wxCoord *h, + const wxFont *font) const +{ + wxCoord widthTextMax = 0, widthLine, + heightTextTotal = 0, heightLineDefault = 0, heightLine = 0; + + wxString curLine; + for ( const wxChar *pc = text; ; pc++ ) + { + if ( *pc == _T('\n') || *pc == _T('\0') ) + { + if ( curLine.empty() ) + { + // we can't use GetTextExtent - it will return 0 for both width + // and height and an empty line should count in height + // calculation + + // assume that this line has the same height as the previous + // one + if ( !heightLineDefault ) + heightLineDefault = heightLine; + + if ( !heightLineDefault ) + { + // but we don't know it yet - choose something reasonable + DoGetTextExtent(_T("W"), NULL, &heightLineDefault, + NULL, NULL, font); + } + + heightTextTotal += heightLineDefault; + } + else + { + DoGetTextExtent(curLine, &widthLine, &heightLine, + NULL, NULL, font); + if ( widthLine > widthTextMax ) + widthTextMax = widthLine; + heightTextTotal += heightLine; + } + + if ( *pc == _T('\n') ) + { + curLine.clear(); + } + else + { + // the end of string + break; + } + } + else + { + curLine += *pc; + } + } + + if ( x ) + *x = widthTextMax; + if ( y ) + *y = heightTextTotal; + if ( h ) + *h = heightLine; +} + +void wxImplDC::DoDrawCheckMark(wxCoord x1, wxCoord y1, + wxCoord width, wxCoord height) +{ + wxCHECK_RET( Ok(), wxT("invalid window dc") ); + + wxCoord x2 = x1 + width, + y2 = y1 + height; + + // the pen width is calibrated to give 3 for width == height == 10 + wxDCPenChanger pen(m_owner, wxPen(GetTextForeground(), (width + height + 1)/7)); + + // we're drawing a scaled version of wx/generic/tick.xpm here + wxCoord x3 = x1 + (4*width) / 10, // x of the tick bottom + y3 = y1 + height / 2; // y of the left tick branch + DoDrawLine(x1, y3, x3, y2); + DoDrawLine(x3, y2, x2, y1); + + CalcBoundingBox(x1, y1); + CalcBoundingBox(x2, y2); +} + +bool +wxImplDC::DoStretchBlit(wxCoord xdest, wxCoord ydest, + wxCoord dstWidth, wxCoord dstHeight, + wxDC *source, + wxCoord xsrc, wxCoord ysrc, + wxCoord srcWidth, wxCoord srcHeight, + int rop, + bool useMask, + wxCoord xsrcMask, + wxCoord ysrcMask) +{ + wxCHECK_MSG( srcWidth && srcHeight && dstWidth && dstHeight, false, + _T("invalid blit size") ); + + // emulate the stretching by modifying the DC scale + double xscale = (double)srcWidth/dstWidth, + yscale = (double)srcHeight/dstHeight; + + double xscaleOld, yscaleOld; + GetUserScale(&xscaleOld, &yscaleOld); + SetUserScale(xscaleOld/xscale, yscaleOld/yscale); + + bool rc = DoBlit(wxCoord(xdest*xscale), wxCoord(ydest*yscale), + wxCoord(dstWidth*xscale), wxCoord(dstHeight*yscale), + source, + xsrc, ysrc, rop, useMask, xsrcMask, ysrcMask); + + SetUserScale(xscaleOld, yscaleOld); + + return rc; +} + +void wxImplDC::DrawLines(const wxList *list, wxCoord xoffset, wxCoord yoffset) +{ + int n = list->GetCount(); + wxPoint *points = new wxPoint[n]; + + int i = 0; + for ( wxList::compatibility_iterator node = list->GetFirst(); node; node = node->GetNext(), i++ ) + { + wxPoint *point = (wxPoint *)node->GetData(); + points[i].x = point->x; + points[i].y = point->y; + } + + DoDrawLines(n, points, xoffset, yoffset); + + delete [] points; +} + +void wxImplDC::DrawPolygon(const wxList *list, + wxCoord xoffset, wxCoord yoffset, + int fillStyle) +{ + int n = list->GetCount(); + wxPoint *points = new wxPoint[n]; + + int i = 0; + for ( wxList::compatibility_iterator node = list->GetFirst(); node; node = node->GetNext(), i++ ) + { + wxPoint *point = (wxPoint *)node->GetData(); + points[i].x = point->x; + points[i].y = point->y; + } + + DoDrawPolygon(n, points, xoffset, yoffset, fillStyle); + + delete [] points; +} + +void +wxImplDC::DoDrawPolyPolygon(int n, + int count[], + wxPoint points[], + wxCoord xoffset, wxCoord yoffset, + int fillStyle) +{ + if ( n == 1 ) + { + DoDrawPolygon(count[0], points, xoffset, yoffset, fillStyle); + return; + } + + int i, j, lastOfs; + wxPoint* pts; + wxPen pen; + + for (i = j = lastOfs = 0; i < n; i++) + { + lastOfs = j; + j += count[i]; + } + pts = new wxPoint[j+n-1]; + for (i = 0; i < j; i++) + pts[i] = points[i]; + for (i = 2; i <= n; i++) + { + lastOfs -= count[n-i]; + pts[j++] = pts[lastOfs]; + } + + pen = GetPen(); + SetPen(wxPen(*wxBLACK, 0, wxTRANSPARENT)); + DoDrawPolygon(j, pts, xoffset, yoffset, fillStyle); + SetPen(pen); + for (i = j = 0; i < n; i++) + { + DoDrawLines(count[i], pts+j, xoffset, yoffset); + j += count[i]; + } + delete[] pts; +} + +#if wxUSE_SPLINES + +// TODO: this API needs fixing (wxPointList, why (!const) "wxList *"?) +void wxImplDC::DrawSpline(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, wxCoord x3, wxCoord y3) +{ + wxList point_list; + + wxPoint *point1 = new wxPoint; + point1->x = x1; point1->y = y1; + point_list.Append((wxObject*)point1); + + wxPoint *point2 = new wxPoint; + point2->x = x2; point2->y = y2; + point_list.Append((wxObject*)point2); + + wxPoint *point3 = new wxPoint; + point3->x = x3; point3->y = y3; + point_list.Append((wxObject*)point3); + + DrawSpline(&point_list); + + for( wxList::compatibility_iterator node = point_list.GetFirst(); node; node = node->GetNext() ) + { + wxPoint *p = (wxPoint *)node->GetData(); + delete p; + } +} + +void wxImplDC::DrawSpline(int n, wxPoint points[]) +{ + wxList list; + for (int i =0; i < n; i++) + { + list.Append((wxObject*)&points[i]); + } + + DrawSpline(&list); +} + +// ----------------------------------- spline code ---------------------------------------- + +void wx_quadratic_spline(double a1, double b1, double a2, double b2, + double a3, double b3, double a4, double b4); +void wx_clear_stack(); +int wx_spline_pop(double *x1, double *y1, double *x2, double *y2, double *x3, + double *y3, double *x4, double *y4); +void wx_spline_push(double x1, double y1, double x2, double y2, double x3, double y3, + double x4, double y4); +static bool wx_spline_add_point(double x, double y); +static void wx_spline_draw_point_array(wxDCBase *dc); + +wxList wx_spline_point_list; + +#define half(z1, z2) ((z1+z2)/2.0) +#define THRESHOLD 5 + +/* iterative version */ + +void wx_quadratic_spline(double a1, double b1, double a2, double b2, double a3, double b3, double a4, + double b4) +{ + register double xmid, ymid; + double x1, y1, x2, y2, x3, y3, x4, y4; + + wx_clear_stack(); + wx_spline_push(a1, b1, a2, b2, a3, b3, a4, b4); + + while (wx_spline_pop(&x1, &y1, &x2, &y2, &x3, &y3, &x4, &y4)) { + xmid = (double)half(x2, x3); + ymid = (double)half(y2, y3); + if (fabs(x1 - xmid) < THRESHOLD && fabs(y1 - ymid) < THRESHOLD && + fabs(xmid - x4) < THRESHOLD && fabs(ymid - y4) < THRESHOLD) { + wx_spline_add_point( x1, y1 ); + wx_spline_add_point( xmid, ymid ); + } else { + wx_spline_push(xmid, ymid, (double)half(xmid, x3), (double)half(ymid, y3), + (double)half(x3, x4), (double)half(y3, y4), x4, y4); + wx_spline_push(x1, y1, (double)half(x1, x2), (double)half(y1, y2), + (double)half(x2, xmid), (double)half(y2, ymid), xmid, ymid); + } + } +} + +/* utilities used by spline drawing routines */ + +typedef struct wx_spline_stack_struct { + double x1, y1, x2, y2, x3, y3, x4, y4; +} Stack; + +#define SPLINE_STACK_DEPTH 20 +static Stack wx_spline_stack[SPLINE_STACK_DEPTH]; +static Stack *wx_stack_top; +static int wx_stack_count; + +void wx_clear_stack() +{ + wx_stack_top = wx_spline_stack; + wx_stack_count = 0; +} + +void wx_spline_push(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) +{ + wx_stack_top->x1 = x1; + wx_stack_top->y1 = y1; + wx_stack_top->x2 = x2; + wx_stack_top->y2 = y2; + wx_stack_top->x3 = x3; + wx_stack_top->y3 = y3; + wx_stack_top->x4 = x4; + wx_stack_top->y4 = y4; + wx_stack_top++; + wx_stack_count++; +} + +int wx_spline_pop(double *x1, double *y1, double *x2, double *y2, + double *x3, double *y3, double *x4, double *y4) +{ + if (wx_stack_count == 0) + return (0); + wx_stack_top--; + wx_stack_count--; + *x1 = wx_stack_top->x1; + *y1 = wx_stack_top->y1; + *x2 = wx_stack_top->x2; + *y2 = wx_stack_top->y2; + *x3 = wx_stack_top->x3; + *y3 = wx_stack_top->y3; + *x4 = wx_stack_top->x4; + *y4 = wx_stack_top->y4; + return (1); +} + +static bool wx_spline_add_point(double x, double y) +{ + wxPoint *point = new wxPoint ; + point->x = (int) x; + point->y = (int) y; + wx_spline_point_list.Append((wxObject*)point); + return true; +} + +static void wx_spline_draw_point_array(wxDC *dc) +{ + dc->DrawLines(&wx_spline_point_list, 0, 0 ); + wxList::compatibility_iterator node = wx_spline_point_list.GetFirst(); + while (node) + { + wxPoint *point = (wxPoint *)node->GetData(); + delete point; + wx_spline_point_list.Erase(node); + node = wx_spline_point_list.GetFirst(); + } +} + +void wxImplDC::DoDrawSpline( wxList *points ) +{ + wxCHECK_RET( Ok(), wxT("invalid window dc") ); + + wxPoint *p; + double cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4; + double x1, y1, x2, y2; + + wxList::compatibility_iterator node = points->GetFirst(); + if (!node) + // empty list + return; + + p = (wxPoint *)node->GetData(); + + x1 = p->x; + y1 = p->y; + + node = node->GetNext(); + p = (wxPoint *)node->GetData(); + + x2 = p->x; + y2 = p->y; + cx1 = (double)((x1 + x2) / 2); + cy1 = (double)((y1 + y2) / 2); + cx2 = (double)((cx1 + x2) / 2); + cy2 = (double)((cy1 + y2) / 2); + + wx_spline_add_point(x1, y1); + + while ((node = node->GetNext()) +#if !wxUSE_STL + != NULL +#endif // !wxUSE_STL + ) + { + p = (wxPoint *)node->GetData(); + x1 = x2; + y1 = y2; + x2 = p->x; + y2 = p->y; + cx4 = (double)(x1 + x2) / 2; + cy4 = (double)(y1 + y2) / 2; + cx3 = (double)(x1 + cx4) / 2; + cy3 = (double)(y1 + cy4) / 2; + + wx_quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4); + + cx1 = cx4; + cy1 = cy4; + cx2 = (double)(cx1 + x2) / 2; + cy2 = (double)(cy1 + y2) / 2; + } + + wx_spline_add_point( cx1, cy1 ); + wx_spline_add_point( x2, y2 ); + + wx_spline_draw_point_array( m_owner ); +} + +#endif // wxUSE_SPLINES + + +void wxImplDC::DrawLabel(const wxString& text, + const wxBitmap& bitmap, + const wxRect& rect, + int alignment, + int indexAccel, + wxRect *rectBounding) +{ + // find the text position + wxCoord widthText, heightText, heightLine; + GetMultiLineTextExtent(text, &widthText, &heightText, &heightLine); + + wxCoord width, height; + if ( bitmap.Ok() ) + { + width = widthText + bitmap.GetWidth(); + height = bitmap.GetHeight(); + } + else // no bitmap + { + width = widthText; + height = heightText; + } + + wxCoord x, y; + if ( alignment & wxALIGN_RIGHT ) + { + x = rect.GetRight() - width; + } + else if ( alignment & wxALIGN_CENTRE_HORIZONTAL ) + { + x = (rect.GetLeft() + rect.GetRight() + 1 - width) / 2; + } + else // alignment & wxALIGN_LEFT + { + x = rect.GetLeft(); + } + + if ( alignment & wxALIGN_BOTTOM ) + { + y = rect.GetBottom() - height; + } + else if ( alignment & wxALIGN_CENTRE_VERTICAL ) + { + y = (rect.GetTop() + rect.GetBottom() + 1 - height) / 2; + } + else // alignment & wxALIGN_TOP + { + y = rect.GetTop(); + } + + // draw the bitmap first + wxCoord x0 = x, + y0 = y, + width0 = width; + if ( bitmap.Ok() ) + { + DoDrawBitmap(bitmap, x, y, true /* use mask */); + + wxCoord offset = bitmap.GetWidth() + 4; + x += offset; + width -= offset; + + y += (height - heightText) / 2; + } + + // we will draw the underscore under the accel char later + wxCoord startUnderscore = 0, + endUnderscore = 0, + yUnderscore = 0; + + // split the string into lines and draw each of them separately + wxString curLine; + for ( wxString::const_iterator pc = text.begin(); ; ++pc ) + { + if ( *pc == _T('\n') || pc == text.end() ) + { + int xRealStart = x; // init it here to avoid compielr warnings + + if ( !curLine.empty() ) + { + // NB: can't test for !(alignment & wxALIGN_LEFT) because + // wxALIGN_LEFT is 0 + if ( alignment & (wxALIGN_RIGHT | wxALIGN_CENTRE_HORIZONTAL) ) + { + wxCoord widthLine; + m_owner->GetTextExtent(curLine, &widthLine, NULL); + + if ( alignment & wxALIGN_RIGHT ) + { + xRealStart += width - widthLine; + } + else // if ( alignment & wxALIGN_CENTRE_HORIZONTAL ) + { + xRealStart += (width - widthLine) / 2; + } + } + //else: left aligned, nothing to do + + DoDrawText(curLine, xRealStart, y); + } + + y += heightLine; + + // do we have underscore in this line? we can check yUnderscore + // because it is set below to just y + heightLine if we do + if ( y == yUnderscore ) + { + // adjust the horz positions to account for the shift + startUnderscore += xRealStart; + endUnderscore += xRealStart; + } + + if ( pc == text.end() ) + break; + + curLine.clear(); + } + else // not end of line + { + if ( pc - text.begin() == indexAccel ) + { + // remeber to draw underscore here + GetTextExtent(curLine, &startUnderscore, NULL); + curLine += *pc; + GetTextExtent(curLine, &endUnderscore, NULL); + + yUnderscore = y + heightLine; + } + else + { + curLine += *pc; + } + } + } + + // draw the underscore if found + if ( startUnderscore != endUnderscore ) + { + // it should be of the same colour as text + SetPen(wxPen(GetTextForeground(), 0, wxSOLID)); + + yUnderscore--; + + DoDrawLine(startUnderscore, yUnderscore, endUnderscore, yUnderscore); + } + + // return bounding rect if requested + if ( rectBounding ) + { + *rectBounding = wxRect(x, y - heightText, widthText, heightText); + } + + CalcBoundingBox(x0, y0); + CalcBoundingBox(x0 + width0, y0 + height); +} + + +void wxImplDC::DoGradientFillLinear(const wxRect& rect, + const wxColour& initialColour, + const wxColour& destColour, + wxDirection nDirection) +{ + // save old pen + wxPen oldPen = m_pen; + wxBrush oldBrush = m_brush; + + wxUint8 nR1 = initialColour.Red(); + wxUint8 nG1 = initialColour.Green(); + wxUint8 nB1 = initialColour.Blue(); + wxUint8 nR2 = destColour.Red(); + wxUint8 nG2 = destColour.Green(); + wxUint8 nB2 = destColour.Blue(); + wxUint8 nR, nG, nB; + + if ( nDirection == wxEAST || nDirection == wxWEST ) + { + wxInt32 x = rect.GetWidth(); + wxInt32 w = x; // width of area to shade + wxInt32 xDelta = w/256; // height of one shade bend + if (xDelta < 1) + xDelta = 1; + + while (x >= xDelta) + { + x -= xDelta; + if (nR1 > nR2) + nR = nR1 - (nR1-nR2)*(w-x)/w; + else + nR = nR1 + (nR2-nR1)*(w-x)/w; + + if (nG1 > nG2) + nG = nG1 - (nG1-nG2)*(w-x)/w; + else + nG = nG1 + (nG2-nG1)*(w-x)/w; + + if (nB1 > nB2) + nB = nB1 - (nB1-nB2)*(w-x)/w; + else + nB = nB1 + (nB2-nB1)*(w-x)/w; + + wxColour colour(nR,nG,nB); + SetPen(wxPen(colour, 1, wxSOLID)); + SetBrush(wxBrush(colour)); + if(nDirection == wxEAST) + DoDrawRectangle(rect.GetRight()-x-xDelta, rect.GetTop(), + xDelta, rect.GetHeight()); + else //nDirection == wxWEST + DoDrawRectangle(rect.GetLeft()+x, rect.GetTop(), + xDelta, rect.GetHeight()); + } + } + else // nDirection == wxNORTH || nDirection == wxSOUTH + { + wxInt32 y = rect.GetHeight(); + wxInt32 w = y; // height of area to shade + wxInt32 yDelta = w/255; // height of one shade bend + if (yDelta < 1) + yDelta = 1; + + while (y > 0) + { + y -= yDelta; + if (nR1 > nR2) + nR = nR1 - (nR1-nR2)*(w-y)/w; + else + nR = nR1 + (nR2-nR1)*(w-y)/w; + + if (nG1 > nG2) + nG = nG1 - (nG1-nG2)*(w-y)/w; + else + nG = nG1 + (nG2-nG1)*(w-y)/w; + + if (nB1 > nB2) + nB = nB1 - (nB1-nB2)*(w-y)/w; + else + nB = nB1 + (nB2-nB1)*(w-y)/w; + + wxColour colour(nR,nG,nB); + SetPen(wxPen(colour, 1, wxSOLID)); + SetBrush(wxBrush(colour)); + if(nDirection == wxNORTH) + DoDrawRectangle(rect.GetLeft(), rect.GetTop()+y, + rect.GetWidth(), yDelta); + else //nDirection == wxSOUTH + DoDrawRectangle(rect.GetLeft(), rect.GetBottom()-y-yDelta, + rect.GetWidth(), yDelta); + } + } + + SetPen(oldPen); + SetBrush(oldBrush); +} + +void wxImplDC::DoGradientFillConcentric(const wxRect& rect, + const wxColour& initialColour, + const wxColour& destColour, + const wxPoint& circleCenter) +{ + //save the old pen color + wxColour oldPenColour = m_pen.GetColour(); + + wxUint8 nR1 = destColour.Red(); + wxUint8 nG1 = destColour.Green(); + wxUint8 nB1 = destColour.Blue(); + wxUint8 nR2 = initialColour.Red(); + wxUint8 nG2 = initialColour.Green(); + wxUint8 nB2 = initialColour.Blue(); + wxUint8 nR, nG, nB; + + + //Radius + wxInt32 cx = rect.GetWidth() / 2; + wxInt32 cy = rect.GetHeight() / 2; + wxInt32 nRadius; + if (cx < cy) + nRadius = cx; + else + nRadius = cy; + + //Offset of circle + wxInt32 nCircleOffX = circleCenter.x - (rect.GetWidth() / 2); + wxInt32 nCircleOffY = circleCenter.y - (rect.GetHeight() / 2); + + for ( wxInt32 x = 0; x < rect.GetWidth(); x++ ) + { + for ( wxInt32 y = 0; y < rect.GetHeight(); y++ ) + { + //get color difference + wxInt32 nGradient = ((nRadius - + (wxInt32)sqrt( + pow((double)(x - cx - nCircleOffX), 2) + + pow((double)(y - cy - nCircleOffY), 2) + )) * 100) / nRadius; + + //normalize Gradient + if (nGradient < 0 ) + nGradient = 0; + + //get dest colors + nR = (wxUint8)(nR1 + ((nR2 - nR1) * nGradient / 100)); + nG = (wxUint8)(nG1 + ((nG2 - nG1) * nGradient / 100)); + nB = (wxUint8)(nB1 + ((nB2 - nB1) * nGradient / 100)); + + //set the pixel + m_pen.SetColour(wxColour(nR,nG,nB)); + DoDrawPoint(wxPoint(x + rect.GetLeft(), y + rect.GetTop())); + } + } + //return old pen color + m_pen.SetColour(oldPenColour); +} + +//----------------------------------------------------------------------------- +// wxDC +//----------------------------------------------------------------------------- + +IMPLEMENT_ABSTRACT_CLASS(wxDC, wxObject) + +#if WXWIN_COMPATIBILITY_2_8 + // for compatibility with the old code when wxCoord was long everywhere +void wxDC::GetTextExtent(const wxString& string, + long *x, long *y, + long *descent, + long *externalLeading, + const wxFont *theFont) const + { + wxCoord x2, y2, descent2, externalLeading2; + m_pimpl->DoGetTextExtent(string, &x2, &y2, + &descent2, &externalLeading2, + theFont); + if ( x ) + *x = x2; + if ( y ) + *y = y2; + if ( descent ) + *descent = descent2; + if ( externalLeading ) + *externalLeading = externalLeading2; + } + +void wxDC::GetLogicalOrigin(long *x, long *y) const + { + wxCoord x2, y2; + m_pimpl->DoGetLogicalOrigin(&x2, &y2); + if ( x ) + *x = x2; + if ( y ) + *y = y2; + } + +void wxDC::GetDeviceOrigin(long *x, long *y) const + { + wxCoord x2, y2; + m_pimpl->DoGetDeviceOrigin(&x2, &y2); + if ( x ) + *x = x2; + if ( y ) + *y = y2; + } + +void wxDC::GetClippingBox(long *x, long *y, long *w, long *h) const + { + wxCoord xx,yy,ww,hh; + m_pimpl->DoGetClippingBox(&xx, &yy, &ww, &hh); + if (x) *x = xx; + if (y) *y = yy; + if (w) *w = ww; + if (h) *h = hh; + } + +#endif // WXWIN_COMPATIBILITY_2_8 + + +#else // wxUSE_NEW_DC + + // bool wxDCBase::sm_cacheing = false; IMPLEMENT_ABSTRACT_CLASS(wxDCBase, wxObject) @@ -1409,3 +2852,5 @@ void wxDCBase::CalculateEllipticPoints( wxList* points, } // CalculateEllipticPoints #endif // __WXWINCE__ + +#endif // wxUSE_NEW_DC diff --git a/src/gtk/dc.cpp b/src/gtk/dc.cpp index 877ec6f2d2..9b2bcee17f 100644 --- a/src/gtk/dc.cpp +++ b/src/gtk/dc.cpp @@ -13,1294 +13,17 @@ #include "wx/dc.h" +//----------------------------------------------------------------------------- +// wxDC +//----------------------------------------------------------------------------- + #if wxUSE_NEW_DC - -//---------------------------------------------------------------------------- -// wxDCFactory -//---------------------------------------------------------------------------- - -wxDCFactory *wxDCFactory::m_factory = NULL; - -void wxDCFactory::SetDCFactory( wxDCFactory *factory ) -{ - if (wxDCFactory::m_factory) - delete wxDCFactory::m_factory; - - wxDCFactory::m_factory = factory; -} - -wxDCFactory *wxDCFactory::GetFactory() -{ - if (!wxDCFactory::m_factory) - wxDCFactory::m_factory = new wxNativeDCFactory; - - return wxDCFactory::m_factory; -} - -//----------------------------------------------------------------------------- -// wxNativeDCFactory -//----------------------------------------------------------------------------- - -wxImplDC* wxNativeDCFactory::CreateWindowDC( wxWindow *window ) -{ -#if defined(__WXMSW__) - return new wxWindowsWindowImplDC( window ); -#elif defined(__WXGTK20__) - return new wxGTKWindowImplDC( window ); -#elif defined(__WXGTK__) - return new wxGTKWindowImplDC( window ); -#elif defined(__WXMAC__) - return new wxMacWindowImplDC( window ); -#elif defined(__WXCOCOA__) - return new wxCocoaWindowImplDC( window ); -#elif defined(__WXMOTIF__) - return new wxMotifWindowImplDC( window ); -#elif defined(__WXX11__) - return new wxX11WindowImplDC( window ); -#elif defined(__WXMGL__) - return new wxMGLWindowImplDC( window ); -#elif defined(__WXDFB__) - return new wxDFBWindowImplDC( window ); -#elif defined(__WXPM__) - return new wxPMWindowImplDC( window ); -#elif defined(__PALMOS__) - return new wxPalmWindowImplDC( window ); +IMPLEMENT_ABSTRACT_CLASS(wxGTKImplDC, wxDC) +#else +IMPLEMENT_ABSTRACT_CLASS(wxGTKImplDC, wxDCBase) #endif -} -wxImplDC* wxNativeDCFactory::CreateClientDC( wxWindow *window ) -{ -#if defined(__WXMSW__) - return new wxWindowsClientImplDC( window ); -#elif defined(__WXGTK20__) - return new wxGTKClientImplDC( window ); -#elif defined(__WXGTK__) - return new wxGTKClientImplDC( window ); -#elif defined(__WXMAC__) - return new wxMacClientImplDC( window ); -#elif defined(__WXCOCOA__) - return new wxCocoaClientImplDC( window ); -#elif defined(__WXMOTIF__) - return new wxMotifClientImplDC( window ); -#elif defined(__WXX11__) - return new wxX11ClientImplDC( window ); -#elif defined(__WXMGL__) - return new wxMGLClientImplDC( window ); -#elif defined(__WXDFB__) - return new wxDFBClientImplDC( window ); -#elif defined(__WXPM__) - return new wxPMClientImplDC( window ); -#elif defined(__PALMOS__) - return new wxPalmClientImplDC( window ); -#endif -} - -wxImplDC* wxNativeDCFactory::CreatePaintDC( wxWindow *window ) -{ -#if defined(__WXMSW__) - return new wxWindowsPaintImplDC( window ); -#elif defined(__WXGTK20__) - return new wxGTKPaintImplDC( window ); -#elif defined(__WXGTK__) - return new wxGTKPaintImplDC( window ); -#elif defined(__WXMAC__) - return new wxMacPaintImplDC( window ); -#elif defined(__WXCOCOA__) - return new wxCocoaPaintImplDC( window ); -#elif defined(__WXMOTIF__) - return new wxMotifPaintImplDC( window ); -#elif defined(__WXX11__) - return new wxX11PaintImplDC( window ); -#elif defined(__WXMGL__) - return new wxMGLPaintImplDC( window ); -#elif defined(__WXDFB__) - return new wxDFBPaintImplDC( window ); -#elif defined(__WXPM__) - return new wxPMPaintImplDC( window ); -#elif defined(__PALMOS__) - return new wxPalmPaintImplDC( window ); -#endif -} - -wxImplDC* wxNativeDCFactory::CreateMemoryDC() -{ -#if defined(__WXMSW__) - return new wxWindowsMemoryImplDC(); -#elif defined(__WXGTK20__) - return new wxGTKMemoryImplDC(); -#elif defined(__WXGTK__) - return new wxGTKMemoryImplDC(); -#elif defined(__WXMAC__) - return new wxMacMemoryImplDC(); -#elif defined(__WXCOCOA__) - return new wxCocoaMemoryImplDC(); -#elif defined(__WXMOTIF__) - return new wxMotifMemoryImplDC(); -#elif defined(__WXX11__) - return new wxX11MemoryImplDC(); -#elif defined(__WXMGL__) - return new wxMGLMemoryImplDC(); -#elif defined(__WXDFB__) - return new wxDFBMemoryImplDC(); -#elif defined(__WXPM__) - return new wxPMMemoryImplDC(); -#elif defined(__PALMOS__) - return new wxPalmMemoryImplDC(); -#endif -} - -wxImplDC* wxNativeDCFactory::CreateMemoryDC( wxBitmap &bitmap ) -{ -#if defined(__WXMSW__) - return new wxWindowsMemoryImplDC( bitmap ); -#elif defined(__WXGTK20__) - return new wxGTKMemoryImplDC( bitmap ); -#elif defined(__WXGTK__) - return new wxGTKMemoryImplDC( bitmap ); -#elif defined(__WXMAC__) - return new wxMacMemoryImplDC( bitmap ); -#elif defined(__WXCOCOA__) - return new wxCocoaMemoryImplDC( bitmap ); -#elif defined(__WXMOTIF__) - return new wxMotifMemoryImplDC( bitmap ); -#elif defined(__WXX11__) - return new wxX11MemoryImplDC( bitmap ); -#elif defined(__WXMGL__) - return new wxMGLMemoryImplDC( bitmap ); -#elif defined(__WXDFB__) - return new wxDFBMemoryImplDC( bitmap ); -#elif defined(__WXPM__) - return new wxPMMemoryImplDC( bitmap ); -#elif defined(__PALMOS__) - return new wxPalmMemoryImplDC( bitmap ); -#endif -} - -wxImplDC* wxNativeDCFactory::CreateMemoryDC( wxDC *dc ) -{ -#if defined(__WXMSW__) - return new wxWindowsMemoryImplDC( dc ); -#elif defined(__WXGTK20__) - return new wxGTKMemoryImplDC( dc ); -#elif defined(__WXGTK__) - return new wxGTKMemoryImplDC( dc ); -#elif defined(__WXMAC__) - return new wxMacMemoryImplDC( dc ); -#elif defined(__WXCOCOA__) - return new wxCocoaMemoryImplDC( dc ); -#elif defined(__WXMOTIF__) - return new wxMotifMemoryImplDC( dc ); -#elif defined(__WXX11__) - return new wxX11MemoryImplDC( dc ); -#elif defined(__WXMGL__) - return new wxMGLMemoryImplDC( dc ); -#elif defined(__WXDFB__) - return new wxDFBMemoryImplDC( dc ); -#elif defined(__WXPM__) - return new wxPMMemoryImplDC( dc ); -#elif defined(__PALMOS__) - return new wxPalmMemoryImplDC( dc ); -#endif -} - -//----------------------------------------------------------------------------- -// wxImplDC -//----------------------------------------------------------------------------- - -IMPLEMENT_ABSTRACT_CLASS(wxImplDC, wxObject) - -wxImplDC::wxImplDC( wxDC *owner ) - : m_colour(wxColourDisplay()) - , m_ok(true) - , m_clipping(false) - , m_isInteractive(0) - , m_isBBoxValid(false) - , m_logicalOriginX(0), m_logicalOriginY(0) - , m_deviceOriginX(0), m_deviceOriginY(0) - , m_deviceLocalOriginX(0), m_deviceLocalOriginY(0) - , m_logicalScaleX(1.0), m_logicalScaleY(1.0) - , m_userScaleX(1.0), m_userScaleY(1.0) - , m_scaleX(1.0), m_scaleY(1.0) - , m_signX(1), m_signY(1) - , m_minX(0), m_minY(0), m_maxX(0), m_maxY(0) - , m_clipX1(0), m_clipY1(0), m_clipX2(0), m_clipY2(0) - , m_logicalFunction(wxCOPY) - , m_backgroundMode(wxTRANSPARENT) - , m_mappingMode(wxMM_TEXT) - , m_pen() - , m_brush() - , m_backgroundBrush(*wxTRANSPARENT_BRUSH) - , m_textForegroundColour(*wxBLACK) - , m_textBackgroundColour(*wxWHITE) - , m_font() -#if wxUSE_PALETTE - , m_palette() - , m_hasCustomPalette(false) -#endif // wxUSE_PALETTE -{ - m_owner = owner; - - m_mm_to_pix_x = (double)wxGetDisplaySize().GetWidth() / - (double)wxGetDisplaySizeMM().GetWidth(); - m_mm_to_pix_y = (double)wxGetDisplaySize().GetHeight() / - (double)wxGetDisplaySizeMM().GetHeight(); - - ResetBoundingBox(); - ResetClipping(); -} - -wxImplDC::~wxImplDC() -{ -} - -#if WXWIN_COMPATIBILITY_2_8 - // for compatibility with the old code when wxCoord was long everywhere -void wxImplDC::GetTextExtent(const wxString& string, - long *x, long *y, - long *descent, - long *externalLeading, - const wxFont *theFont) const - { - wxCoord x2, y2, descent2, externalLeading2; - DoGetTextExtent(string, &x2, &y2, - &descent2, &externalLeading2, - theFont); - if ( x ) - *x = x2; - if ( y ) - *y = y2; - if ( descent ) - *descent = descent2; - if ( externalLeading ) - *externalLeading = externalLeading2; - } - -void wxImplDC::GetLogicalOrigin(long *x, long *y) const - { - wxCoord x2, y2; - DoGetLogicalOrigin(&x2, &y2); - if ( x ) - *x = x2; - if ( y ) - *y = y2; - } - -void wxImplDC::GetDeviceOrigin(long *x, long *y) const - { - wxCoord x2, y2; - DoGetDeviceOrigin(&x2, &y2); - if ( x ) - *x = x2; - if ( y ) - *y = y2; - } - -void wxImplDC::GetClippingBox(long *x, long *y, long *w, long *h) const - { - wxCoord xx,yy,ww,hh; - DoGetClippingBox(&xx, &yy, &ww, &hh); - if (x) *x = xx; - if (y) *y = yy; - if (w) *w = ww; - if (h) *h = hh; - } -#endif // WXWIN_COMPATIBILITY_2_8 - - - -// ---------------------------------------------------------------------------- -// coordinate conversions and transforms -// ---------------------------------------------------------------------------- - -wxCoord wxImplDC::DeviceToLogicalX(wxCoord x) const -{ - return wxRound((double)(x - m_deviceOriginX - m_deviceLocalOriginX) / m_scaleX) * m_signX + m_logicalOriginX; -} - -wxCoord wxImplDC::DeviceToLogicalY(wxCoord y) const -{ - return wxRound((double)(y - m_deviceOriginY - m_deviceLocalOriginY) / m_scaleY) * m_signY + m_logicalOriginY; -} - -wxCoord wxImplDC::DeviceToLogicalXRel(wxCoord x) const -{ - return wxRound((double)(x) / m_scaleX); -} - -wxCoord wxImplDC::DeviceToLogicalYRel(wxCoord y) const -{ - return wxRound((double)(y) / m_scaleY); -} - -wxCoord wxImplDC::LogicalToDeviceX(wxCoord x) const -{ - return wxRound((double)(x - m_logicalOriginX) * m_scaleX) * m_signX + m_deviceOriginX + m_deviceLocalOriginX; -} - -wxCoord wxImplDC::LogicalToDeviceY(wxCoord y) const -{ - return wxRound((double)(y - m_logicalOriginY) * m_scaleY) * m_signY + m_deviceOriginY + m_deviceLocalOriginY; -} - -wxCoord wxImplDC::LogicalToDeviceXRel(wxCoord x) const -{ - return wxRound((double)(x) * m_scaleX); -} - -wxCoord wxImplDC::LogicalToDeviceYRel(wxCoord y) const -{ - return wxRound((double)(y) * m_scaleY); -} - -void wxImplDC::ComputeScaleAndOrigin() -{ - m_scaleX = m_logicalScaleX * m_userScaleX; - m_scaleY = m_logicalScaleY * m_userScaleY; -} - -void wxImplDC::SetMapMode( int mode ) -{ - switch (mode) - { - case wxMM_TWIPS: - SetLogicalScale( twips2mm*m_mm_to_pix_x, twips2mm*m_mm_to_pix_y ); - break; - case wxMM_POINTS: - SetLogicalScale( pt2mm*m_mm_to_pix_x, pt2mm*m_mm_to_pix_y ); - break; - case wxMM_METRIC: - SetLogicalScale( m_mm_to_pix_x, m_mm_to_pix_y ); - break; - case wxMM_LOMETRIC: - SetLogicalScale( m_mm_to_pix_x/10.0, m_mm_to_pix_y/10.0 ); - break; - default: - case wxMM_TEXT: - SetLogicalScale( 1.0, 1.0 ); - break; - } - m_mappingMode = mode; -} - -void wxImplDC::SetUserScale( double x, double y ) -{ - // allow negative ? -> no - m_userScaleX = x; - m_userScaleY = y; - ComputeScaleAndOrigin(); -} - -void wxImplDC::SetLogicalScale( double x, double y ) -{ - // allow negative ? - m_logicalScaleX = x; - m_logicalScaleY = y; - ComputeScaleAndOrigin(); -} - -void wxImplDC::SetLogicalOrigin( wxCoord x, wxCoord y ) -{ - m_logicalOriginX = x * m_signX; - m_logicalOriginY = y * m_signY; - ComputeScaleAndOrigin(); -} - -void wxImplDC::SetDeviceOrigin( wxCoord x, wxCoord y ) -{ - m_deviceOriginX = x; - m_deviceOriginY = y; - ComputeScaleAndOrigin(); -} - -void wxImplDC::SetDeviceLocalOrigin( wxCoord x, wxCoord y ) -{ - m_deviceLocalOriginX = x; - m_deviceLocalOriginY = y; - ComputeScaleAndOrigin(); -} - -void wxImplDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp ) -{ - // only wxPostScripDC has m_signX = -1, we override SetAxisOrientation there - m_signX = (xLeftRight ? 1 : -1); - m_signY = (yBottomUp ? -1 : 1); - ComputeScaleAndOrigin(); -} - - -// Each element of the widths array will be the width of the string up to and -// including the corresponding character in text. This is the generic -// implementation, the port-specific classes should do this with native APIs -// if available and if faster. Note: pango_layout_index_to_pos is much slower -// than calling GetTextExtent!! - -#define FWC_SIZE 256 - -class FontWidthCache -{ -public: - FontWidthCache() : m_scaleX(1), m_widths(NULL) { } - ~FontWidthCache() { delete []m_widths; } - - void Reset() - { - if (!m_widths) - m_widths = new int[FWC_SIZE]; - - memset(m_widths, 0, sizeof(int)*FWC_SIZE); - } - - wxFont m_font; - double m_scaleX; - int *m_widths; -}; - -static FontWidthCache s_fontWidthCache; - -bool wxImplDC::DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths) const -{ - int totalWidth = 0; - - const size_t len = text.length(); - widths.Empty(); - widths.Add(0, len); - - // reset the cache if font or horizontal scale have changed - if ( !s_fontWidthCache.m_widths || - !wxIsSameDouble(s_fontWidthCache.m_scaleX, m_scaleX) || - (s_fontWidthCache.m_font != GetFont()) ) - { - s_fontWidthCache.Reset(); - s_fontWidthCache.m_font = GetFont(); - s_fontWidthCache.m_scaleX = m_scaleX; - } - - // Calculate the position of each character based on the widths of - // the previous characters - int w, h; - for ( size_t i = 0; i < len; i++ ) - { - const wxChar c = text[i]; - unsigned int c_int = (unsigned int)c; - - if ((c_int < FWC_SIZE) && (s_fontWidthCache.m_widths[c_int] != 0)) - { - w = s_fontWidthCache.m_widths[c_int]; - } - else - { - GetTextExtent(c, &w, &h); - if (c_int < FWC_SIZE) - s_fontWidthCache.m_widths[c_int] = w; - } - - totalWidth += w; - widths[i] = totalWidth; - } - - return true; -} - -void wxImplDC::GetMultiLineTextExtent(const wxString& text, - wxCoord *x, - wxCoord *y, - wxCoord *h, - const wxFont *font) const -{ - wxCoord widthTextMax = 0, widthLine, - heightTextTotal = 0, heightLineDefault = 0, heightLine = 0; - - wxString curLine; - for ( const wxChar *pc = text; ; pc++ ) - { - if ( *pc == _T('\n') || *pc == _T('\0') ) - { - if ( curLine.empty() ) - { - // we can't use GetTextExtent - it will return 0 for both width - // and height and an empty line should count in height - // calculation - - // assume that this line has the same height as the previous - // one - if ( !heightLineDefault ) - heightLineDefault = heightLine; - - if ( !heightLineDefault ) - { - // but we don't know it yet - choose something reasonable - DoGetTextExtent(_T("W"), NULL, &heightLineDefault, - NULL, NULL, font); - } - - heightTextTotal += heightLineDefault; - } - else - { - DoGetTextExtent(curLine, &widthLine, &heightLine, - NULL, NULL, font); - if ( widthLine > widthTextMax ) - widthTextMax = widthLine; - heightTextTotal += heightLine; - } - - if ( *pc == _T('\n') ) - { - curLine.clear(); - } - else - { - // the end of string - break; - } - } - else - { - curLine += *pc; - } - } - - if ( x ) - *x = widthTextMax; - if ( y ) - *y = heightTextTotal; - if ( h ) - *h = heightLine; -} - -void wxImplDC::DoDrawCheckMark(wxCoord x1, wxCoord y1, - wxCoord width, wxCoord height) -{ - wxCHECK_RET( Ok(), wxT("invalid window dc") ); - - wxCoord x2 = x1 + width, - y2 = y1 + height; - - // the pen width is calibrated to give 3 for width == height == 10 - wxDCPenChanger pen(m_owner, wxPen(GetTextForeground(), (width + height + 1)/7)); - - // we're drawing a scaled version of wx/generic/tick.xpm here - wxCoord x3 = x1 + (4*width) / 10, // x of the tick bottom - y3 = y1 + height / 2; // y of the left tick branch - DoDrawLine(x1, y3, x3, y2); - DoDrawLine(x3, y2, x2, y1); - - CalcBoundingBox(x1, y1); - CalcBoundingBox(x2, y2); -} - -bool -wxImplDC::DoStretchBlit(wxCoord xdest, wxCoord ydest, - wxCoord dstWidth, wxCoord dstHeight, - wxDC *source, - wxCoord xsrc, wxCoord ysrc, - wxCoord srcWidth, wxCoord srcHeight, - int rop, - bool useMask, - wxCoord xsrcMask, - wxCoord ysrcMask) -{ - wxCHECK_MSG( srcWidth && srcHeight && dstWidth && dstHeight, false, - _T("invalid blit size") ); - - // emulate the stretching by modifying the DC scale - double xscale = (double)srcWidth/dstWidth, - yscale = (double)srcHeight/dstHeight; - - double xscaleOld, yscaleOld; - GetUserScale(&xscaleOld, &yscaleOld); - SetUserScale(xscaleOld/xscale, yscaleOld/yscale); - - bool rc = DoBlit(wxCoord(xdest*xscale), wxCoord(ydest*yscale), - wxCoord(dstWidth*xscale), wxCoord(dstHeight*yscale), - source, - xsrc, ysrc, rop, useMask, xsrcMask, ysrcMask); - - SetUserScale(xscaleOld, yscaleOld); - - return rc; -} - -void wxImplDC::DrawLines(const wxList *list, wxCoord xoffset, wxCoord yoffset) -{ - int n = list->GetCount(); - wxPoint *points = new wxPoint[n]; - - int i = 0; - for ( wxList::compatibility_iterator node = list->GetFirst(); node; node = node->GetNext(), i++ ) - { - wxPoint *point = (wxPoint *)node->GetData(); - points[i].x = point->x; - points[i].y = point->y; - } - - DoDrawLines(n, points, xoffset, yoffset); - - delete [] points; -} - -void wxImplDC::DrawPolygon(const wxList *list, - wxCoord xoffset, wxCoord yoffset, - int fillStyle) -{ - int n = list->GetCount(); - wxPoint *points = new wxPoint[n]; - - int i = 0; - for ( wxList::compatibility_iterator node = list->GetFirst(); node; node = node->GetNext(), i++ ) - { - wxPoint *point = (wxPoint *)node->GetData(); - points[i].x = point->x; - points[i].y = point->y; - } - - DoDrawPolygon(n, points, xoffset, yoffset, fillStyle); - - delete [] points; -} - -void -wxImplDC::DoDrawPolyPolygon(int n, - int count[], - wxPoint points[], - wxCoord xoffset, wxCoord yoffset, - int fillStyle) -{ - if ( n == 1 ) - { - DoDrawPolygon(count[0], points, xoffset, yoffset, fillStyle); - return; - } - - int i, j, lastOfs; - wxPoint* pts; - wxPen pen; - - for (i = j = lastOfs = 0; i < n; i++) - { - lastOfs = j; - j += count[i]; - } - pts = new wxPoint[j+n-1]; - for (i = 0; i < j; i++) - pts[i] = points[i]; - for (i = 2; i <= n; i++) - { - lastOfs -= count[n-i]; - pts[j++] = pts[lastOfs]; - } - - pen = GetPen(); - SetPen(wxPen(*wxBLACK, 0, wxTRANSPARENT)); - DoDrawPolygon(j, pts, xoffset, yoffset, fillStyle); - SetPen(pen); - for (i = j = 0; i < n; i++) - { - DoDrawLines(count[i], pts+j, xoffset, yoffset); - j += count[i]; - } - delete[] pts; -} - -#if wxUSE_SPLINES - -// TODO: this API needs fixing (wxPointList, why (!const) "wxList *"?) -void wxImplDC::DrawSpline(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, wxCoord x3, wxCoord y3) -{ - wxList point_list; - - wxPoint *point1 = new wxPoint; - point1->x = x1; point1->y = y1; - point_list.Append((wxObject*)point1); - - wxPoint *point2 = new wxPoint; - point2->x = x2; point2->y = y2; - point_list.Append((wxObject*)point2); - - wxPoint *point3 = new wxPoint; - point3->x = x3; point3->y = y3; - point_list.Append((wxObject*)point3); - - DrawSpline(&point_list); - - for( wxList::compatibility_iterator node = point_list.GetFirst(); node; node = node->GetNext() ) - { - wxPoint *p = (wxPoint *)node->GetData(); - delete p; - } -} - -void wxImplDC::DrawSpline(int n, wxPoint points[]) -{ - wxList list; - for (int i =0; i < n; i++) - { - list.Append((wxObject*)&points[i]); - } - - DrawSpline(&list); -} - -// ----------------------------------- spline code ---------------------------------------- - -void wx_quadratic_spline(double a1, double b1, double a2, double b2, - double a3, double b3, double a4, double b4); -void wx_clear_stack(); -int wx_spline_pop(double *x1, double *y1, double *x2, double *y2, double *x3, - double *y3, double *x4, double *y4); -void wx_spline_push(double x1, double y1, double x2, double y2, double x3, double y3, - double x4, double y4); -static bool wx_spline_add_point(double x, double y); -static void wx_spline_draw_point_array(wxDCBase *dc); - -wxList wx_spline_point_list; - -#define half(z1, z2) ((z1+z2)/2.0) -#define THRESHOLD 5 - -/* iterative version */ - -void wx_quadratic_spline(double a1, double b1, double a2, double b2, double a3, double b3, double a4, - double b4) -{ - register double xmid, ymid; - double x1, y1, x2, y2, x3, y3, x4, y4; - - wx_clear_stack(); - wx_spline_push(a1, b1, a2, b2, a3, b3, a4, b4); - - while (wx_spline_pop(&x1, &y1, &x2, &y2, &x3, &y3, &x4, &y4)) { - xmid = (double)half(x2, x3); - ymid = (double)half(y2, y3); - if (fabs(x1 - xmid) < THRESHOLD && fabs(y1 - ymid) < THRESHOLD && - fabs(xmid - x4) < THRESHOLD && fabs(ymid - y4) < THRESHOLD) { - wx_spline_add_point( x1, y1 ); - wx_spline_add_point( xmid, ymid ); - } else { - wx_spline_push(xmid, ymid, (double)half(xmid, x3), (double)half(ymid, y3), - (double)half(x3, x4), (double)half(y3, y4), x4, y4); - wx_spline_push(x1, y1, (double)half(x1, x2), (double)half(y1, y2), - (double)half(x2, xmid), (double)half(y2, ymid), xmid, ymid); - } - } -} - -/* utilities used by spline drawing routines */ - -typedef struct wx_spline_stack_struct { - double x1, y1, x2, y2, x3, y3, x4, y4; -} Stack; - -#define SPLINE_STACK_DEPTH 20 -static Stack wx_spline_stack[SPLINE_STACK_DEPTH]; -static Stack *wx_stack_top; -static int wx_stack_count; - -void wx_clear_stack() -{ - wx_stack_top = wx_spline_stack; - wx_stack_count = 0; -} - -void wx_spline_push(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) -{ - wx_stack_top->x1 = x1; - wx_stack_top->y1 = y1; - wx_stack_top->x2 = x2; - wx_stack_top->y2 = y2; - wx_stack_top->x3 = x3; - wx_stack_top->y3 = y3; - wx_stack_top->x4 = x4; - wx_stack_top->y4 = y4; - wx_stack_top++; - wx_stack_count++; -} - -int wx_spline_pop(double *x1, double *y1, double *x2, double *y2, - double *x3, double *y3, double *x4, double *y4) -{ - if (wx_stack_count == 0) - return (0); - wx_stack_top--; - wx_stack_count--; - *x1 = wx_stack_top->x1; - *y1 = wx_stack_top->y1; - *x2 = wx_stack_top->x2; - *y2 = wx_stack_top->y2; - *x3 = wx_stack_top->x3; - *y3 = wx_stack_top->y3; - *x4 = wx_stack_top->x4; - *y4 = wx_stack_top->y4; - return (1); -} - -static bool wx_spline_add_point(double x, double y) -{ - wxPoint *point = new wxPoint ; - point->x = (int) x; - point->y = (int) y; - wx_spline_point_list.Append((wxObject*)point); - return true; -} - -static void wx_spline_draw_point_array(wxDC *dc) -{ - dc->DrawLines(&wx_spline_point_list, 0, 0 ); - wxList::compatibility_iterator node = wx_spline_point_list.GetFirst(); - while (node) - { - wxPoint *point = (wxPoint *)node->GetData(); - delete point; - wx_spline_point_list.Erase(node); - node = wx_spline_point_list.GetFirst(); - } -} - -void wxImplDC::DoDrawSpline( wxList *points ) -{ - wxCHECK_RET( Ok(), wxT("invalid window dc") ); - - wxPoint *p; - double cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4; - double x1, y1, x2, y2; - - wxList::compatibility_iterator node = points->GetFirst(); - if (!node) - // empty list - return; - - p = (wxPoint *)node->GetData(); - - x1 = p->x; - y1 = p->y; - - node = node->GetNext(); - p = (wxPoint *)node->GetData(); - - x2 = p->x; - y2 = p->y; - cx1 = (double)((x1 + x2) / 2); - cy1 = (double)((y1 + y2) / 2); - cx2 = (double)((cx1 + x2) / 2); - cy2 = (double)((cy1 + y2) / 2); - - wx_spline_add_point(x1, y1); - - while ((node = node->GetNext()) -#if !wxUSE_STL - != NULL -#endif // !wxUSE_STL - ) - { - p = (wxPoint *)node->GetData(); - x1 = x2; - y1 = y2; - x2 = p->x; - y2 = p->y; - cx4 = (double)(x1 + x2) / 2; - cy4 = (double)(y1 + y2) / 2; - cx3 = (double)(x1 + cx4) / 2; - cy3 = (double)(y1 + cy4) / 2; - - wx_quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4); - - cx1 = cx4; - cy1 = cy4; - cx2 = (double)(cx1 + x2) / 2; - cy2 = (double)(cy1 + y2) / 2; - } - - wx_spline_add_point( cx1, cy1 ); - wx_spline_add_point( x2, y2 ); - - wx_spline_draw_point_array( m_owner ); -} - -#endif // wxUSE_SPLINES - - -void wxImplDC::DrawLabel(const wxString& text, - const wxBitmap& bitmap, - const wxRect& rect, - int alignment, - int indexAccel, - wxRect *rectBounding) -{ - // find the text position - wxCoord widthText, heightText, heightLine; - GetMultiLineTextExtent(text, &widthText, &heightText, &heightLine); - - wxCoord width, height; - if ( bitmap.Ok() ) - { - width = widthText + bitmap.GetWidth(); - height = bitmap.GetHeight(); - } - else // no bitmap - { - width = widthText; - height = heightText; - } - - wxCoord x, y; - if ( alignment & wxALIGN_RIGHT ) - { - x = rect.GetRight() - width; - } - else if ( alignment & wxALIGN_CENTRE_HORIZONTAL ) - { - x = (rect.GetLeft() + rect.GetRight() + 1 - width) / 2; - } - else // alignment & wxALIGN_LEFT - { - x = rect.GetLeft(); - } - - if ( alignment & wxALIGN_BOTTOM ) - { - y = rect.GetBottom() - height; - } - else if ( alignment & wxALIGN_CENTRE_VERTICAL ) - { - y = (rect.GetTop() + rect.GetBottom() + 1 - height) / 2; - } - else // alignment & wxALIGN_TOP - { - y = rect.GetTop(); - } - - // draw the bitmap first - wxCoord x0 = x, - y0 = y, - width0 = width; - if ( bitmap.Ok() ) - { - DoDrawBitmap(bitmap, x, y, true /* use mask */); - - wxCoord offset = bitmap.GetWidth() + 4; - x += offset; - width -= offset; - - y += (height - heightText) / 2; - } - - // we will draw the underscore under the accel char later - wxCoord startUnderscore = 0, - endUnderscore = 0, - yUnderscore = 0; - - // split the string into lines and draw each of them separately - wxString curLine; - for ( wxString::const_iterator pc = text.begin(); ; ++pc ) - { - if ( *pc == _T('\n') || pc == text.end() ) - { - int xRealStart = x; // init it here to avoid compielr warnings - - if ( !curLine.empty() ) - { - // NB: can't test for !(alignment & wxALIGN_LEFT) because - // wxALIGN_LEFT is 0 - if ( alignment & (wxALIGN_RIGHT | wxALIGN_CENTRE_HORIZONTAL) ) - { - wxCoord widthLine; - m_owner->GetTextExtent(curLine, &widthLine, NULL); - - if ( alignment & wxALIGN_RIGHT ) - { - xRealStart += width - widthLine; - } - else // if ( alignment & wxALIGN_CENTRE_HORIZONTAL ) - { - xRealStart += (width - widthLine) / 2; - } - } - //else: left aligned, nothing to do - - DoDrawText(curLine, xRealStart, y); - } - - y += heightLine; - - // do we have underscore in this line? we can check yUnderscore - // because it is set below to just y + heightLine if we do - if ( y == yUnderscore ) - { - // adjust the horz positions to account for the shift - startUnderscore += xRealStart; - endUnderscore += xRealStart; - } - - if ( pc == text.end() ) - break; - - curLine.clear(); - } - else // not end of line - { - if ( pc - text.begin() == indexAccel ) - { - // remeber to draw underscore here - GetTextExtent(curLine, &startUnderscore, NULL); - curLine += *pc; - GetTextExtent(curLine, &endUnderscore, NULL); - - yUnderscore = y + heightLine; - } - else - { - curLine += *pc; - } - } - } - - // draw the underscore if found - if ( startUnderscore != endUnderscore ) - { - // it should be of the same colour as text - SetPen(wxPen(GetTextForeground(), 0, wxSOLID)); - - yUnderscore--; - - DoDrawLine(startUnderscore, yUnderscore, endUnderscore, yUnderscore); - } - - // return bounding rect if requested - if ( rectBounding ) - { - *rectBounding = wxRect(x, y - heightText, widthText, heightText); - } - - CalcBoundingBox(x0, y0); - CalcBoundingBox(x0 + width0, y0 + height); -} - - -void wxImplDC::DoGradientFillLinear(const wxRect& rect, - const wxColour& initialColour, - const wxColour& destColour, - wxDirection nDirection) -{ - // save old pen - wxPen oldPen = m_pen; - wxBrush oldBrush = m_brush; - - wxUint8 nR1 = initialColour.Red(); - wxUint8 nG1 = initialColour.Green(); - wxUint8 nB1 = initialColour.Blue(); - wxUint8 nR2 = destColour.Red(); - wxUint8 nG2 = destColour.Green(); - wxUint8 nB2 = destColour.Blue(); - wxUint8 nR, nG, nB; - - if ( nDirection == wxEAST || nDirection == wxWEST ) - { - wxInt32 x = rect.GetWidth(); - wxInt32 w = x; // width of area to shade - wxInt32 xDelta = w/256; // height of one shade bend - if (xDelta < 1) - xDelta = 1; - - while (x >= xDelta) - { - x -= xDelta; - if (nR1 > nR2) - nR = nR1 - (nR1-nR2)*(w-x)/w; - else - nR = nR1 + (nR2-nR1)*(w-x)/w; - - if (nG1 > nG2) - nG = nG1 - (nG1-nG2)*(w-x)/w; - else - nG = nG1 + (nG2-nG1)*(w-x)/w; - - if (nB1 > nB2) - nB = nB1 - (nB1-nB2)*(w-x)/w; - else - nB = nB1 + (nB2-nB1)*(w-x)/w; - - wxColour colour(nR,nG,nB); - SetPen(wxPen(colour, 1, wxSOLID)); - SetBrush(wxBrush(colour)); - if(nDirection == wxEAST) - DoDrawRectangle(rect.GetRight()-x-xDelta, rect.GetTop(), - xDelta, rect.GetHeight()); - else //nDirection == wxWEST - DoDrawRectangle(rect.GetLeft()+x, rect.GetTop(), - xDelta, rect.GetHeight()); - } - } - else // nDirection == wxNORTH || nDirection == wxSOUTH - { - wxInt32 y = rect.GetHeight(); - wxInt32 w = y; // height of area to shade - wxInt32 yDelta = w/255; // height of one shade bend - if (yDelta < 1) - yDelta = 1; - - while (y > 0) - { - y -= yDelta; - if (nR1 > nR2) - nR = nR1 - (nR1-nR2)*(w-y)/w; - else - nR = nR1 + (nR2-nR1)*(w-y)/w; - - if (nG1 > nG2) - nG = nG1 - (nG1-nG2)*(w-y)/w; - else - nG = nG1 + (nG2-nG1)*(w-y)/w; - - if (nB1 > nB2) - nB = nB1 - (nB1-nB2)*(w-y)/w; - else - nB = nB1 + (nB2-nB1)*(w-y)/w; - - wxColour colour(nR,nG,nB); - SetPen(wxPen(colour, 1, wxSOLID)); - SetBrush(wxBrush(colour)); - if(nDirection == wxNORTH) - DoDrawRectangle(rect.GetLeft(), rect.GetTop()+y, - rect.GetWidth(), yDelta); - else //nDirection == wxSOUTH - DoDrawRectangle(rect.GetLeft(), rect.GetBottom()-y-yDelta, - rect.GetWidth(), yDelta); - } - } - - SetPen(oldPen); - SetBrush(oldBrush); -} - -void wxImplDC::DoGradientFillConcentric(const wxRect& rect, - const wxColour& initialColour, - const wxColour& destColour, - const wxPoint& circleCenter) -{ - //save the old pen color - wxColour oldPenColour = m_pen.GetColour(); - - wxUint8 nR1 = destColour.Red(); - wxUint8 nG1 = destColour.Green(); - wxUint8 nB1 = destColour.Blue(); - wxUint8 nR2 = initialColour.Red(); - wxUint8 nG2 = initialColour.Green(); - wxUint8 nB2 = initialColour.Blue(); - wxUint8 nR, nG, nB; - - - //Radius - wxInt32 cx = rect.GetWidth() / 2; - wxInt32 cy = rect.GetHeight() / 2; - wxInt32 nRadius; - if (cx < cy) - nRadius = cx; - else - nRadius = cy; - - //Offset of circle - wxInt32 nCircleOffX = circleCenter.x - (rect.GetWidth() / 2); - wxInt32 nCircleOffY = circleCenter.y - (rect.GetHeight() / 2); - - for ( wxInt32 x = 0; x < rect.GetWidth(); x++ ) - { - for ( wxInt32 y = 0; y < rect.GetHeight(); y++ ) - { - //get color difference - wxInt32 nGradient = ((nRadius - - (wxInt32)sqrt( - pow((double)(x - cx - nCircleOffX), 2) + - pow((double)(y - cy - nCircleOffY), 2) - )) * 100) / nRadius; - - //normalize Gradient - if (nGradient < 0 ) - nGradient = 0; - - //get dest colors - nR = (wxUint8)(nR1 + ((nR2 - nR1) * nGradient / 100)); - nG = (wxUint8)(nG1 + ((nG2 - nG1) * nGradient / 100)); - nB = (wxUint8)(nB1 + ((nB2 - nB1) * nGradient / 100)); - - //set the pixel - m_pen.SetColour(wxColour(nR,nG,nB)); - DoDrawPoint(wxPoint(x + rect.GetLeft(), y + rect.GetTop())); - } - } - //return old pen color - m_pen.SetColour(oldPenColour); -} - -//----------------------------------------------------------------------------- -// wxDC -//----------------------------------------------------------------------------- - -IMPLEMENT_ABSTRACT_CLASS(wxDC, wxObject) - -#if WXWIN_COMPATIBILITY_2_8 - // for compatibility with the old code when wxCoord was long everywhere -void wxDC::GetTextExtent(const wxString& string, - long *x, long *y, - long *descent, - long *externalLeading, - const wxFont *theFont) const - { - wxCoord x2, y2, descent2, externalLeading2; - m_pimpl->DoGetTextExtent(string, &x2, &y2, - &descent2, &externalLeading2, - theFont); - if ( x ) - *x = x2; - if ( y ) - *y = y2; - if ( descent ) - *descent = descent2; - if ( externalLeading ) - *externalLeading = externalLeading2; - } - -void wxDC::GetLogicalOrigin(long *x, long *y) const - { - wxCoord x2, y2; - m_pimpl->DoGetLogicalOrigin(&x2, &y2); - if ( x ) - *x = x2; - if ( y ) - *y = y2; - } - -void wxDC::GetDeviceOrigin(long *x, long *y) const - { - wxCoord x2, y2; - m_pimpl->DoGetDeviceOrigin(&x2, &y2); - if ( x ) - *x = x2; - if ( y ) - *y = y2; - } - -void wxDC::GetClippingBox(long *x, long *y, long *w, long *h) const - { - wxCoord xx,yy,ww,hh; - m_pimpl->DoGetClippingBox(&xx, &yy, &ww, &hh); - if (x) *x = xx; - if (y) *y = yy; - if (w) *w = ww; - if (h) *h = hh; - } - -#endif // WXWIN_COMPATIBILITY_2_8 - - -#endif // wxUSE_NEW_DC - -//----------------------------------------------------------------------------- -// wxDC -//----------------------------------------------------------------------------- - -IMPLEMENT_ABSTRACT_CLASS(wxDC, wxDCBase) - -wxDC::wxDC() +wxGTKImplDC::wxGTKImplDC() { m_ok = FALSE; @@ -1309,7 +32,7 @@ wxDC::wxDC() m_brush = *wxWHITE_BRUSH; } -void wxDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) +void wxGTKImplDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) { m_clipping = TRUE; m_clipX1 = x; @@ -1322,7 +45,7 @@ void wxDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord hei // get DC capabilities // --------------------------------------------------------------------------- -void wxDC::DoGetSizeMM( int* width, int* height ) const +void wxGTKImplDC::DoGetSizeMM( int* width, int* height ) const { int w = 0; int h = 0; @@ -1332,7 +55,7 @@ void wxDC::DoGetSizeMM( int* width, int* height ) const } // Resolution in pixels per logical inch -wxSize wxDC::GetPPI() const +wxSize wxGTKImplDC::GetPPI() const { // TODO (should probably be pure virtual) return wxSize(0, 0); diff --git a/src/gtk/dcclient.cpp b/src/gtk/dcclient.cpp index 3ffd2a1776..f76c0f040a 100644 --- a/src/gtk/dcclient.cpp +++ b/src/gtk/dcclient.cpp @@ -252,9 +252,13 @@ static void wxFreePoolGC( GdkGC *gc ) // wxWindowDC //----------------------------------------------------------------------------- +#if wxUSE_NEW_DC +IMPLEMENT_DYNAMIC_CLASS(wxGTKWindowImplDC, wxGTKImplDC) +#else IMPLEMENT_DYNAMIC_CLASS(wxWindowDC, wxDC) +#endif -wxWindowDC::wxWindowDC() +wxGTKWindowImplDC::wxGTKWindowImplDC() { m_penGC = (GdkGC *) NULL; m_brushGC = (GdkGC *) NULL; @@ -269,7 +273,7 @@ wxWindowDC::wxWindowDC() m_fontdesc = (PangoFontDescription *)NULL; } -wxWindowDC::wxWindowDC( wxWindow *window ) +wxGTKWindowImplDC::wxGTKWindowImplDC( wxWindow *window ) { wxASSERT_MSG( window, wxT("DC needs a window") ); @@ -335,7 +339,7 @@ wxWindowDC::wxWindowDC( wxWindow *window ) } } -wxWindowDC::~wxWindowDC() +wxGTKWindowImplDC::~wxGTKWindowImplDC() { Destroy(); @@ -345,7 +349,7 @@ wxWindowDC::~wxWindowDC() pango_font_description_free( m_fontdesc ); } -void wxWindowDC::SetUpDC() +void wxGTKWindowImplDC::SetUpDC() { m_ok = true; @@ -437,7 +441,7 @@ void wxWindowDC::SetUpDC() } } -void wxWindowDC::DoGetSize( int* width, int* height ) const +void wxGTKWindowImplDC::DoGetSize( int* width, int* height ) const { wxCHECK_RET( m_owner, _T("GetSize() doesn't work without window") ); @@ -447,13 +451,13 @@ void wxWindowDC::DoGetSize( int* width, int* height ) const extern bool wxDoFloodFill(wxDC *dc, wxCoord x, wxCoord y, const wxColour & col, int style); -bool wxWindowDC::DoFloodFill(wxCoord x, wxCoord y, +bool wxGTKWindowImplDC::DoFloodFill(wxCoord x, wxCoord y, const wxColour& col, int style) { return wxDoFloodFill(this, x, y, col, style); } -bool wxWindowDC::DoGetPixel( wxCoord x1, wxCoord y1, wxColour *col ) const +bool wxGTKWindowImplDC::DoGetPixel( wxCoord x1, wxCoord y1, wxColour *col ) const { // Generic (and therefore rather inefficient) method. // Could be improved. @@ -468,7 +472,7 @@ bool wxWindowDC::DoGetPixel( wxCoord x1, wxCoord y1, wxColour *col ) const return true; } -void wxWindowDC::DoDrawLine( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2 ) +void wxGTKWindowImplDC::DoDrawLine( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2 ) { wxCHECK_RET( Ok(), wxT("invalid window dc") ); @@ -482,7 +486,7 @@ void wxWindowDC::DoDrawLine( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2 ) } } -void wxWindowDC::DoCrossHair( wxCoord x, wxCoord y ) +void wxGTKWindowImplDC::DoCrossHair( wxCoord x, wxCoord y ) { wxCHECK_RET( Ok(), wxT("invalid window dc") ); @@ -501,7 +505,7 @@ void wxWindowDC::DoCrossHair( wxCoord x, wxCoord y ) } } -void wxWindowDC::DoDrawArc( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, +void wxGTKWindowImplDC::DoDrawArc( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, wxCoord xc, wxCoord yc ) { wxCHECK_RET( Ok(), wxT("invalid window dc") ); @@ -596,7 +600,7 @@ void wxWindowDC::DoDrawArc( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, CalcBoundingBox (x2, y2); } -void wxWindowDC::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord width, wxCoord height, double sa, double ea ) +void wxGTKWindowImplDC::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord width, wxCoord height, double sa, double ea ) { wxCHECK_RET( Ok(), wxT("invalid window dc") ); @@ -658,7 +662,7 @@ void wxWindowDC::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord width, wxCoord CalcBoundingBox (x + width, y + height); } -void wxWindowDC::DoDrawPoint( wxCoord x, wxCoord y ) +void wxGTKWindowImplDC::DoDrawPoint( wxCoord x, wxCoord y ) { wxCHECK_RET( Ok(), wxT("invalid window dc") ); @@ -668,7 +672,7 @@ void wxWindowDC::DoDrawPoint( wxCoord x, wxCoord y ) CalcBoundingBox (x, y); } -void wxWindowDC::DoDrawLines( int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset ) +void wxGTKWindowImplDC::DoDrawLines( int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset ) { wxCHECK_RET( Ok(), wxT("invalid window dc") ); @@ -702,7 +706,7 @@ void wxWindowDC::DoDrawLines( int n, wxPoint points[], wxCoord xoffset, wxCoord delete[] gpts; } -void wxWindowDC::DoDrawPolygon( int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset, int WXUNUSED(fillStyle) ) +void wxGTKWindowImplDC::DoDrawPolygon( int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset, int WXUNUSED(fillStyle) ) { wxCHECK_RET( Ok(), wxT("invalid window dc") ); @@ -788,7 +792,7 @@ void wxWindowDC::DoDrawPolygon( int n, wxPoint points[], wxCoord xoffset, wxCoor delete[] gdkpoints; } -void wxWindowDC::DoDrawRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) +void wxGTKWindowImplDC::DoDrawRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) { wxCHECK_RET( Ok(), wxT("invalid window dc") ); @@ -879,7 +883,7 @@ void wxWindowDC::DoDrawRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoord h CalcBoundingBox( x + width, y + height ); } -void wxWindowDC::DoDrawRoundedRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoord height, double radius ) +void wxGTKWindowImplDC::DoDrawRoundedRectangle( wxCoord x, wxCoord y, wxCoord width, wxCoord height, double radius ) { wxCHECK_RET( Ok(), wxT("invalid window dc") ); @@ -1002,7 +1006,7 @@ void wxWindowDC::DoDrawRoundedRectangle( wxCoord x, wxCoord y, wxCoord width, wx CalcBoundingBox( x + width, y + height ); } -void wxWindowDC::DoDrawEllipse( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) +void wxGTKWindowImplDC::DoDrawEllipse( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) { wxCHECK_RET( Ok(), wxT("invalid window dc") ); @@ -1061,13 +1065,13 @@ void wxWindowDC::DoDrawEllipse( wxCoord x, wxCoord y, wxCoord width, wxCoord hei CalcBoundingBox( x + width, y + height ); } -void wxWindowDC::DoDrawIcon( const wxIcon &icon, wxCoord x, wxCoord y ) +void wxGTKWindowImplDC::DoDrawIcon( const wxIcon &icon, wxCoord x, wxCoord y ) { // VZ: egcs 1.0.3 refuses to compile this without cast, no idea why DoDrawBitmap( (const wxBitmap&)icon, x, y, true ); } -void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, +void wxGTKWindowImplDC::DoDrawBitmap( const wxBitmap &bitmap, wxCoord x, wxCoord y, bool useMask ) { @@ -1199,7 +1203,7 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, } } -bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, +bool wxGTKWindowImplDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height, wxDC *source, wxCoord xsrc, wxCoord ysrc, @@ -1448,7 +1452,7 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, return true; } -void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) +void wxGTKWindowImplDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) { wxCHECK_RET( Ok(), wxT("invalid window dc") ); @@ -1614,7 +1618,7 @@ void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) // a better approach here: // http://www.daa.com.au/pipermail/pygtk/2003-April/005052.html -void wxWindowDC::DoDrawRotatedText( const wxString &text, wxCoord x, wxCoord y, double angle ) +void wxGTKWindowImplDC::DoDrawRotatedText( const wxString &text, wxCoord x, wxCoord y, double angle ) { if (!m_window || text.empty()) return; @@ -1716,7 +1720,7 @@ void wxWindowDC::DoDrawRotatedText( const wxString &text, wxCoord x, wxCoord y, CalcBoundingBox(x + maxX, y + maxY); } -void wxWindowDC::DoGetTextExtent(const wxString &string, +void wxGTKWindowImplDC::DoGetTextExtent(const wxString &string, wxCoord *width, wxCoord *height, wxCoord *descent, wxCoord *externalLeading, const wxFont *theFont) const @@ -1780,7 +1784,7 @@ void wxWindowDC::DoGetTextExtent(const wxString &string, } -bool wxWindowDC::DoGetPartialTextExtents(const wxString& text, +bool wxGTKWindowImplDC::DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths) const { const size_t len = text.length(); @@ -1823,7 +1827,7 @@ bool wxWindowDC::DoGetPartialTextExtents(const wxString& text, } -wxCoord wxWindowDC::GetCharWidth() const +wxCoord wxGTKWindowImplDC::GetCharWidth() const { pango_layout_set_text( m_layout, "H", 1 ); int w; @@ -1831,7 +1835,7 @@ wxCoord wxWindowDC::GetCharWidth() const return w; } -wxCoord wxWindowDC::GetCharHeight() const +wxCoord wxGTKWindowImplDC::GetCharHeight() const { PangoFontMetrics *metrics = pango_context_get_metrics (m_context, m_fontdesc, pango_context_get_language(m_context)); wxCHECK_MSG( metrics, -1, _T("failed to get pango font metrics") ); @@ -1842,7 +1846,7 @@ wxCoord wxWindowDC::GetCharHeight() const return h; } -void wxWindowDC::Clear() +void wxGTKWindowImplDC::Clear() { wxCHECK_RET( Ok(), wxT("invalid window dc") ); @@ -1880,7 +1884,7 @@ void wxWindowDC::Clear() #endif // 0/1 } -void wxWindowDC::SetFont( const wxFont &font ) +void wxGTKWindowImplDC::SetFont( const wxFont &font ) { m_font = font; @@ -1914,7 +1918,7 @@ void wxWindowDC::SetFont( const wxFont &font ) } } -void wxWindowDC::SetPen( const wxPen &pen ) +void wxGTKWindowImplDC::SetPen( const wxPen &pen ) { wxCHECK_RET( Ok(), wxT("invalid window dc") ); @@ -2064,7 +2068,7 @@ void wxWindowDC::SetPen( const wxPen &pen ) gdk_gc_set_foreground( m_penGC, m_pen.GetColour().GetColor() ); } -void wxWindowDC::SetBrush( const wxBrush &brush ) +void wxGTKWindowImplDC::SetBrush( const wxBrush &brush ) { wxCHECK_RET( Ok(), wxT("invalid window dc") ); @@ -2109,7 +2113,7 @@ void wxWindowDC::SetBrush( const wxBrush &brush ) } } -void wxWindowDC::SetBackground( const wxBrush &brush ) +void wxGTKWindowImplDC::SetBackground( const wxBrush &brush ) { /* CMB 21/7/98: Added SetBackground. Sets background brush * for Clear() and bg colour for shapes filled with cross-hatch brush */ @@ -2154,7 +2158,7 @@ void wxWindowDC::SetBackground( const wxBrush &brush ) } } -void wxWindowDC::SetLogicalFunction( int function ) +void wxGTKWindowImplDC::SetLogicalFunction( int function ) { wxCHECK_RET( Ok(), wxT("invalid window dc") ); @@ -2202,7 +2206,7 @@ void wxWindowDC::SetLogicalFunction( int function ) gdk_gc_set_function( m_textGC, mode ); } -void wxWindowDC::SetTextForeground( const wxColour &col ) +void wxGTKWindowImplDC::SetTextForeground( const wxColour &col ) { wxCHECK_RET( Ok(), wxT("invalid window dc") ); @@ -2221,7 +2225,7 @@ void wxWindowDC::SetTextForeground( const wxColour &col ) } } -void wxWindowDC::SetTextBackground( const wxColour &col ) +void wxGTKWindowImplDC::SetTextBackground( const wxColour &col ) { wxCHECK_RET( Ok(), wxT("invalid window dc") ); @@ -2238,7 +2242,7 @@ void wxWindowDC::SetTextBackground( const wxColour &col ) } } -void wxWindowDC::SetBackgroundMode( int mode ) +void wxGTKWindowImplDC::SetBackgroundMode( int mode ) { wxCHECK_RET( Ok(), wxT("invalid window dc") ); @@ -2256,12 +2260,12 @@ void wxWindowDC::SetBackgroundMode( int mode ) } } -void wxWindowDC::SetPalette( const wxPalette& WXUNUSED(palette) ) +void wxGTKWindowImplDC::SetPalette( const wxPalette& WXUNUSED(palette) ) { - wxFAIL_MSG( wxT("wxWindowDC::SetPalette not implemented") ); + wxFAIL_MSG( wxT("wxGTKWindowImplDC::SetPalette not implemented") ); } -void wxWindowDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) +void wxGTKWindowImplDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) { wxCHECK_RET( Ok(), wxT("invalid window dc") ); @@ -2298,7 +2302,7 @@ void wxWindowDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoo gdk_gc_set_clip_region( m_bgGC, m_currentClippingRegion.GetRegion() ); } -void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion ®ion ) +void wxGTKWindowImplDC::DoSetClippingRegionAsRegion( const wxRegion ®ion ) { wxCHECK_RET( Ok(), wxT("invalid window dc") ); @@ -2330,7 +2334,7 @@ void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion ®ion ) gdk_gc_set_clip_region( m_bgGC, m_currentClippingRegion.GetRegion() ); } -void wxWindowDC::DestroyClippingRegion() +void wxGTKWindowImplDC::DestroyClippingRegion() { wxCHECK_RET( Ok(), wxT("invalid window dc") ); @@ -2361,7 +2365,7 @@ void wxWindowDC::DestroyClippingRegion() } } -void wxWindowDC::Destroy() +void wxGTKWindowImplDC::Destroy() { if (m_penGC) wxFreePoolGC( m_penGC ); m_penGC = (GdkGC*) NULL; @@ -2373,7 +2377,7 @@ void wxWindowDC::Destroy() m_bgGC = (GdkGC*) NULL; } -void wxWindowDC::SetDeviceOrigin( wxCoord x, wxCoord y ) +void wxGTKWindowImplDC::SetDeviceOrigin( wxCoord x, wxCoord y ) { m_deviceOriginX = x; m_deviceOriginY = y; @@ -2381,7 +2385,7 @@ void wxWindowDC::SetDeviceOrigin( wxCoord x, wxCoord y ) ComputeScaleAndOrigin(); } -void wxWindowDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp ) +void wxGTKWindowImplDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp ) { m_signX = (xLeftRight ? 1 : -1); m_signY = (yBottomUp ? -1 : 1); @@ -2392,7 +2396,7 @@ void wxWindowDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp ) ComputeScaleAndOrigin(); } -void wxWindowDC::ComputeScaleAndOrigin() +void wxGTKWindowImplDC::ComputeScaleAndOrigin() { const wxRealPoint origScale(m_scaleX, m_scaleY); @@ -2410,12 +2414,12 @@ void wxWindowDC::ComputeScaleAndOrigin() } // Resolution in pixels per logical inch -wxSize wxWindowDC::GetPPI() const +wxSize wxGTKWindowImplDC::GetPPI() const { return wxSize( (int) (m_mm_to_pix_x * 25.4 + 0.5), (int) (m_mm_to_pix_y * 25.4 + 0.5)); } -int wxWindowDC::GetDepth() const +int wxGTKWindowImplDC::GetDepth() const { return gdk_drawable_get_depth(m_window); } @@ -2425,7 +2429,11 @@ int wxWindowDC::GetDepth() const // wxPaintDC //----------------------------------------------------------------------------- +#if wxUSE_NEW_DC +IMPLEMENT_DYNAMIC_CLASS(wxGTKPaintImplDC, wxGTKClientImplDC) +#else IMPLEMENT_DYNAMIC_CLASS(wxPaintDC, wxClientDC) +#endif // Limit the paint region to the window size. Sometimes // the paint region is too big, and this risks X11 errors @@ -2446,8 +2454,8 @@ static void wxLimitRegionToSize(wxRegion& region, const wxSize& sz) } } -wxPaintDC::wxPaintDC( wxWindow *win ) - : wxClientDC( win ) +wxGTKPaintImplDC::wxGTKPaintImplDC( wxWindow *win ) + : wxGTKClientImplDC( win ) { #if USE_PAINT_REGION if (!win->m_clipPaintRegion) @@ -2478,12 +2486,16 @@ wxPaintDC::wxPaintDC( wxWindow *win ) // wxClientDC //----------------------------------------------------------------------------- +#if wxUSE_NEW_DC +IMPLEMENT_DYNAMIC_CLASS(wxGTKClientImplDC, wxGTKWindowImplDC) +#else IMPLEMENT_DYNAMIC_CLASS(wxClientDC, wxWindowDC) +#endif -wxClientDC::wxClientDC( wxWindow *win ) - : wxWindowDC( win ) +wxGTKClientImplDC::wxGTKClientImplDC( wxWindow *win ) + : wxGTKWindowImplDC( win ) { - wxCHECK_RET( win, _T("NULL window in wxClientDC::wxClientDC") ); + wxCHECK_RET( win, _T("NULL window in wxGTKClientImplDC::wxClientDC") ); #ifdef __WXUNIVERSAL__ wxPoint ptOrigin = win->GetClientAreaOrigin(); @@ -2493,7 +2505,7 @@ wxClientDC::wxClientDC( wxWindow *win ) #endif // __WXUNIVERSAL__ } -void wxClientDC::DoGetSize(int *width, int *height) const +void wxGTKClientImplDC::DoGetSize(int *width, int *height) const { wxCHECK_RET( m_owner, _T("GetSize() doesn't work without window") );