X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a23fd0e1d1329a4a258b4defb3e0b0001b700c6e..821baf7da4a57028eaa17830b6195056216b71f9:/include/wx/msw/dc.h diff --git a/include/wx/msw/dc.h b/include/wx/msw/dc.h index f2ca533725..908e24bcff 100644 --- a/include/wx/msw/dc.h +++ b/include/wx/msw/dc.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: dc.h +// Name: wx/msw/dc.h // Purpose: wxDC class // Author: Julian Smart // Modified by: @@ -9,20 +9,45 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifndef _WX_DC_H_ -#define _WX_DC_H_ +#ifndef _WX_MSW_DC_H_ +#define _WX_MSW_DC_H_ -#ifdef __GNUG__ - #pragma interface "dc.h" -#endif +#include "wx/defs.h" +#include "wx/dc.h" + +// --------------------------------------------------------------------------- +// macros +// --------------------------------------------------------------------------- + +#if wxUSE_DC_CACHEING +/* + * Cached blitting, maintaining a cache + * of bitmaps required for transparent blitting + * instead of constant creation/deletion + */ -class WXDLLEXPORT wxDC : public wxDCBase +class wxDCCacheEntry: public wxObject { - DECLARE_DYNAMIC_CLASS(wxDC) +public: + wxDCCacheEntry(WXHBITMAP hBitmap, int w, int h, int depth); + wxDCCacheEntry(WXHDC hDC, int depth); + virtual ~wxDCCacheEntry(); + + WXHBITMAP m_bitmap; + WXHDC m_dc; + int m_width; + int m_height; + int m_depth; +}; +#endif +// this is an ABC: use one of the derived classes to create a DC associated +// with a window, screen, printer and so on +class WXDLLIMPEXP_CORE wxMSWDCImpl: public wxDCImpl +{ public: - wxDC(); - ~wxDC(); + wxMSWDCImpl(wxDC *owner, WXHDC hDC); + virtual ~wxMSWDCImpl(); // implement base class pure virtuals // ---------------------------------- @@ -40,109 +65,221 @@ public: virtual void SetBrush(const wxBrush& brush); virtual void SetBackground(const wxBrush& brush); virtual void SetBackgroundMode(int mode); +#if wxUSE_PALETTE virtual void SetPalette(const wxPalette& palette); +#endif // wxUSE_PALETTE virtual void DestroyClippingRegion(); - virtual long GetCharHeight() const; - virtual long GetCharWidth() const; - virtual void GetTextExtent(const wxString& string, - long *x, long *y, - long *descent = NULL, - long *externalLeading = NULL, - wxFont *theFont = NULL) const; + virtual wxCoord GetCharHeight() const; + virtual wxCoord GetCharWidth() const; virtual bool CanDrawBitmap() const; virtual bool CanGetTextExtent() const; virtual int GetDepth() const; virtual wxSize GetPPI() const; - virtual void SetMapMode(int mode); + + virtual void SetMapMode(wxMappingMode mode); virtual void SetUserScale(double x, double y); - virtual void SetSystemScale(double x, double y); virtual void SetLogicalScale(double x, double y); - virtual void SetLogicalOrigin(long x, long y); - virtual void SetDeviceOrigin(long x, long y); + virtual void SetLogicalOrigin(wxCoord x, wxCoord y); + virtual void SetDeviceOrigin(wxCoord x, wxCoord y); virtual void SetAxisOrientation(bool xLeftRight, bool yBottomUp); - virtual void SetLogicalFunction(int function); + + virtual void SetLogicalFunction(wxRasterOperationMode function); // implementation from now on // -------------------------- virtual void SetRop(WXHDC cdc); - virtual void DoClipping(WXHDC cdc); virtual void SelectOldObjects(WXHDC dc); - wxWindow *GetWindow() const { return m_canvas; } - void SetWindow(wxWindow *win) { m_canvas = win; } + void SetWindow(wxWindow *win) + { + m_window = win; + +#if wxUSE_PALETTE + // if we have palettes use the correct one for this window + InitializePalette(); +#endif // wxUSE_PALETTE + } WXHDC GetHDC() const { return m_hDC; } - void SetHDC(WXHDC dc, bool bOwnsDC = FALSE) + void SetHDC(WXHDC dc, bool bOwnsDC = false) { m_hDC = dc; m_bOwnsDC = bOwnsDC; + + // we might have a pre existing clipping region, make sure that we + // return it if asked -- but avoid calling ::GetClipBox() right now as + // it could be unnecessary wasteful + m_clipping = true; + m_clipX1 = + m_clipX2 = 0; } + const wxBitmap& GetSelectedBitmap() const { return m_selectedBitmap; } + wxBitmap& GetSelectedBitmap() { return m_selectedBitmap; } + + // update the internal clip box variables + void UpdateClipBox(); + +#if wxUSE_DC_CACHEING + static wxDCCacheEntry* FindBitmapInCache(WXHDC hDC, int w, int h); + static wxDCCacheEntry* FindDCInCache(wxDCCacheEntry* notThis, WXHDC hDC); + + static void AddToBitmapCache(wxDCCacheEntry* entry); + static void AddToDCCache(wxDCCacheEntry* entry); + static void ClearCache(); +#endif + + // RTL related functions + // --------------------- + + // get or change the layout direction (LTR or RTL) for this dc, + // wxLayout_Default is returned if layout direction is not supported + virtual wxLayoutDirection GetLayoutDirection() const; + virtual void SetLayoutDirection(wxLayoutDirection dir); + protected: - virtual void DoFloodFill(long x, long y, const wxColour& col, - int style = wxFLOOD_SURFACE); + void Init() + { + m_bOwnsDC = false; + m_hDC = NULL; - virtual bool DoGetPixel(long x, long y, wxColour *col) const; + m_oldBitmap = NULL; + m_oldPen = NULL; + m_oldBrush = NULL; + m_oldFont = NULL; - virtual void DoDrawPoint(long x, long y); - virtual void DoDrawLine(long x1, long y1, long x2, long y2); +#if wxUSE_PALETTE + m_oldPalette = NULL; +#endif // wxUSE_PALETTE + } + + // create an uninitialized DC: this should be only used by the derived + // classes + wxMSWDCImpl( wxDC *owner ) : wxDCImpl( owner ) { Init(); } - virtual void DoDrawArc(long x1, long y1, - long x2, long y2, - long xc, long yc); - virtual void DoDrawEllipticArc(long x, long y, long w, long h, + void RealizeScaleAndOrigin(); + +public: + virtual void DoGetTextExtent(const wxString& string, + wxCoord *x, wxCoord *y, + wxCoord *descent = NULL, + wxCoord *externalLeading = NULL, + const wxFont *theFont = NULL) const; + virtual bool DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths) const; + + virtual bool DoFloodFill(wxCoord x, wxCoord y, const wxColour& col, + wxFloodFillStyle style = wxFLOOD_SURFACE); + + virtual void DoGradientFillLinear(const wxRect& rect, + const wxColour& initialColour, + const wxColour& destColour, + wxDirection nDirection = wxEAST); + + virtual bool DoGetPixel(wxCoord x, wxCoord y, wxColour *col) const; + + virtual void DoDrawPoint(wxCoord x, wxCoord y); + virtual void DoDrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2); + + virtual void DoDrawArc(wxCoord x1, wxCoord y1, + wxCoord x2, wxCoord y2, + wxCoord xc, wxCoord yc); + 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); - virtual void DoDrawRectangle(long x, long y, long width, long height); - virtual void DoDrawRoundedRectangle(long x, long y, - long width, long height, + virtual void DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height); + virtual void DoDrawRoundedRectangle(wxCoord x, wxCoord y, + wxCoord width, wxCoord height, double radius); - virtual void DoDrawEllipse(long x, long y, long width, long height); + virtual void DoDrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height); - virtual void DoCrossHair(long x, long y); +#if wxUSE_SPLINES && !defined(__WXWINCE__) + virtual void DoDrawSpline(const wxPointList *points); +#endif - virtual void DoDrawIcon(const wxIcon& icon, long x, long y); - virtual void DoDrawBitmap(const wxBitmap &bmp, long x, long y, - bool useMask = FALSE); + virtual void DoCrossHair(wxCoord x, wxCoord y); - virtual void DoDrawText(const wxString& text, long x, long y); + virtual void DoDrawIcon(const wxIcon& icon, wxCoord x, wxCoord y); + virtual void DoDrawBitmap(const wxBitmap &bmp, wxCoord x, wxCoord y, + bool useMask = false); - virtual bool DoBlit(long xdest, long ydest, long width, long height, - wxDC *source, long xsrc, long ysrc, - int rop = wxCOPY, bool useMask = FALSE); + virtual void DoDrawText(const wxString& text, wxCoord x, wxCoord y); + virtual void DoDrawRotatedText(const wxString& text, wxCoord x, wxCoord y, + double angle); - // this is gnarly - we can't even call this function DoSetClippingRegion() - // because of virtual function hiding - virtual void DoSetClippingRegionAsRegion(const wxRegion& region); - virtual void DoSetClippingRegion(long x, long y, - long width, long height); - virtual void DoGetClippingRegion(long *x, long *y, - long *width, long *height) - { - GetClippingBox(x, y, width, height); - } + virtual bool DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height, + wxDC *source, wxCoord xsrc, wxCoord ysrc, + wxRasterOperationMode rop = wxCOPY, bool useMask = false, + wxCoord xsrcMask = wxDefaultCoord, wxCoord ysrcMask = wxDefaultCoord); + + virtual bool DoStretchBlit(wxCoord xdest, wxCoord ydest, + wxCoord dstWidth, wxCoord dstHeight, + wxDC *source, + wxCoord xsrc, wxCoord ysrc, + wxCoord srcWidth, wxCoord srcHeight, + wxRasterOperationMode rop = wxCOPY, bool useMask = false, + wxCoord xsrcMask = wxDefaultCoord, wxCoord ysrcMask = wxDefaultCoord); + + virtual void DoSetClippingRegion(wxCoord x, wxCoord y, + wxCoord width, wxCoord height); + virtual void DoSetDeviceClippingRegion(const wxRegion& region); + virtual void DoGetClippingBox(wxCoord *x, wxCoord *y, + wxCoord *w, wxCoord *h) const; - virtual void DoGetSize(int *width, int *height) const; virtual void DoGetSizeMM(int* width, int* height) const; virtual void DoDrawLines(int n, wxPoint points[], - long xoffset, long yoffset); + wxCoord xoffset, wxCoord yoffset); virtual void DoDrawPolygon(int n, wxPoint points[], - long xoffset, long yoffset, - int fillStyle = wxODDEVEN_RULE); + wxCoord xoffset, wxCoord yoffset, + wxPolygonFillMode fillStyle = wxODDEVEN_RULE); + virtual void DoDrawPolyPolygon(int n, int count[], wxPoint points[], + wxCoord xoffset, wxCoord yoffset, + wxPolygonFillMode fillStyle = wxODDEVEN_RULE); + virtual wxBitmap DoGetAsBitmap(const wxRect *subrect) const + { + return subrect == NULL ? GetSelectedBitmap() + : GetSelectedBitmap().GetSubBitmap(*subrect); + } + + +#if wxUSE_PALETTE + // MSW specific, select a logical palette into the HDC + // (tell windows to translate pixel from other palettes to our custom one + // and vice versa) + // Realize tells it to also reset the system palette to this one. + void DoSelectPalette(bool realize = false); + + // Find out what palette our parent window has, then select it into the dc + void InitializePalette(); +#endif // wxUSE_PALETTE + +protected: + // common part of DoDrawText() and DoDrawRotatedText() + void DrawAnyText(const wxString& text, wxCoord x, wxCoord y); + + // common part of DoSetClippingRegion() and DoSetDeviceClippingRegion() + void SetClippingHrgn(WXHRGN hrgn); + + // implementation of DoGetSize() for wxScreen/PrinterDC: this simply + // returns the size of the entire device this DC is associated with + // + // notice that we intentionally put it in a separate function instead of + // DoGetSize() itself because we want it to remain pure virtual both + // because each derived class should take care to define it as needed (this + // implementation is not at all always appropriate) and because we want + // wxDC to be an ABC to prevent it from being created directly + void GetDeviceSize(int *width, int *height) const; -#if wxUSE_SPLINES - virtual void DoDrawSpline(wxList *points); -#endif // wxUSE_SPLINES // MSW-specific member variables - int m_windowExtX; - int m_windowExtY; + // ----------------------------- // the window associated with this DC (may be NULL) wxWindow *m_canvas; @@ -152,10 +289,8 @@ protected: // TRUE => DeleteDC() in dtor, FALSE => only ReleaseDC() it bool m_bOwnsDC:1; - // our HDC and its usage count: we only free it when the usage count drops - // to 0 + // our HDC WXHDC m_hDC; - int m_hDCCount; // Store all old GDI objects when do a SelectObject, so we can select them // back in (this unselecting user's objects) so we can safely delete the @@ -164,70 +299,69 @@ protected: WXHPEN m_oldPen; WXHBRUSH m_oldBrush; WXHFONT m_oldFont; - WXHPALETTE m_oldPalette; -}; - -// Logical to device -// Absolute -#define XLOG2DEV(x) (x) -#define YLOG2DEV(y) (y) -// Relative -#define XLOG2DEVREL(x) (x) -#define YLOG2DEVREL(y) (y) - -// Device to logical -// Absolute -#define XDEV2LOG(x) (x) - -#define YDEV2LOG(y) (y) - -// Relative -#define XDEV2LOGREL(x) (x) -#define YDEV2LOGREL(y) (y) - -/* - * Have the same macros as for XView but not for every operation: - * just for calculating window/viewport extent (a better way of scaling). - */ - -// Logical to device -// Absolute -#define MS_XLOG2DEV(x) LogicalToDevice(x) +#if wxUSE_PALETTE + WXHPALETTE m_oldPalette; +#endif // wxUSE_PALETTE -#define MS_YLOG2DEV(y) LogicalToDevice(y) +#if wxUSE_DC_CACHEING + static wxObjectList sm_bitmapCache; + static wxObjectList sm_dcCache; +#endif -// Relative -#define MS_XLOG2DEVREL(x) LogicalToDeviceXRel(x) -#define MS_YLOG2DEVREL(y) LogicalToDeviceYRel(y) + DECLARE_CLASS(wxMSWDCImpl) + DECLARE_NO_COPY_CLASS(wxMSWDCImpl) +}; -// Device to logical -// Absolute -#define MS_XDEV2LOG(x) DeviceToLogicalX(x) +// ---------------------------------------------------------------------------- +// wxDCTemp: a wxDC which doesn't free the given HDC (used by wxWidgets +// only/mainly) +// ---------------------------------------------------------------------------- -#define MS_YDEV2LOG(y) DeviceToLogicalY(y) +class WXDLLIMPEXP_CORE wxDCTempImpl : public wxMSWDCImpl +{ +public: + // construct a temporary DC with the specified HDC and size (it should be + // specified whenever we know it for this HDC) + wxDCTempImpl(wxDC *owner, WXHDC hdc, const wxSize& size ) + : wxMSWDCImpl( owner, hdc ), + m_size(size) + { + } -// Relative -#define MS_XDEV2LOGREL(x) DeviceToLogicalXRel(x) -#define MS_YDEV2LOGREL(y) DeviceToLogicalYRel(y) + virtual ~wxDCTempImpl() + { + // prevent base class dtor from freeing it + SetHDC((WXHDC)NULL); + } -#define MM_POINTS 9 -#define MM_METRIC 10 + virtual void DoGetSize(int *w, int *h) const + { + wxASSERT_MSG( m_size.IsFullySpecified(), + _T("size of this DC hadn't been set and is unknown") ); -// Conversion -#define METRIC_CONVERSION_CONSTANT 0.0393700787 + if ( w ) + *w = m_size.x; + if ( h ) + *h = m_size.y; + } -// Scaling factors for various unit conversions -#define mm2inches (METRIC_CONVERSION_CONSTANT) -#define inches2mm (1/METRIC_CONVERSION_CONSTANT) +private: + // size of this DC must be explicitly set by SetSize() as we have no way to + // find it ourselves + const wxSize m_size; -#define mm2twips (METRIC_CONVERSION_CONSTANT*1440) -#define twips2mm (1/(METRIC_CONVERSION_CONSTANT*1440)) + DECLARE_NO_COPY_CLASS(wxDCTempImpl) +}; -#define mm2pt (METRIC_CONVERSION_CONSTANT*72) -#define pt2mm (1/(METRIC_CONVERSION_CONSTANT*72)) +class WXDLLIMPEXP_CORE wxDCTemp : public wxDC +{ +public: + wxDCTemp(WXHDC hdc, const wxSize& size = wxDefaultSize) + : wxDC(new wxDCTempImpl(this, hdc, size)) + { + } +}; -#define wx_round(a) (int)((a)+.5) +#endif // _WX_MSW_DC_H_ -#endif - // _WX_DC_H_