X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/aa6208d975c3757d75d780c661b4d7918236f4fb..9c20523110b6601abd001eb6316c563ff1b53af0:/src/generic/graphicc.cpp diff --git a/src/generic/graphicc.cpp b/src/generic/graphicc.cpp index e2e63d632f..50965a5b99 100644 --- a/src/generic/graphicc.cpp +++ b/src/generic/graphicc.cpp @@ -286,6 +286,24 @@ private : #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 { public: @@ -329,7 +347,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 +364,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 +381,7 @@ private: void Init(cairo_t *context); cairo_t* m_context; - + wxVector m_layerOpacities; wxDECLARE_NO_COPY_CLASS(wxCairoContext); @@ -993,6 +1012,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 = 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 +1449,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 +1576,7 @@ bool wxCairoContext::SetAntialiasMode(wxAntialiasMode antialias) return true; m_antialias = antialias; - + cairo_antialias_t antialiasMode; switch (antialias) { @@ -1547,7 +1597,7 @@ bool wxCairoContext::SetCompositionMode(wxCompositionMode op) { if ( m_composition == op ) return true; - + m_composition = op; cairo_operator_t cop; switch (op) @@ -1611,7 +1661,7 @@ void wxCairoContext::EndLayer() cairo_pop_group_to_source(m_context); cairo_paint_with_alpha(m_context,opacity); } - + //----------------------------------------------------------------------------- // wxCairoRenderer declaration //----------------------------------------------------------------------------- @@ -1664,18 +1714,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) @@ -1738,6 +1783,9 @@ wxGraphicsContext * wxCairoRenderer::CreateContextFromNativeWindow( void * windo wxGraphicsContext * wxCairoRenderer::CreateMeasuringContext() { +#ifdef __WXGTK__ + return CreateContextFromNativeWindow(gdk_get_default_root_window()); +#endif return NULL; // TODO } @@ -1830,4 +1878,39 @@ 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::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_GRAPHICS_CONTEXT