diff --git a/include/wx/graphics.h b/include/wx/graphics.h index e96202c37b..54a0ad58c8 100755 --- a/include/wx/graphics.h +++ b/include/wx/graphics.h @@ -29,6 +29,7 @@ class WXDLLIMPEXP_CORE wxGraphicsRenderer; class WXDLLIMPEXP_CORE wxGraphicsPen; class WXDLLIMPEXP_CORE wxGraphicsBrush; class WXDLLIMPEXP_CORE wxGraphicsFont; +class WXDLLIMPEXP_CORE wxGraphicsBitmap; /* * notes about the graphics context apis @@ -111,6 +112,16 @@ private : extern WXDLLEXPORT_DATA(wxGraphicsFont) wxNullGraphicsFont; +class WXDLLIMPEXP_CORE wxGraphicsBitmap : public wxGraphicsObject +{ +public : + wxGraphicsBitmap() {} + virtual ~wxGraphicsBitmap() {} +private : + DECLARE_DYNAMIC_CLASS(wxGraphicsBitmap) +} ; + +extern WXDLLEXPORT_DATA(wxGraphicsBitmap) wxNullGraphicsBitmap; class WXDLLIMPEXP_CORE wxGraphicsMatrixData : public wxGraphicsObjectRefData { @@ -428,6 +439,12 @@ public: // sets the font virtual wxGraphicsFont CreateFont( const wxFont &font , const wxColour &col = *wxBLACK ) const; + +#if wxABI_VERSION >= 20809 + wxGraphicsBitmap CreateBitmap( const wxBitmap &bitmap ) const; +#endif + + //virtual wxGraphicsBitmap CreateSubBitmap( const wxGraphicsBitmap &bitmap, wxDouble x, wxDouble y, wxDouble w, wxDouble h ) const; // create a 'native' matrix corresponding to these values virtual wxGraphicsMatrix CreateMatrix( wxDouble a=1.0, wxDouble b=0.0, wxDouble c=0.0, wxDouble d=1.0, @@ -527,7 +544,10 @@ public: // // image support // - +#if wxABI_VERSION >= 20809 + void DrawBitmap( const wxGraphicsBitmap &bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h ); +#endif + virtual void DrawBitmap( const wxBitmap &bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h ) = 0; virtual void DrawIcon( const wxIcon &icon, wxDouble x, wxDouble y, wxDouble w, wxDouble h ) = 0; @@ -666,6 +686,7 @@ public : // sets the font virtual wxGraphicsFont CreateFont( const wxFont &font , const wxColour &col = *wxBLACK ) = 0; + wxGraphicsBitmap CreateBitmap( const wxBitmap &bmp ) = 0; private : DECLARE_NO_COPY_CLASS(wxGraphicsRenderer) DECLARE_ABSTRACT_CLASS(wxGraphicsRenderer) diff --git a/src/common/graphcmn.cpp b/src/common/graphcmn.cpp index 7cced0c1ce..0a8859e111 100644 --- a/src/common/graphcmn.cpp +++ b/src/common/graphcmn.cpp @@ -120,10 +120,12 @@ wxObjectRefData* wxGraphicsObject::CloneRefData(const wxObjectRefData* data) con IMPLEMENT_DYNAMIC_CLASS(wxGraphicsPen, wxGraphicsObject) IMPLEMENT_DYNAMIC_CLASS(wxGraphicsBrush, wxGraphicsObject) IMPLEMENT_DYNAMIC_CLASS(wxGraphicsFont, wxGraphicsObject) +IMPLEMENT_DYNAMIC_CLASS(wxGraphicsBitmap, wxGraphicsObject) WXDLLIMPEXP_DATA_CORE(wxGraphicsPen) wxNullGraphicsPen; WXDLLIMPEXP_DATA_CORE(wxGraphicsBrush) wxNullGraphicsBrush; WXDLLIMPEXP_DATA_CORE(wxGraphicsFont) wxNullGraphicsFont; +WXDLLIMPEXP_DATA_CORE(wxGraphicsBitmap) wxNullGraphicsBitmap; //----------------------------------------------------------------------------- // matrix @@ -729,6 +731,11 @@ wxGraphicsFont wxGraphicsContext::CreateFont( const wxFont &font , const wxColou return GetRenderer()->CreateFont(font,col); } +wxGraphicsBitmap wxGraphicsContext::CreateBitmap( const wxBitmap& bmp ) const +{ + return GetRenderer()->CreateBitmap(bmp); +} + wxGraphicsContext* wxGraphicsContext::Create( const wxWindowDC& dc) { return wxGraphicsRenderer::GetDefaultRenderer()->CreateContext(dc); diff --git a/src/generic/graphicc.cpp b/src/generic/graphicc.cpp index 2b2c0671f5..e545fe4781 100644 --- a/src/generic/graphicc.cpp +++ b/src/generic/graphicc.cpp @@ -341,6 +341,7 @@ public: // gets the matrix of this context virtual wxGraphicsMatrix GetTransform() const; + 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(); @@ -1372,6 +1373,8 @@ public : // sets the font virtual wxGraphicsFont CreateFont( const wxFont &font , const wxColour &col = *wxBLACK ) ; + + wxGraphicsBitmap CreateBitmap( const wxBitmap &bitmap ) { return wxGraphicsBitmap(); } private : DECLARE_DYNAMIC_CLASS_NO_COPY(wxCairoRenderer) diff --git a/src/mac/carbon/graphics.cpp b/src/mac/carbon/graphics.cpp index 74b2173952..4446f29eb5 100755 --- a/src/mac/carbon/graphics.cpp +++ b/src/mac/carbon/graphics.cpp @@ -788,6 +788,27 @@ wxMacCoreGraphicsFontData::~wxMacCoreGraphicsFontData() } } +class wxMacCoreGraphicsBitmapData : public wxGraphicsObjectRefData +{ +public: + wxMacCoreGraphicsBitmapData( wxGraphicsRenderer* renderer, const wxBitmap& bmp ); + ~wxMacCoreGraphicsBitmapData(); + + virtual CGImageRef GetBitmap() { return m_bitmap; } +private : + CGImageRef m_bitmap; +}; + +wxMacCoreGraphicsBitmapData::wxMacCoreGraphicsBitmapData( wxGraphicsRenderer* renderer, const wxBitmap& bmp ) : wxGraphicsObjectRefData( renderer ) +{ + m_bitmap = (CGImageRef)( bmp.CGImageCreate() ); +} + +wxMacCoreGraphicsBitmapData::~wxMacCoreGraphicsBitmapData() +{ + CGImageRelease( m_bitmap ); +} + // // Graphics Matrix // @@ -1281,6 +1302,7 @@ public: // // image support // + 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 ); @@ -1689,39 +1711,38 @@ void wxMacCoreGraphicsContext::Rotate( wxDouble angle ) } void wxMacCoreGraphicsContext::DrawBitmap( const wxBitmap &bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h ) +{ + wxGraphicsBitmap bitmap = GetRenderer()->CreateBitmap(bmp); + DrawBitmap(bitmap, x, y, w, h); +} + +void wxMacCoreGraphicsContext::DrawBitmap( const wxGraphicsBitmap &bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h ) { EnsureIsValid(); - CGImageRef image = (CGImageRef)( bmp.CGImageCreate() ); + CGImageRef image = static_cast(bmp.GetRefData())->GetBitmap(); HIRect r = CGRectMake( x , y , w , h ); - if ( bmp.GetDepth() == 1 ) + + // set the brush, which is used when the bitmap's depth == 1 + if ( !m_brush.IsNull() ) { - // is is a mask, the '1' in the mask tell where to draw the current brush - if ( !m_brush.IsNull() ) + if ( ((wxMacCoreGraphicsBrushData*)m_brush.GetRefData())->IsShading() ) { - if ( ((wxMacCoreGraphicsBrushData*)m_brush.GetRefData())->IsShading() ) - { - // TODO clip to mask - /* - CGContextSaveGState( m_cgContext ); - CGContextAddPath( m_cgContext , (CGPathRef) path.GetNativePath() ); - CGContextClip( m_cgContext ); - CGContextDrawShading( m_cgContext, ((wxMacCoreGraphicsBrushData*)m_brush.GetRefData())->GetShading() ); - CGContextRestoreGState( m_cgContext); - */ - } - else - { - ((wxMacCoreGraphicsBrushData*)m_brush.GetRefData())->Apply(this); - HIViewDrawCGImage( m_cgContext , &r , image ); - } + // TODO clip to mask + /* + CGContextSaveGState( m_cgContext ); + CGContextAddPath( m_cgContext , (CGPathRef) path.GetNativePath() ); + CGContextClip( m_cgContext ); + CGContextDrawShading( m_cgContext, ((wxMacCoreGraphicsBrushData*)m_brush.GetRefData())->GetShading() ); + CGContextRestoreGState( m_cgContext); + */ + } + else + { + ((wxMacCoreGraphicsBrushData*)m_brush.GetRefData())->Apply(this); + HIViewDrawCGImage( m_cgContext , &r , image ); } } - else - { - HIViewDrawCGImage( m_cgContext , &r , image ); - } - CGImageRelease( image ); } void wxMacCoreGraphicsContext::DrawIcon( const wxIcon &icon, wxDouble x, wxDouble y, wxDouble w, wxDouble h ) @@ -2131,6 +2152,8 @@ public : // sets the font virtual wxGraphicsFont CreateFont( const wxFont &font , const wxColour &col = *wxBLACK ) ; + + wxGraphicsBitmap CreateBitmap( const wxBitmap &bitmap ) ; private : DECLARE_DYNAMIC_CLASS_NO_COPY(wxMacCoreGraphicsRenderer) @@ -2266,6 +2289,18 @@ wxGraphicsFont wxMacCoreGraphicsRenderer::CreateFont( const wxFont &font , const return wxNullGraphicsFont; } +wxGraphicsBitmap wxMacCoreGraphicsRenderer::CreateBitmap( const wxBitmap& bmp ) +{ + if ( bmp.Ok() ) + { + wxGraphicsBitmap p; + p.SetRefData(new wxMacCoreGraphicsBitmapData( this , bmp )); + return p; + } + else + return wxNullGraphicsBitmap; +} + #endif // wxMAC_USE_CORE_GRAPHICS diff --git a/src/msw/graphics.cpp b/src/msw/graphics.cpp index ff674f05b6..33f39009f0 100644 --- a/src/msw/graphics.cpp +++ b/src/msw/graphics.cpp @@ -258,6 +258,19 @@ private : GraphicsPath* m_brushPath; }; +class WXDLLIMPEXP_CORE wxGDIPlusBitmapData : public wxGraphicsObjectRefData +{ +public: + wxGDIPlusBitmapData( wxGraphicsRenderer* renderer ); + wxGDIPlusBitmapData( wxGraphicsRenderer* renderer, const wxBitmap &bmp ); + ~wxGDIPlusBitmapData (); + + virtual Bitmap* GetGDIPlusBitmap() { return m_bitmap; } + +private : + Bitmap* m_bitmap; +}; + class WXDLLIMPEXP_CORE wxGDIPlusFontData : public wxGraphicsObjectRefData { public: @@ -312,6 +325,7 @@ public: // gets the matrix of this context virtual wxGraphicsMatrix GetTransform() const; + 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(); @@ -612,6 +626,99 @@ void wxGDIPlusBrushData::CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wx b->SetSurroundColors(colors, &count); } +wxGDIPlusBitmapData::wxGDIPlusBitmapData( wxGraphicsRenderer* renderer, + const wxBitmap &bmp) : wxGraphicsObjectRefData( renderer ) +{ + m_bitmap = NULL; + Bitmap* image = NULL; + Bitmap* helper = NULL; + if ( bmp.GetMask() ) + { + Bitmap interim((HBITMAP)bmp.GetHBITMAP(),(HPALETTE)bmp.GetPalette()->GetHPALETTE()) ; + + size_t width = interim.GetWidth(); + size_t height = interim.GetHeight(); + Rect bounds(0,0,width,height); + + image = new Bitmap(width,height,PixelFormat32bppPARGB) ; + + Bitmap interimMask((HBITMAP)bmp.GetMask()->GetMaskBitmap(),NULL); + wxASSERT(interimMask.GetPixelFormat() == PixelFormat1bppIndexed); + + BitmapData dataMask ; + interimMask.LockBits(&bounds,ImageLockModeRead, + interimMask.GetPixelFormat(),&dataMask); + + + BitmapData imageData ; + image->LockBits(&bounds,ImageLockModeWrite, PixelFormat32bppPARGB, &imageData); + + BYTE maskPattern = 0 ; + BYTE maskByte = 0; + size_t maskIndex ; + + for ( size_t y = 0 ; y < height ; ++y) + { + maskIndex = 0 ; + for( size_t x = 0 ; x < width; ++x) + { + if ( x % 8 == 0) + { + maskPattern = 0x80; + maskByte = *((BYTE*)dataMask.Scan0 + dataMask.Stride*y + maskIndex); + maskIndex++; + } + else + maskPattern = maskPattern >> 1; + + ARGB *dest = (ARGB*)((BYTE*)imageData.Scan0 + imageData.Stride*y + x*4); + if ( (maskByte & maskPattern) == 0 ) + *dest = 0x00000000; + else + { + Color c ; + interim.GetPixel(x,y,&c) ; + *dest = (c.GetValue() | Color::AlphaMask); + } + } + } + + image->UnlockBits(&imageData); + + interimMask.UnlockBits(&dataMask); + interim.UnlockBits(&dataMask); + } + else + { + image = Bitmap::FromHBITMAP((HBITMAP)bmp.GetHBITMAP(),(HPALETTE)bmp.GetPalette()->GetHPALETTE()); + if ( bmp.HasAlpha() && GetPixelFormatSize(image->GetPixelFormat()) == 32 ) + { + size_t width = image->GetWidth(); + size_t height = image->GetHeight(); + Rect bounds(0,0,width,height); + BitmapData data ; + + helper = image ; + image = NULL ; + helper->LockBits(&bounds, ImageLockModeRead, + helper->GetPixelFormat(),&data); + + image = new Bitmap(data.Width, data.Height, data.Stride, + PixelFormat32bppPARGB , (BYTE*) data.Scan0); + + helper->UnlockBits(&data); + } + } + if ( image ) + m_bitmap = image; + delete helper; +} + +wxGDIPlusBitmapData::~wxGDIPlusBitmapData() +{ + delete m_bitmap; +} + //----------------------------------------------------------------------------- // wxGDIPlusFont implementation //----------------------------------------------------------------------------- @@ -1064,91 +1171,17 @@ void wxGDIPlusContext::PopState() // premultiplied format, therefore in the failing cases we create a new bitmap using the non-premultiplied // bytes as parameter -void wxGDIPlusContext::DrawBitmap( const wxBitmap &bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h ) +void wxGDIPlusContext::DrawBitmap( const wxGraphicsBitmap &bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h ) { - Bitmap* image = NULL; - Bitmap* helper = NULL; - if ( bmp.GetMask() ) - { - Bitmap interim((HBITMAP)bmp.GetHBITMAP(),(HPALETTE)bmp.GetPalette()->GetHPALETTE()) ; - - size_t width = interim.GetWidth(); - size_t height = interim.GetHeight(); - Rect bounds(0,0,width,height); - - image = new Bitmap(width,height,PixelFormat32bppPARGB) ; - - Bitmap interimMask((HBITMAP)bmp.GetMask()->GetMaskBitmap(),NULL); - wxASSERT(interimMask.GetPixelFormat() == PixelFormat1bppIndexed); - - BitmapData dataMask ; - interimMask.LockBits(&bounds,ImageLockModeRead, - interimMask.GetPixelFormat(),&dataMask); - - - BitmapData imageData ; - image->LockBits(&bounds,ImageLockModeWrite, PixelFormat32bppPARGB, &imageData); - - BYTE maskPattern = 0 ; - BYTE maskByte = 0; - size_t maskIndex ; - - for ( size_t y = 0 ; y < height ; ++y) - { - maskIndex = 0 ; - for( size_t x = 0 ; x < width; ++x) - { - if ( x % 8 == 0) - { - maskPattern = 0x80; - maskByte = *((BYTE*)dataMask.Scan0 + dataMask.Stride*y + maskIndex); - maskIndex++; - } - else - maskPattern = maskPattern >> 1; - - ARGB *dest = (ARGB*)((BYTE*)imageData.Scan0 + imageData.Stride*y + x*4); - if ( (maskByte & maskPattern) == 0 ) - *dest = 0x00000000; - else - { - Color c ; - interim.GetPixel(x,y,&c) ; - *dest = (c.GetValue() | Color::AlphaMask); - } - } - } - - image->UnlockBits(&imageData); - - interimMask.UnlockBits(&dataMask); - interim.UnlockBits(&dataMask); - } - else - { - image = Bitmap::FromHBITMAP((HBITMAP)bmp.GetHBITMAP(),(HPALETTE)bmp.GetPalette()->GetHPALETTE()); - if ( bmp.HasAlpha() && GetPixelFormatSize(image->GetPixelFormat()) == 32 ) - { - size_t width = image->GetWidth(); - size_t height = image->GetHeight(); - Rect bounds(0,0,width,height); - BitmapData data ; - - helper = image ; - image = NULL ; - helper->LockBits(&bounds, ImageLockModeRead, - helper->GetPixelFormat(),&data); - - image = new Bitmap(data.Width, data.Height, data.Stride, - PixelFormat32bppPARGB , (BYTE*) data.Scan0); - - helper->UnlockBits(&data); - } - } + Bitmap* image = static_cast(bmp.GetRefData())->GetGDIPlusBitmap(); if ( image ) m_context->DrawImage(image,(REAL) x,(REAL) y,(REAL) w,(REAL) h) ; - delete image ; - delete helper ; +} + +void wxGDIPlusContext::DrawBitmap( const wxBitmap &bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h ) +{ + wxGraphicsBitmap bitmap = GetRenderer()->CreateBitmap(bmp); + DrawBitmap(bitmap, x, y, w, h); } void wxGDIPlusContext::DrawIcon( const wxIcon &icon, wxDouble x, wxDouble y, wxDouble w, wxDouble h ) @@ -1402,6 +1435,8 @@ public : // sets the font virtual wxGraphicsFont CreateFont( const wxFont &font , const wxColour &col = *wxBLACK ) ; + + wxGraphicsBitmap CreateBitmap( const wxBitmap &bmp ) ; protected : void EnsureIsLoaded(); void Load(); @@ -1576,4 +1611,16 @@ wxGraphicsFont wxGDIPlusRenderer::CreateFont( const wxFont &font , const wxColou return wxNullGraphicsFont; } +wxGraphicsBitmap wxGDIPlusRenderer::CreateBitmap( const wxBitmap& bmp ) +{ + if ( bmp.Ok() ) + { + wxGraphicsBitmap p; + p.SetRefData(new wxGDIPlusBitmapData( this , bmp )); + return p; + } + else + return wxNullGraphicsBitmap; +} + #endif // wxUSE_GRAPHICS_CONTEXT