X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/0b7dce5480b8cf7ce4368122744d853f7a684e34..2aa54d47d66b5cda0dca2b743e11c954581a7b99:/include/wx/graphics.h diff --git a/include/wx/graphics.h b/include/wx/graphics.h index ede12ad06c..6b1a0ee5f1 100644 --- a/include/wx/graphics.h +++ b/include/wx/graphics.h @@ -18,12 +18,67 @@ #include "wx/geometry.h" #include "wx/dynarray.h" +#include "wx/dc.h" +#include "wx/image.h" +#include "wx/vector.h" + +enum wxAntialiasMode +{ + wxANTIALIAS_NONE, // should be 0 + wxANTIALIAS_DEFAULT +}; + +enum wxInterpolationQuality +{ + // default interpolation + wxINTERPOLATION_DEFAULT, + // no interpolation + wxINTERPOLATION_NONE, + // fast interpolation, suited for interactivity + wxINTERPOLATION_FAST, + // better quality + wxINTERPOLATION_GOOD, + // best quality, not suited for interactivity + wxINTERPOLATION_BEST +}; + +enum wxCompositionMode +{ + // R = Result, S = Source, D = Destination, premultiplied with alpha + // Ra, Sa, Da their alpha components + + // classic Porter-Duff compositions + // http://keithp.com/~keithp/porterduff/p253-porter.pdf + + wxCOMPOSITION_INVALID = -1, /* indicates invalid/unsupported mode */ + wxCOMPOSITION_CLEAR, /* R = 0 */ + wxCOMPOSITION_SOURCE, /* R = S */ + wxCOMPOSITION_OVER, /* R = S + D*(1 - Sa) */ + wxCOMPOSITION_IN, /* R = S*Da */ + wxCOMPOSITION_OUT, /* R = S*(1 - Da) */ + wxCOMPOSITION_ATOP, /* R = S*Da + D*(1 - Sa) */ + + wxCOMPOSITION_DEST, /* R = D, essentially a noop */ + wxCOMPOSITION_DEST_OVER, /* R = S*(1 - Da) + D */ + wxCOMPOSITION_DEST_IN, /* R = D*Sa */ + wxCOMPOSITION_DEST_OUT, /* R = D*(1 - Sa) */ + wxCOMPOSITION_DEST_ATOP, /* R = S*(1 - Da) + D*Sa */ + wxCOMPOSITION_XOR, /* R = S*(1 - Da) + D*(1 - Sa) */ + + // mathematical compositions + wxCOMPOSITION_ADD /* R = S + D */ +}; class WXDLLIMPEXP_FWD_CORE wxWindowDC; class WXDLLIMPEXP_FWD_CORE wxMemoryDC; #if wxUSE_PRINTING_ARCHITECTURE class WXDLLIMPEXP_FWD_CORE wxPrinterDC; #endif +#ifdef __WXMSW__ +#if wxUSE_ENH_METAFILE +class WXDLLIMPEXP_FWD_CORE wxEnhMetaFileDC; +#endif +#endif class WXDLLIMPEXP_FWD_CORE wxGraphicsContext; class WXDLLIMPEXP_FWD_CORE wxGraphicsPath; class WXDLLIMPEXP_FWD_CORE wxGraphicsMatrix; @@ -52,6 +107,7 @@ class WXDLLIMPEXP_FWD_CORE wxGraphicsBitmap; // class WXDLLIMPEXP_FWD_CORE wxGraphicsObjectRefData; +class WXDLLIMPEXP_FWD_CORE wxGraphicsBitmapData; class WXDLLIMPEXP_FWD_CORE wxGraphicsMatrixData; class WXDLLIMPEXP_FWD_CORE wxGraphicsPathData; @@ -112,6 +168,21 @@ class WXDLLIMPEXP_CORE wxGraphicsBitmap : public wxGraphicsObject public: wxGraphicsBitmap() {} virtual ~wxGraphicsBitmap() {} + + // Convert bitmap to wxImage: this is more efficient than converting to + // wxBitmap first and then to wxImage and also works without X server + // connection under Unix that wxBitmap requires. +#if wxUSE_IMAGE + wxImage ConvertToImage() const; +#endif // wxUSE_IMAGE + + void* GetNativeBitmap() const; + + const wxGraphicsBitmapData* GetBitmapData() const + { return (const wxGraphicsBitmapData*) GetRefData(); } + wxGraphicsBitmapData* GetBitmapData() + { return (wxGraphicsBitmapData*) GetRefData(); } + private: DECLARE_DYNAMIC_CLASS(wxGraphicsBitmap) }; @@ -256,8 +327,8 @@ public: virtual void GetBox(wxDouble *x, wxDouble *y, wxDouble *w, wxDouble *h)const; wxRect2DDouble GetBox()const; - virtual bool Contains( wxDouble x, wxDouble y, int fillStyle = wxODDEVEN_RULE)const; - bool Contains( const wxPoint2DDouble& c, int fillStyle = wxODDEVEN_RULE)const; + virtual bool Contains( wxDouble x, wxDouble y, wxPolygonFillMode fillStyle = wxODDEVEN_RULE)const; + bool Contains( const wxPoint2DDouble& c, wxPolygonFillMode fillStyle = wxODDEVEN_RULE)const; const wxGraphicsPathData* GetPathData() const { return (const wxGraphicsPathData*) GetRefData(); } @@ -271,6 +342,82 @@ private: extern WXDLLIMPEXP_DATA_CORE(wxGraphicsPath) wxNullGraphicsPath; +// Describes a single gradient stop. +class wxGraphicsGradientStop +{ +public: + wxGraphicsGradientStop(wxColour col = wxTransparentColour, + float pos = 0.) + : m_col(col), + m_pos(pos) + { + } + + // default copy ctor, assignment operator and dtor are ok + + const wxColour& GetColour() const { return m_col; } + void SetColour(const wxColour& col) { m_col = col; } + + float GetPosition() const { return m_pos; } + void SetPosition(float pos) + { + wxASSERT_MSG( pos >= 0 && pos <= 1, "invalid gradient stop position" ); + + m_pos = pos; + } + +private: + // The colour of this gradient band. + wxColour m_col; + + // Its starting position: 0 is the beginning and 1 is the end. + float m_pos; +}; + +// A collection of gradient stops ordered by their positions (from lowest to +// highest). The first stop (index 0, position 0.0) is always the starting +// colour and the last one (index GetCount() - 1, position 1.0) is the end +// colour. +class WXDLLIMPEXP_CORE wxGraphicsGradientStops +{ +public: + wxGraphicsGradientStops(wxColour startCol = wxTransparentColour, + wxColour endCol = wxTransparentColour) + { + // we can't use Add() here as it relies on having start/end stops as + // first/last array elements so do it manually + m_stops.push_back(wxGraphicsGradientStop(startCol, 0.f)); + m_stops.push_back(wxGraphicsGradientStop(endCol, 1.f)); + } + + // default copy ctor, assignment operator and dtor are ok for this class + + + // Add a stop in correct order. + void Add(const wxGraphicsGradientStop& stop); + void Add(wxColour col, float pos) { Add(wxGraphicsGradientStop(col, pos)); } + + // Get the number of stops. + size_t GetCount() const { return m_stops.size(); } + + // Return the stop at the given index (which must be valid). + wxGraphicsGradientStop Item(unsigned n) const { return m_stops.at(n); } + + // Get/set start and end colours. + void SetStartColour(wxColour col) + { m_stops[0].SetColour(col); } + wxColour GetStartColour() const + { return m_stops[0].GetColour(); } + void SetEndColour(wxColour col) + { m_stops[m_stops.size() - 1].SetColour(col); } + wxColour GetEndColour() const + { return m_stops[m_stops.size() - 1].GetColour(); } + +private: + // All the stops stored in ascending order of positions. + wxVector m_stops; +}; + class WXDLLIMPEXP_CORE wxGraphicsContext : public wxGraphicsObject { public: @@ -282,6 +429,11 @@ public: static wxGraphicsContext * Create( const wxMemoryDC& dc); #if wxUSE_PRINTING_ARCHITECTURE static wxGraphicsContext * Create( const wxPrinterDC& dc); +#endif +#ifdef __WXMSW__ +#if wxUSE_ENH_METAFILE + static wxGraphicsContext * Create( const wxEnhMetaFileDC& dc); +#endif #endif static wxGraphicsContext* CreateFromNative( void * context ); @@ -290,6 +442,13 @@ public: static wxGraphicsContext* Create( wxWindow* window ); +#if wxUSE_IMAGE + // Create a context for drawing onto a wxImage. The image life time must be + // greater than that of the context itself as when the context is destroyed + // it will copy its contents to the specified image. + static wxGraphicsContext* Create(wxImage& image); +#endif // wxUSE_IMAGE + // create a context that can be used for measuring texts only, no drawing allowed static wxGraphicsContext * Create(); @@ -315,20 +474,42 @@ public: virtual wxGraphicsBrush CreateBrush(const wxBrush& brush ) const; - // sets the brush to a linear gradient, starting at (x1,y1) with color c1 to (x2,y2) with color c2 - virtual wxGraphicsBrush CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2, - const wxColour&c1, const wxColour&c2) const; - - // sets the brush to a radial gradient originating at (xo,yc) with color oColor and ends on a circle around (xc,yc) - // with radius r and color cColor - virtual wxGraphicsBrush CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius, - const wxColour &oColor, const wxColour &cColor) const; - - // sets the font + // sets the brush to a linear gradient, starting at (x1,y1) and ending at + // (x2,y2) with the given boundary colours or the specified stops + wxGraphicsBrush + CreateLinearGradientBrush(wxDouble x1, wxDouble y1, + wxDouble x2, wxDouble y2, + const wxColour& c1, const wxColour& c2) const; + wxGraphicsBrush + CreateLinearGradientBrush(wxDouble x1, wxDouble y1, + wxDouble x2, wxDouble y2, + const wxGraphicsGradientStops& stops) const; + + // sets the brush to a radial gradient originating at (xo,yc) and ending + // on a circle around (xc,yc) with the given radius; the colours may be + // specified by just the two extremes or the full array of gradient stops + wxGraphicsBrush + CreateRadialGradientBrush(wxDouble xo, wxDouble yo, + wxDouble xc, wxDouble yc, wxDouble radius, + const wxColour& oColor, const wxColour& cColor) const; + + wxGraphicsBrush + CreateRadialGradientBrush(wxDouble xo, wxDouble yo, + wxDouble xc, wxDouble yc, wxDouble radius, + const wxGraphicsGradientStops& stops) const; + + // creates a font virtual wxGraphicsFont CreateFont( const wxFont &font , const wxColour &col = *wxBLACK ) const; + virtual wxGraphicsFont CreateFont(double sizeInPixels, + const wxString& facename, + int flags = wxFONTFLAG_DEFAULT, + const wxColour& col = *wxBLACK) const; // create a native bitmap representation virtual wxGraphicsBitmap CreateBitmap( const wxBitmap &bitmap ) const; +#if wxUSE_IMAGE + wxGraphicsBitmap CreateBitmapFromImage(const wxImage& image) const; +#endif // wxUSE_IMAGE // create a native bitmap representation virtual wxGraphicsBitmap CreateSubBitmap( const wxGraphicsBitmap &bitmap, wxDouble x, wxDouble y, wxDouble w, wxDouble h ) const; @@ -337,6 +518,16 @@ public: virtual wxGraphicsMatrix CreateMatrix( wxDouble a=1.0, wxDouble b=0.0, wxDouble c=0.0, wxDouble d=1.0, wxDouble tx=0.0, wxDouble ty=0.0) const; + wxGraphicsMatrix CreateMatrix( const wxAffineMatrix2DBase& mat ) const + { + wxMatrix2D mat2D; + wxPoint2DDouble tr; + mat.Get(&mat2D, &tr); + + return CreateMatrix(mat2D.m_11, mat2D.m_12, mat2D.m_21, mat2D.m_22, + tr.m_x, tr.m_y); + } + // push the current state of the context, ie the transformation matrix on a stack virtual void PushState() = 0; @@ -355,14 +546,32 @@ public: // returns the native context virtual void * GetNativeContext() = 0; - // returns the current logical function - virtual int GetLogicalFunction() const { return m_logicalFunction; } + // returns the current shape antialiasing mode + virtual wxAntialiasMode GetAntialiasMode() const { return m_antialias; } + + // sets the antialiasing mode, returns true if it supported + virtual bool SetAntialiasMode(wxAntialiasMode antialias) = 0; - // sets the current logical function, returns true if it supported - virtual bool SetLogicalFunction(int function); + // returns the current interpolation quality + virtual wxInterpolationQuality GetInterpolationQuality() const { return m_interpolation; } + + // sets the interpolation quality, returns true if it supported + virtual bool SetInterpolationQuality(wxInterpolationQuality interpolation) = 0; + + // returns the current compositing operator + virtual wxCompositionMode GetCompositionMode() const { return m_composition; } + + // sets the compositing operator, returns true if it supported + virtual bool SetCompositionMode(wxCompositionMode op) = 0; // returns the size of the graphics context in device coordinates - virtual void GetSize( wxDouble* width, wxDouble* height); + void GetSize(wxDouble* width, wxDouble* height) const + { + if ( width ) + *width = m_width; + if ( height ) + *height = m_height; + } // returns the resolution of the graphics context in device points per inch virtual void GetDPI( wxDouble* dpiX, wxDouble* dpiY); @@ -374,6 +583,14 @@ public: // returns the alpha on this context virtual wxDouble GetAlpha() const; #endif + + // all rendering is done into a fully transparent temporary context + virtual void BeginLayer(wxDouble opacity) = 0; + + // composites back the drawings into the context with the opacity given at + // the BeginLayer call + virtual void EndLayer() = 0; + // // transformation : changes the current transformation matrix CTM of the context // @@ -419,10 +636,10 @@ public: virtual void StrokePath( const wxGraphicsPath& path ) = 0; // fills a path with the current brush - virtual void FillPath( const wxGraphicsPath& path, int fillStyle = wxODDEVEN_RULE ) = 0; + virtual void FillPath( const wxGraphicsPath& path, wxPolygonFillMode fillStyle = wxODDEVEN_RULE ) = 0; // draws a path by first filling and then stroking - virtual void DrawPath( const wxGraphicsPath& path, int fillStyle = wxODDEVEN_RULE ); + virtual void DrawPath( const wxGraphicsPath& path, wxPolygonFillMode fillStyle = wxODDEVEN_RULE ); // // text @@ -444,7 +661,7 @@ public: virtual void GetTextExtent( const wxString &text, wxDouble *width, wxDouble *height, - wxDouble *descent, wxDouble *externalLeading ) const = 0; + wxDouble *descent = NULL, wxDouble *externalLeading = NULL ) const = 0; virtual void GetPartialTextExtents(const wxString& text, wxArrayDouble& widths) const = 0; @@ -452,9 +669,7 @@ public: // image support // -#ifndef __WXGTK20__ virtual void DrawBitmap( const wxGraphicsBitmap &bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h ) = 0; -#endif virtual void DrawBitmap( const wxBitmap &bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h ) = 0; @@ -474,9 +689,9 @@ public: virtual void StrokeLines( size_t n, const wxPoint2DDouble *beginPoints, const wxPoint2DDouble *endPoints); // draws a polygon - virtual void DrawLines( size_t n, const wxPoint2DDouble *points, int fillStyle = wxODDEVEN_RULE ); + virtual void DrawLines( size_t n, const wxPoint2DDouble *points, wxPolygonFillMode fillStyle = wxODDEVEN_RULE ); - // draws a polygon + // draws a rectangle virtual void DrawRectangle( wxDouble x, wxDouble y, wxDouble w, wxDouble h); // draws an ellipse @@ -489,15 +704,28 @@ public: // helper to determine if a 0.5 offset should be applied for the drawing operation virtual bool ShouldOffset() const { return false; } - + + // indicates whether the context should try to offset for pixel boundaries, this only makes sense on + // bitmap devices like screen, by default this is turned off + virtual void EnableOffset(bool enable = true); + + void DisableOffset() { EnableOffset(false); } + bool OffsetEnabled() { return m_enableOffset; } + protected: + // These fields must be initialized in the derived class ctors. + wxDouble m_width, + m_height; wxGraphicsPen m_pen; wxGraphicsBrush m_brush; wxGraphicsFont m_font; - int m_logicalFunction; + wxAntialiasMode m_antialias; + wxCompositionMode m_composition; + wxInterpolationQuality m_interpolation; + bool m_enableOffset; -private: +protected: // implementations of overloaded public functions: we use different names // for them to avoid the virtual function hiding problems in the derived // classes @@ -511,7 +739,7 @@ private: wxDouble angle, const wxGraphicsBrush& backgroundBrush); - DECLARE_NO_COPY_CLASS(wxGraphicsContext) + wxDECLARE_NO_COPY_CLASS(wxGraphicsContext); DECLARE_ABSTRACT_CLASS(wxGraphicsContext) }; @@ -565,12 +793,18 @@ public: static wxGraphicsRenderer* GetDefaultRenderer(); + static wxGraphicsRenderer* GetCairoRenderer(); // Context virtual wxGraphicsContext * CreateContext( const wxWindowDC& dc) = 0; virtual wxGraphicsContext * CreateContext( const wxMemoryDC& dc) = 0; #if wxUSE_PRINTING_ARCHITECTURE virtual wxGraphicsContext * CreateContext( const wxPrinterDC& dc) = 0; +#endif +#ifdef __WXMSW__ +#if wxUSE_ENH_METAFILE + virtual wxGraphicsContext * CreateContext( const wxEnhMetaFileDC& dc) = 0; +#endif #endif virtual wxGraphicsContext * CreateContextFromNativeContext( void * context ) = 0; @@ -579,6 +813,10 @@ public: virtual wxGraphicsContext * CreateContext( wxWindow* window ) = 0; +#if wxUSE_IMAGE + virtual wxGraphicsContext * CreateContextFromImage(wxImage& image) = 0; +#endif // wxUSE_IMAGE + // create a context that can be used for measuring texts only, no drawing allowed virtual wxGraphicsContext * CreateMeasuringContext() = 0; @@ -597,32 +835,55 @@ public: virtual wxGraphicsBrush CreateBrush(const wxBrush& brush ) = 0; - // sets the brush to a linear gradient, starting at (x1,y1) with color c1 to (x2,y2) with color c2 - virtual wxGraphicsBrush CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2, - const wxColour&c1, const wxColour&c2) = 0; + // Gradient brush creation functions may not honour all the stops specified + // stops and use just its boundary colours (this is currently the case + // under OS X) + virtual wxGraphicsBrush + CreateLinearGradientBrush(wxDouble x1, wxDouble y1, + wxDouble x2, wxDouble y2, + const wxGraphicsGradientStops& stops) = 0; - // sets the brush to a radial gradient originating at (xo,yc) with color oColor and ends on a circle around (xc,yc) - // with radius r and color cColor - virtual wxGraphicsBrush CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius, - const wxColour &oColor, const wxColour &cColor) = 0; + virtual wxGraphicsBrush + CreateRadialGradientBrush(wxDouble xo, wxDouble yo, + wxDouble xc, wxDouble yc, + wxDouble radius, + const wxGraphicsGradientStops& stops) = 0; - // sets the font + // sets the font virtual wxGraphicsFont CreateFont( const wxFont &font , const wxColour &col = *wxBLACK ) = 0; + virtual wxGraphicsFont CreateFont(double sizeInPixels, + const wxString& facename, + int flags = wxFONTFLAG_DEFAULT, + const wxColour& col = *wxBLACK) = 0; -#ifndef __WXGTK20__ // create a native bitmap representation virtual wxGraphicsBitmap CreateBitmap( const wxBitmap &bitmap ) = 0; +#if wxUSE_IMAGE + virtual wxGraphicsBitmap CreateBitmapFromImage(const wxImage& image) = 0; + virtual wxImage CreateImageFromBitmap(const wxGraphicsBitmap& bmp) = 0; +#endif // wxUSE_IMAGE + + // create a graphics bitmap from a native bitmap + virtual wxGraphicsBitmap CreateBitmapFromNativeBitmap( void* bitmap ) = 0; // create a subimage from a native image representation virtual wxGraphicsBitmap CreateSubBitmap( const wxGraphicsBitmap &bitmap, wxDouble x, wxDouble y, wxDouble w, wxDouble h ) = 0; -#endif - private: - DECLARE_NO_COPY_CLASS(wxGraphicsRenderer) + wxDECLARE_NO_COPY_CLASS(wxGraphicsRenderer); DECLARE_ABSTRACT_CLASS(wxGraphicsRenderer) }; -#endif + +#if wxUSE_IMAGE +inline +wxImage wxGraphicsBitmap::ConvertToImage() const +{ + wxGraphicsRenderer* renderer = GetRenderer(); + return renderer ? renderer->CreateImageFromBitmap(*this) : wxNullImage; +} +#endif // wxUSE_IMAGE + +#endif // wxUSE_GRAPHICS_CONTEXT #endif // _WX_GRAPHICS_H_