X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/bf02a7f9761ce9c0a1279ae958a0e5d53f603e15..f124a4c5379a13a396cb6ee4356d8be9b266bd1b:/src/generic/graphicc.cpp diff --git a/src/generic/graphicc.cpp b/src/generic/graphicc.cpp index 12f147147d..a47a9362ac 100644 --- a/src/generic/graphicc.cpp +++ b/src/generic/graphicc.cpp @@ -17,11 +17,15 @@ #if wxUSE_GRAPHICS_CONTEXT +#include "wx/graphics.h" + +#if wxUSE_CAIRO + +#include "wx/cairo.h" + #ifndef WX_PRECOMP #include "wx/bitmap.h" #include "wx/icon.h" - - #include "wx/dc.h" #include "wx/dcclient.h" #include "wx/dcmemory.h" #include "wx/dcprint.h" @@ -29,37 +33,10 @@ #include "wx/private/graphics.h" #include "wx/rawbmp.h" +#include "wx/vector.h" using namespace std; -//----------------------------------------------------------------------------- -// constants -//----------------------------------------------------------------------------- - -const double RAD2DEG = 180.0 / M_PI; - -//----------------------------------------------------------------------------- -// Local functions -//----------------------------------------------------------------------------- - -static inline double dmin(double a, double b) -{ - return a < b ? a : b; -} -static inline double dmax(double a, double b) -{ - return a > b ? a : b; -} - -static inline double DegToRad(double deg) -{ - return (deg * M_PI) / 180.0; -} -static inline double RadToDeg(double deg) -{ - return (deg * 180.0) / M_PI; -} - //----------------------------------------------------------------------------- // device context implementation // @@ -87,6 +64,10 @@ static inline double RadToDeg(double deg) #endif #include +#ifdef __WXMSW__ +#include +#endif + #ifdef __WXGTK__ #include #include "wx/fontutil.h" @@ -255,6 +236,8 @@ private : double *m_userLengths; wxPen m_pen; + + wxDECLARE_NO_COPY_CLASS(wxCairoPenData); }; class WXDLLIMPEXP_CORE wxCairoBrushData : public wxGraphicsObjectRefData @@ -309,6 +292,27 @@ private : cairo_font_slant_t m_slant; cairo_font_weight_t m_weight; #endif +#ifdef __WXMSW__ + wxCairoContext( wxGraphicsRenderer* renderer, HDC context ); +#endif +}; + +class wxCairoBitmapData : public wxGraphicsObjectRefData +{ +public: + wxCairoBitmapData( wxGraphicsRenderer* renderer, const wxBitmap& bmp ); + wxCairoBitmapData( wxGraphicsRenderer* renderer, cairo_surface_t* bitmap ); + ~wxCairoBitmapData(); + + virtual cairo_surface_t* GetCairoSurface() { return m_surface; } + virtual cairo_pattern_t* GetCairoPattern() { return m_pattern; } + virtual wxSize GetSize() { return wxSize(m_width, m_height); } +private : + cairo_surface_t* m_surface; + cairo_pattern_t* m_pattern; + int m_width; + int m_height; + unsigned char* m_buffer; }; class WXDLLIMPEXP_CORE wxCairoContext : public wxGraphicsContext @@ -338,6 +342,9 @@ public: } virtual void Clip( const wxRegion ®ion ); +#ifdef __WXMSW__ + cairo_surface_t* m_mswSurface; +#endif // clips drawings to the rect virtual void Clip( wxDouble x, wxDouble y, wxDouble w, wxDouble h ); @@ -354,7 +361,7 @@ public: virtual void BeginLayer(wxDouble opacity); virtual void EndLayer(); - + virtual void StrokePath( const wxGraphicsPath& p ); virtual void FillPath( const wxGraphicsPath& p , wxPolygonFillMode fillStyle = wxWINDING_RULE ); @@ -371,6 +378,7 @@ public: // gets the matrix of this context virtual wxGraphicsMatrix GetTransform() const; + virtual void DrawBitmap( const wxGraphicsBitmap &bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h ); virtual void DrawBitmap( const wxBitmap &bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h ); virtual void DrawIcon( const wxIcon &icon, wxDouble x, wxDouble y, wxDouble w, wxDouble h ); virtual void PushState(); @@ -380,13 +388,14 @@ public: wxDouble *descent, wxDouble *externalLeading ) const; virtual void GetPartialTextExtents(const wxString& text, wxArrayDouble& widths) const; +protected: + virtual void DoDrawText( const wxString &str, wxDouble x, wxDouble y ); + private: void Init(cairo_t *context); - virtual void DoDrawText( const wxString &str, wxDouble x, wxDouble y ); - cairo_t* m_context; - + wxVector m_layerOpacities; wxDECLARE_NO_COPY_CLASS(wxCairoContext); @@ -716,7 +725,7 @@ wxCairoFontData::wxCairoFontData( wxGraphicsRenderer* renderer, const wxFont &fo m_underlined = font.GetUnderlined(); #ifdef __WXMAC__ - m_font = cairo_atsui_font_face_create_for_atsu_font_id( font.MacGetATSUFontID() ); + m_font = cairo_quartz_font_face_create_for_cgfont( font.OSXGetCGFont() ); #elif defined(__WXGTK__) m_font = pango_font_description_copy( font.GetNativeFontInfo()->description ); #else @@ -1017,6 +1026,102 @@ void * wxCairoMatrixData::GetNativeMatrix() const return (void*) &m_matrix; } +// wxCairoBitmap implementation +//----------------------------------------------------------------------------- + +wxCairoBitmapData::wxCairoBitmapData( wxGraphicsRenderer* renderer, cairo_surface_t* bitmap ) : + wxGraphicsObjectRefData( renderer ) +{ + m_surface = bitmap; + m_pattern = cairo_pattern_create_for_surface(m_surface); +} + +wxCairoBitmapData::wxCairoBitmapData( wxGraphicsRenderer* renderer, const wxBitmap& bmp ) : wxGraphicsObjectRefData( renderer ) +{ + wxCHECK_RET( bmp.IsOk(), wxT("Invalid bitmap in wxCairoContext::DrawBitmap")); + + int bw = m_width = bmp.GetWidth(); + int bh = m_height = bmp.GetHeight(); + wxBitmap bmpSource = bmp; // we need a non-const instance + m_buffer = new unsigned char[bw*bh*4]; + wxUint32* data = (wxUint32*)m_buffer; + + // Create a surface object and copy the bitmap pixel data to it. if the + // image has alpha (or a mask represented as alpha) then we'll use a + // different format and iterator than if it doesn't... + if (bmpSource.HasAlpha() || bmpSource.GetMask()) + { + m_surface = cairo_image_surface_create_for_data( + m_buffer, CAIRO_FORMAT_ARGB32, bw, bh, bw*4); + wxAlphaPixelData pixData(bmpSource, wxPoint(0,0), wxSize(bw, bh)); + wxCHECK_RET( pixData, wxT("Failed to gain raw access to bitmap data.")); + + wxAlphaPixelData::Iterator p(pixData); + for (int y=0; yGetHandle()); + m_context = cairo_create(m_mswSurface); +#endif PopState(); cairo_destroy(m_context); } +#ifdef __WXMSW__ + if ( m_mswSurface ) + cairo_surface_destroy(m_mswSurface); +#endif } void wxCairoContext::Init(cairo_t *context) @@ -1297,99 +1422,34 @@ void wxCairoContext::PopState() void wxCairoContext::DrawBitmap( const wxBitmap &bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h ) { - wxCHECK_RET( bmp.IsOk(), wxT("Invalid bitmap in wxCairoContext::DrawBitmap")); - - cairo_surface_t* surface; - int bw = bmp.GetWidth(); - int bh = bmp.GetHeight(); - wxBitmap bmpSource = bmp; // we need a non-const instance - unsigned char* buffer = new unsigned char[bw*bh*4]; - wxUint32* data = (wxUint32*)buffer; - - // Create a surface object and copy the bitmap pixel data to it. if the - // image has alpha (or a mask represented as alpha) then we'll use a - // different format and iterator than if it doesn't... - if (bmpSource.HasAlpha() || bmpSource.GetMask()) - { - surface = cairo_image_surface_create_for_data( - buffer, CAIRO_FORMAT_ARGB32, bw, bh, bw*4); - wxAlphaPixelData pixData(bmpSource, wxPoint(0,0), wxSize(bw, bh)); - wxCHECK_RET( pixData, wxT("Failed to gain raw access to bitmap data.")); - - wxAlphaPixelData::Iterator p(pixData); - for (int y=0; yCreateBitmap(bmp); + DrawBitmap(bitmap, x, y, w, h); +} +void wxCairoContext::DrawBitmap(const wxGraphicsBitmap &bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h ) +{ PushState(); // In case we're scaling the image by using a width and height different // than the bitmap's size create a pattern transformation on the surface and // draw the transformed pattern. - cairo_pattern_t* pattern = cairo_pattern_create_for_surface(surface); - wxDouble scaleX = w / bw; - wxDouble scaleY = h / bh; + wxCairoBitmapData* data = static_cast(bmp.GetRefData()); + cairo_pattern_t* pattern = data->GetCairoPattern(); + wxSize size = data->GetSize(); + + wxDouble scaleX = w / size.GetWidth(); + wxDouble scaleY = h / size.GetHeight(); cairo_scale(m_context, scaleX, scaleY); // prepare to draw the image cairo_translate(m_context, x, y); cairo_set_source(m_context, pattern); // use the original size here since the context is scaled already... - cairo_rectangle(m_context, 0, 0, bw, bh); + cairo_rectangle(m_context, 0, 0, size.GetWidth(), size.GetHeight()); // fill the rectangle using the pattern cairo_fill(m_context); - // clean up - cairo_pattern_destroy(pattern); - cairo_surface_destroy(surface); - delete [] buffer; PopState(); } @@ -1423,8 +1483,8 @@ void wxCairoContext::DoDrawText(const wxString& str, wxDouble x, wxDouble y) wxCairoFontData* font_data = (wxCairoFontData*) m_font.GetRefData(); pango_layout_set_font_description( layout, font_data->GetFont()); pango_layout_set_text(layout, data, datalen); - - if (font_data->GetUnderlined()) + + if (font_data->GetUnderlined()) { PangoAttrList *attrs = pango_attr_list_new(); PangoAttribute *attr = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE); @@ -1550,7 +1610,7 @@ bool wxCairoContext::SetAntialiasMode(wxAntialiasMode antialias) return true; m_antialias = antialias; - + cairo_antialias_t antialiasMode; switch (antialias) { @@ -1571,12 +1631,12 @@ bool wxCairoContext::SetCompositionMode(wxCompositionMode op) { if ( m_composition == op ) return true; - + m_composition = op; cairo_operator_t cop; switch (op) { - case wxCOMPOSITION__CLEAR: + case wxCOMPOSITION_CLEAR: cop = CAIRO_OPERATOR_CLEAR; break; case wxCOMPOSITION_SOURCE: @@ -1635,7 +1695,7 @@ void wxCairoContext::EndLayer() cairo_pop_group_to_source(m_context); cairo_paint_with_alpha(m_context,opacity); } - + //----------------------------------------------------------------------------- // wxCairoRenderer declaration //----------------------------------------------------------------------------- @@ -1688,18 +1748,13 @@ public : virtual wxGraphicsFont CreateFont( const wxFont &font , const wxColour &col = *wxBLACK ) ; // create a native bitmap representation -#if 0 - virtual wxGraphicsBitmap CreateBitmap( const wxBitmap &bitmap ) - { - return wxGraphicsBitmap; - } + virtual wxGraphicsBitmap CreateBitmap( const wxBitmap &bitmap ); + + // create a graphics bitmap from a native bitmap + virtual wxGraphicsBitmap CreateBitmapFromNativeBitmap( void* bitmap ); // create a subimage from a native image representation - virtual wxGraphicsBitmap CreateSubBitmap( const wxGraphicsBitmap &bitmap, wxDouble x, wxDouble y, wxDouble w, wxDouble h ) - { - return wxGraphicsBitmap; - } -#endif + virtual wxGraphicsBitmap CreateSubBitmap( const wxGraphicsBitmap &bitmap, wxDouble x, wxDouble y, wxDouble w, wxDouble h ); private : DECLARE_DYNAMIC_CLASS_NO_COPY(wxCairoRenderer) @@ -1747,7 +1802,12 @@ wxGraphicsContext * wxCairoRenderer::CreateContext( const wxPrinterDC& dc) wxGraphicsContext * wxCairoRenderer::CreateContextFromNativeContext( void * context ) { +#ifdef __WXMSW__ + return new wxCairoContext(this,(HDC)context); +#endif +#ifdef __WXGTK__ return new wxCairoContext(this,(cairo_t*)context); +#endif } @@ -1762,6 +1822,9 @@ wxGraphicsContext * wxCairoRenderer::CreateContextFromNativeWindow( void * windo wxGraphicsContext * wxCairoRenderer::CreateMeasuringContext() { +#ifdef __WXGTK__ + return CreateContextFromNativeWindow(gdk_get_default_root_window()); +#endif return NULL; // TODO } @@ -1796,7 +1859,7 @@ wxGraphicsMatrix wxCairoRenderer::CreateMatrix( wxDouble a, wxDouble b, wxDouble wxGraphicsPen wxCairoRenderer::CreatePen(const wxPen& pen) { - if ( !pen.Ok() || pen.GetStyle() == wxTRANSPARENT ) + if ( !pen.Ok() || pen.GetStyle() == wxPENSTYLE_TRANSPARENT ) return wxNullGraphicsPen; else { @@ -1808,7 +1871,7 @@ wxGraphicsPen wxCairoRenderer::CreatePen(const wxPen& pen) wxGraphicsBrush wxCairoRenderer::CreateBrush(const wxBrush& brush ) { - if ( !brush.Ok() || brush.GetStyle() == wxTRANSPARENT ) + if ( !brush.Ok() || brush.GetStyle() == wxBRUSHSTYLE_TRANSPARENT ) return wxNullGraphicsBrush; else { @@ -1854,4 +1917,50 @@ wxGraphicsFont wxCairoRenderer::CreateFont( const wxFont &font , const wxColour return wxNullGraphicsFont; } -#endif // wxUSE_GRAPHICS_CONTEXT +wxGraphicsBitmap wxCairoRenderer::CreateBitmap( const wxBitmap& bmp ) +{ + if ( bmp.Ok() ) + { + wxGraphicsBitmap p; + p.SetRefData(new wxCairoBitmapData( this , bmp )); + return p; + } + else + return wxNullGraphicsBitmap; +} + +wxGraphicsBitmap wxCairoRenderer::CreateBitmapFromNativeBitmap( void* bitmap ) +{ + if ( bitmap != NULL ) + { + wxGraphicsBitmap p; + p.SetRefData(new wxCairoBitmapData( this , (cairo_surface_t*) bitmap )); + return p; + } + else + return wxNullGraphicsBitmap; +} + +wxGraphicsBitmap +wxCairoRenderer::CreateSubBitmap(const wxGraphicsBitmap& WXUNUSED(bitmap), + wxDouble WXUNUSED(x), + wxDouble WXUNUSED(y), + wxDouble WXUNUSED(w), + wxDouble WXUNUSED(h)) +{ + wxFAIL_MSG("wxCairoRenderer::CreateSubBitmap is not implemented."); + return wxNullGraphicsBitmap; +} + +#endif // wxUSE_CAIRO + +wxGraphicsRenderer* wxGraphicsRenderer::GetCairoRenderer() +{ +#if wxUSE_CAIRO + return &gs_cairoGraphicsRenderer; +#else + return NULL; +#endif +} + +#endif // wxUSE_GRAPHICS_CONTEXT