X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/f1c40652a0c2d6752c57df1b8aed22fae7e118dd..890defb4f3a0012a296c69949bf5f93075743e8f:/src/generic/graphicc.cpp?ds=sidebyside diff --git a/src/generic/graphicc.cpp b/src/generic/graphicc.cpp index 3a1c5bc01b..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<float> m_layerOpacities; wxDECLARE_NO_COPY_CLASS(wxCairoContext); @@ -692,7 +710,7 @@ wxCairoFontData::wxCairoFontData( wxGraphicsRenderer* renderer, const wxFont &fo m_underlined = font.GetUnderlined(); #ifdef __WXMAC__ - m_font = cairo_quartz_font_face_create_for_cgfont( font.GetCGFont() ); + m_font = cairo_quartz_font_face_create_for_cgfont( font.OSXGetCGFont() ); #elif defined(__WXGTK__) m_font = pango_font_description_copy( font.GetNativeFontInfo()->description ); #else @@ -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; y<bh; y++) + { + wxAlphaPixelData::Iterator rowStart = p; + for (int x=0; x<bw; x++) + { + // Each pixel in CAIRO_FORMAT_ARGB32 is a 32-bit quantity, + // with alpha in the upper 8 bits, then red, then green, then + // blue. The 32-bit quantities are stored native-endian. + // Pre-multiplied alpha is used. + unsigned char alpha = p.Alpha(); + if (alpha == 0) + *data = 0; + else + *data = ( alpha << 24 + | (p.Red() * alpha/255) << 16 + | (p.Green() * alpha/255) << 8 + | (p.Blue() * alpha/255) ); + ++data; + ++p; + } + p = rowStart; + p.OffsetY(pixData, 1); + } + } + else // no alpha + { + m_surface = cairo_image_surface_create_for_data( + m_buffer, CAIRO_FORMAT_RGB24, bw, bh, bw*4); + wxNativePixelData pixData(bmpSource, wxPoint(0,0), wxSize(bw, bh)); + wxCHECK_RET( pixData, wxT("Failed to gain raw access to bitmap data.")); + + wxNativePixelData::Iterator p(pixData); + for (int y=0; y<bh; y++) + { + wxNativePixelData::Iterator rowStart = p; + for (int x=0; x<bw; x++) + { + // Each pixel in CAIRO_FORMAT_RGB24 is a 32-bit quantity, with + // the upper 8 bits unused. Red, Green, and Blue are stored in + // the remaining 24 bits in that order. The 32-bit quantities + // are stored native-endian. + *data = ( p.Red() << 16 | p.Green() << 8 | p.Blue() ); + ++data; + ++p; + } + p = rowStart; + p.OffsetY(pixData, 1); + } + } + m_pattern = cairo_pattern_create_for_surface(m_surface); +} + +wxCairoBitmapData::~wxCairoBitmapData() +{ + if (m_pattern) + cairo_pattern_destroy(m_pattern); + + if (m_surface) + cairo_surface_destroy(m_surface); + + delete [] m_buffer; +} + + + //----------------------------------------------------------------------------- // wxCairoContext implementation //----------------------------------------------------------------------------- @@ -1273,99 +1380,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; y<bh; y++) - { - wxAlphaPixelData::Iterator rowStart = p; - for (int x=0; x<bw; x++) - { - // Each pixel in CAIRO_FORMAT_ARGB32 is a 32-bit quantity, - // with alpha in the upper 8 bits, then red, then green, then - // blue. The 32-bit quantities are stored native-endian. - // Pre-multiplied alpha is used. - unsigned char alpha = p.Alpha(); - if (alpha == 0) - *data = 0; - else - *data = ( alpha << 24 - | (p.Red() * alpha/255) << 16 - | (p.Green() * alpha/255) << 8 - | (p.Blue() * alpha/255) ); - ++data; - ++p; - } - p = rowStart; - p.OffsetY(pixData, 1); - } - } - else // no alpha - { - surface = cairo_image_surface_create_for_data( - buffer, CAIRO_FORMAT_RGB24, bw, bh, bw*4); - wxNativePixelData pixData(bmpSource, wxPoint(0,0), wxSize(bw, bh)); - wxCHECK_RET( pixData, wxT("Failed to gain raw access to bitmap data.")); - - wxNativePixelData::Iterator p(pixData); - for (int y=0; y<bh; y++) - { - wxNativePixelData::Iterator rowStart = p; - for (int x=0; x<bw; x++) - { - // Each pixel in CAIRO_FORMAT_RGB24 is a 32-bit quantity, with - // the upper 8 bits unused. Red, Green, and Blue are stored in - // the remaining 24 bits in that order. The 32-bit quantities - // are stored native-endian. - *data = ( p.Red() << 16 | p.Green() << 8 | p.Blue() ); - ++data; - ++p; - } - p = rowStart; - p.OffsetY(pixData, 1); - } - } + wxGraphicsBitmap bitmap = GetRenderer()->CreateBitmap(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<wxCairoBitmapData*>(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) @@ -1738,6 +1772,9 @@ wxGraphicsContext * wxCairoRenderer::CreateContextFromNativeWindow( void * windo wxGraphicsContext * wxCairoRenderer::CreateMeasuringContext() { +#ifdef __WXGTK__ + return CreateContextFromNativeWindow(gdk_get_default_root_window()); +#endif return NULL; // TODO } @@ -1830,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