X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/5e8d27fea5f809460cce496107d7fcb7642ab6ab..1508fcaccd04f4bec57790536201c80703d3c8f1:/src/generic/graphicc.cpp diff --git a/src/generic/graphicc.cpp b/src/generic/graphicc.cpp index ebc8e253d0..d2a9ab089f 100644 --- a/src/generic/graphicc.cpp +++ b/src/generic/graphicc.cpp @@ -286,6 +286,23 @@ private : #endif }; +class wxCairoBitmapData : public wxGraphicsObjectRefData +{ +public: + wxCairoBitmapData( wxGraphicsRenderer* renderer, const wxBitmap& bmp ); + ~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 { public: @@ -329,7 +346,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 ); @@ -346,6 +363,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(); @@ -362,7 +380,7 @@ private: void Init(cairo_t *context); cairo_t* m_context; - + wxVector m_layerOpacities; wxDECLARE_NO_COPY_CLASS(wxCairoContext); @@ -993,6 +1011,95 @@ void * wxCairoMatrixData::GetNativeMatrix() const return (void*) &m_matrix; } +// wxCairoBitmap implementation +//----------------------------------------------------------------------------- + +wxCairoBitmapData::wxCairoBitmapData( wxGraphicsRenderer* renderer, const wxBitmap& bmp ) : wxGraphicsObjectRefData( renderer ) +{ + wxCHECK_RET( bmp.IsOk(), wxT("Invalid bitmap in wxCairoContext::DrawBitmap")); + + int bw = bmp.GetWidth(); + int bh = 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; 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(); } @@ -1399,8 +1441,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); @@ -1526,7 +1568,7 @@ bool wxCairoContext::SetAntialiasMode(wxAntialiasMode antialias) return true; m_antialias = antialias; - + cairo_antialias_t antialiasMode; switch (antialias) { @@ -1547,7 +1589,7 @@ bool wxCairoContext::SetCompositionMode(wxCompositionMode op) { if ( m_composition == op ) return true; - + m_composition = op; cairo_operator_t cop; switch (op) @@ -1611,7 +1653,7 @@ void wxCairoContext::EndLayer() cairo_pop_group_to_source(m_context); cairo_paint_with_alpha(m_context,opacity); } - + //----------------------------------------------------------------------------- // wxCairoRenderer declaration //----------------------------------------------------------------------------- @@ -1664,18 +1706,10 @@ 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 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) @@ -1833,4 +1867,27 @@ wxGraphicsFont wxCairoRenderer::CreateFont( const wxFont &font , const wxColour return wxNullGraphicsFont; } +wxGraphicsBitmap wxCairoRenderer::CreateBitmap( const wxBitmap& bmp ) +{ + if ( bmp.Ok() ) + { + wxGraphicsBitmap p; + p.SetRefData(new wxCairoBitmapData( this , bmp )); + 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_GRAPHICS_CONTEXT