From d6afb66388d8bb3f9ff6f4428c1ef7021045a9d4 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Thu, 24 Mar 2016 21:12:40 +0100 Subject: [PATCH] Implemented wxCairoRenderer::CreateSubBitmap method. --- interface/wx/graphics.h | 3 --- src/common/cairo.cpp | 4 ++++ src/generic/graphicc.cpp | 42 ++++++++++++++++++++++++++++++++-------- 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/interface/wx/graphics.h b/interface/wx/graphics.h index 79902b28fc..d23a309b24 100644 --- a/interface/wx/graphics.h +++ b/interface/wx/graphics.h @@ -446,9 +446,6 @@ public: /** Extracts a sub-bitmap from an existing bitmap. - - Currently this function is implemented in the native MSW and OS X - versions but not when using Cairo. */ virtual wxGraphicsBitmap CreateSubBitmap(const wxGraphicsBitmap& bitmap, wxDouble x, wxDouble y, diff --git a/src/common/cairo.cpp b/src/common/cairo.cpp index 7d4984efb2..fc8c7b7d14 100644 --- a/src/common/cairo.cpp +++ b/src/common/cairo.cpp @@ -168,6 +168,8 @@ (cairo_t *cr, double tx, double ty), (cr, tx, ty) ) \ m( cairo_surface_flush, \ (cairo_surface_t *surface), (surface) ) \ + m( cairo_set_source_surface, \ + (cairo_t *cr, cairo_surface_t *surface, double x, double y), (cr, surface, x, y) ) \ #ifdef __WXMAC__ #define wxCAIRO_PLATFORM_METHODS(m) \ @@ -230,6 +232,8 @@ (cairo_surface_t *surface), (surface), -1) \ m( const char *, cairo_version_string, \ (), () , NULL ) \ + m( cairo_surface_t*, cairo_surface_create_similar_image, \ + (cairo_surface_t *other, cairo_format_t format, int width, int height), (other, format, width, height), NULL) \ wxCAIRO_PLATFORM_METHODS(m) #define wxCAIRO_DECLARE_TYPE(rettype, name, args, argnames, defret) \ diff --git a/src/generic/graphicc.cpp b/src/generic/graphicc.cpp index b486d4f75f..2635ae1196 100644 --- a/src/generic/graphicc.cpp +++ b/src/generic/graphicc.cpp @@ -2787,15 +2787,41 @@ wxGraphicsBitmap wxCairoRenderer::CreateBitmapFromNativeBitmap( void* bitmap ) } wxGraphicsBitmap -wxCairoRenderer::CreateSubBitmap(const wxGraphicsBitmap& WXUNUSED(bitmap), - wxDouble WXUNUSED(x), - wxDouble WXUNUSED(y), - wxDouble WXUNUSED(w), - wxDouble WXUNUSED(h)) +wxCairoRenderer::CreateSubBitmap(const wxGraphicsBitmap& bitmap, + wxDouble x, wxDouble y, + wxDouble w, wxDouble h) { - wxGraphicsBitmap p; - wxFAIL_MSG("wxCairoRenderer::CreateSubBitmap is not implemented."); - return p; + ENSURE_LOADED_OR_RETURN(wxNullGraphicsBitmap); + + wxCHECK_MSG(!bitmap.IsNull(), wxNullGraphicsBitmap, wxS("Invalid bitmap")); + + wxCairoBitmapData* dataSrc = static_cast(bitmap.GetRefData()); + cairo_surface_t* srcSurface = dataSrc->GetCairoSurface(); + int srcWidth = cairo_image_surface_get_width(srcSurface); + int srcHeight = cairo_image_surface_get_height(srcSurface); + + int dstWidth = wxRound(w); + int dstHeight = wxRound(h); + + wxCHECK_MSG( x >= 0.0 && y >= 0.0 && dstWidth > 0 && dstHeight > 0 && + x + dstWidth <= srcWidth && y + dstHeight <= srcHeight, + wxNullGraphicsBitmap, wxS("Invalid bitmap region")); + + cairo_surface_t* dstSurface = cairo_surface_create_similar_image(srcSurface, + cairo_image_surface_get_format(srcSurface), + dstWidth, dstHeight); + + cairo_t* cr = cairo_create(dstSurface); + cairo_set_source_surface(cr, srcSurface, -x, -y); + + cairo_rectangle(cr, 0.0, 0.0, dstWidth, dstHeight); + cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); + cairo_fill(cr); + cairo_destroy(cr); + + wxGraphicsBitmap bmpRes; + bmpRes.SetRefData(new wxCairoBitmapData(this, dstSurface)); + return bmpRes; } wxString wxCairoRenderer::GetName() const