Allow creating wxGraphicsBitmap and wxGraphicsContext from wxImage.
Provide a way to use wxGraphicsContext to draw on wxImage. This is implemented internally by drawing on wxGraphicsBitmap which can be now also created from wxImage. Add a test of the new functionality to the image sample. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@69358 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -473,6 +473,7 @@ All (GUI):
|
||||
- Added wxPersistentSplitter.
|
||||
- Derive wxAuiNotebook from wxBookCtrlBase (Steven Lamerton).
|
||||
- Fix tooltips in wxSearchCtrl and other composite controls (Catalin Raceanu).
|
||||
- Allow converting to and from wxGraphicsBitmap and wxImage directly.
|
||||
|
||||
OSX:
|
||||
|
||||
|
@@ -434,6 +434,13 @@ public:
|
||||
|
||||
static wxGraphicsContext* Create( wxWindow* window );
|
||||
|
||||
#if wxUSE_IMAGE
|
||||
// Create a context for drawing onto a wxImage. The image life time must be
|
||||
// greater than that of the context itself as when the context is destroyed
|
||||
// it will copy its contents to the specified image.
|
||||
static wxGraphicsContext* Create(wxImage& image);
|
||||
#endif // wxUSE_IMAGE
|
||||
|
||||
// create a context that can be used for measuring texts only, no drawing allowed
|
||||
static wxGraphicsContext * Create();
|
||||
|
||||
@@ -488,6 +495,9 @@ public:
|
||||
|
||||
// create a native bitmap representation
|
||||
virtual wxGraphicsBitmap CreateBitmap( const wxBitmap &bitmap ) const;
|
||||
#if wxUSE_IMAGE
|
||||
wxGraphicsBitmap CreateBitmapFromImage(const wxImage& image) const;
|
||||
#endif // wxUSE_IMAGE
|
||||
|
||||
// create a native bitmap representation
|
||||
virtual wxGraphicsBitmap CreateSubBitmap( const wxGraphicsBitmap &bitmap, wxDouble x, wxDouble y, wxDouble w, wxDouble h ) const;
|
||||
@@ -781,6 +791,10 @@ public:
|
||||
|
||||
virtual wxGraphicsContext * CreateContext( wxWindow* window ) = 0;
|
||||
|
||||
#if wxUSE_IMAGE
|
||||
virtual wxGraphicsContext * CreateContextFromImage(wxImage& image) = 0;
|
||||
#endif // wxUSE_IMAGE
|
||||
|
||||
// create a context that can be used for measuring texts only, no drawing allowed
|
||||
virtual wxGraphicsContext * CreateMeasuringContext() = 0;
|
||||
|
||||
@@ -818,6 +832,9 @@ public:
|
||||
|
||||
// create a native bitmap representation
|
||||
virtual wxGraphicsBitmap CreateBitmap( const wxBitmap &bitmap ) = 0;
|
||||
#if wxUSE_IMAGE
|
||||
virtual wxGraphicsBitmap CreateBitmapFromImage(const wxImage& image) = 0;
|
||||
#endif // wxUSE_IMAGE
|
||||
|
||||
// create a graphics bitmap from a native bitmap
|
||||
virtual wxGraphicsBitmap CreateBitmapFromNativeBitmap( void* bitmap ) = 0;
|
||||
|
@@ -269,11 +269,11 @@ enum wxCompositionMode
|
||||
Represents a bitmap.
|
||||
|
||||
The objects of this class are not created directly but only via
|
||||
wxGraphicsContext or wxGraphicsRenderer CreateBitmap() and
|
||||
CreateSubBitmap() methods. They can subsequently be used with
|
||||
wxGraphicsContext::DrawBitmap(). The only other operation is testing for
|
||||
the bitmap validity which can be performed using IsNull() method inherited
|
||||
from the base class.
|
||||
wxGraphicsContext or wxGraphicsRenderer CreateBitmap(),
|
||||
CreateBitmapFromImage() or CreateSubBitmap() methods. They can subsequently
|
||||
be used with wxGraphicsContext::DrawBitmap(). The only other operation is
|
||||
testing for the bitmap validity which can be performed using IsNull()
|
||||
method inherited from the base class.
|
||||
*/
|
||||
class wxGraphicsBitmap : public wxGraphicsObject
|
||||
{
|
||||
@@ -384,6 +384,19 @@ public:
|
||||
*/
|
||||
static wxGraphicsContext* Create(const wxEnhMetaFileDC& dc);
|
||||
|
||||
/**
|
||||
Creates a wxGraphicsContext associated with a wxImage.
|
||||
|
||||
The image specifies the size of the context as well as whether alpha is
|
||||
supported (if wxImage::HasAlpha()) or not and the initial contents of
|
||||
the context. The @a image object must have a life time greater than
|
||||
that of the new context as the context copies its contents back to the
|
||||
image when it is destroyed.
|
||||
|
||||
@since 2.9.3
|
||||
*/
|
||||
static wxGraphicsContext* Create(wxImage& image);
|
||||
|
||||
/**
|
||||
Clips drawings to the specified region.
|
||||
*/
|
||||
@@ -407,6 +420,18 @@ public:
|
||||
*/
|
||||
virtual wxGraphicsBitmap CreateBitmap( const wxBitmap &bitmap ) = 0;
|
||||
|
||||
/**
|
||||
Creates wxGraphicsBitmap from an existing wxImage.
|
||||
|
||||
This method is more efficient than converting wxImage to wxBitmap first
|
||||
and then calling CreateBitmap() but otherwise has the same effect.
|
||||
|
||||
Returns an invalid wxNullGraphicsBitmap on failure.
|
||||
|
||||
@since 2.9.3
|
||||
*/
|
||||
virtual wxGraphicsBitmap CreateBitmapFromImage(const wxImage& image);
|
||||
|
||||
/**
|
||||
Extracts a sub-bitmap from an existing bitmap.
|
||||
|
||||
@@ -914,6 +939,18 @@ public:
|
||||
*/
|
||||
virtual wxGraphicsBitmap CreateBitmap( const wxBitmap &bitmap ) = 0;
|
||||
|
||||
/**
|
||||
Creates wxGraphicsBitmap from an existing wxImage.
|
||||
|
||||
This method is more efficient than converting wxImage to wxBitmap first
|
||||
and then calling CreateBitmap() but otherwise has the same effect.
|
||||
|
||||
Returns an invalid wxNullGraphicsBitmap on failure.
|
||||
|
||||
@since 2.9.3
|
||||
*/
|
||||
virtual wxGraphicsBitmap CreateBitmapFromImage(const wxImage& image) = 0;
|
||||
|
||||
/**
|
||||
Creates wxGraphicsBitmap from a native bitmap handle.
|
||||
|
||||
@@ -951,6 +988,16 @@ public:
|
||||
*/
|
||||
virtual wxGraphicsContext* CreateContext(const wxEnhMetaFileDC& dc) = 0;
|
||||
|
||||
/**
|
||||
Creates a wxGraphicsContext associated with a wxImage.
|
||||
|
||||
This function is used by wxContext::CreateFromImage() and is not
|
||||
normally called directly.
|
||||
|
||||
@since 2.9.3
|
||||
*/
|
||||
static wxGraphicsContext* CreateContextFromImage(wxImage& image);
|
||||
|
||||
/**
|
||||
Creates a native brush from a wxBrush.
|
||||
*/
|
||||
|
@@ -24,9 +24,11 @@
|
||||
#include "wx/image.h"
|
||||
#include "wx/file.h"
|
||||
#include "wx/filename.h"
|
||||
#include "wx/graphics.h"
|
||||
#include "wx/mstream.h"
|
||||
#include "wx/wfstream.h"
|
||||
#include "wx/quantize.h"
|
||||
#include "wx/scopedptr.h"
|
||||
#include "wx/stopwatch.h"
|
||||
#include "wx/versioninfo.h"
|
||||
|
||||
@@ -83,6 +85,9 @@ public:
|
||||
#ifdef wxHAVE_RAW_BITMAP
|
||||
void OnTestRawBitmap( wxCommandEvent &event );
|
||||
#endif // wxHAVE_RAW_BITMAP
|
||||
#if wxUSE_GRAPHICS_CONTEXT
|
||||
void OnTestGraphics(wxCommandEvent& event);
|
||||
#endif // wxUSE_GRAPHICS_CONTEXT
|
||||
void OnQuit( wxCommandEvent &event );
|
||||
|
||||
#if wxUSE_CLIPBOARD
|
||||
@@ -617,6 +622,7 @@ enum
|
||||
ID_NEW = 100,
|
||||
ID_INFO,
|
||||
ID_SHOWRAW,
|
||||
ID_GRAPHICS,
|
||||
ID_SHOWTHUMBNAIL
|
||||
};
|
||||
|
||||
@@ -630,6 +636,9 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
||||
#ifdef wxHAVE_RAW_BITMAP
|
||||
EVT_MENU (ID_SHOWRAW, MyFrame::OnTestRawBitmap)
|
||||
#endif
|
||||
#if wxUSE_GRAPHICS_CONTEXT
|
||||
EVT_MENU (ID_GRAPHICS, MyFrame::OnTestGraphics)
|
||||
#endif // wxUSE_GRAPHICS_CONTEXT
|
||||
#if wxUSE_CLIPBOARD
|
||||
EVT_MENU(wxID_COPY, MyFrame::OnCopy)
|
||||
EVT_MENU(wxID_PASTE, MyFrame::OnPaste)
|
||||
@@ -651,6 +660,10 @@ MyFrame::MyFrame()
|
||||
menuImage->AppendSeparator();
|
||||
menuImage->Append( ID_SHOWRAW, wxT("Test &raw bitmap...\tCtrl-R"));
|
||||
#endif
|
||||
#if wxUSE_GRAPHICS_CONTEXT
|
||||
menuImage->AppendSeparator();
|
||||
menuImage->Append(ID_GRAPHICS, "Test &graphics context...\tCtrl-G");
|
||||
#endif // wxUSE_GRAPHICS_CONTEXT
|
||||
menuImage->AppendSeparator();
|
||||
menuImage->Append( ID_SHOWTHUMBNAIL, wxT("Test &thumbnail...\tCtrl-T"),
|
||||
"Test scaling the image during load (try with JPEG)");
|
||||
@@ -796,6 +809,84 @@ void MyFrame::OnTestRawBitmap( wxCommandEvent &WXUNUSED(event) )
|
||||
|
||||
#endif // wxHAVE_RAW_BITMAP
|
||||
|
||||
#if wxUSE_GRAPHICS_CONTEXT
|
||||
|
||||
class MyGraphicsFrame : public wxFrame
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
WIDTH = 256,
|
||||
HEIGHT = 90
|
||||
};
|
||||
|
||||
MyGraphicsFrame(wxWindow* parent) :
|
||||
wxFrame(parent, wxID_ANY, "Graphics context test"),
|
||||
m_image(WIDTH, HEIGHT, false)
|
||||
{
|
||||
// Create a test image: it has 3 horizontal primary colour bands with
|
||||
// alpha increasing from left to right.
|
||||
m_image.SetAlpha();
|
||||
unsigned char* alpha = m_image.GetAlpha();
|
||||
unsigned char* data = m_image.GetData();
|
||||
|
||||
for ( int y = 0; y < HEIGHT; y++ )
|
||||
{
|
||||
unsigned char r = 0,
|
||||
g = 0,
|
||||
b = 0;
|
||||
if ( y < HEIGHT/3 )
|
||||
r = 0xff;
|
||||
else if ( y < (2*HEIGHT)/3 )
|
||||
g = 0xff;
|
||||
else
|
||||
b = 0xff;
|
||||
|
||||
for ( int x = 0; x < WIDTH; x++ )
|
||||
{
|
||||
*alpha++ = x;
|
||||
*data++ = r;
|
||||
*data++ = g;
|
||||
*data++ = b;
|
||||
}
|
||||
}
|
||||
|
||||
m_bitmap = wxBitmap(m_image);
|
||||
|
||||
Connect(wxEVT_PAINT, wxPaintEventHandler(MyGraphicsFrame::OnPaint));
|
||||
|
||||
Show();
|
||||
}
|
||||
|
||||
private:
|
||||
void OnPaint(wxPaintEvent& WXUNUSED(event))
|
||||
{
|
||||
wxPaintDC dc(this);
|
||||
wxScopedPtr<wxGraphicsContext> gc(wxGraphicsContext::Create(dc));
|
||||
wxGraphicsBitmap gb(gc->CreateBitmapFromImage(m_image));
|
||||
|
||||
gc->SetFont(*wxNORMAL_FONT, *wxBLACK);
|
||||
|
||||
gc->DrawText("Bitmap", 0, HEIGHT/2);
|
||||
gc->DrawBitmap(m_bitmap, 0, 0, WIDTH, HEIGHT);
|
||||
|
||||
gc->DrawText("Graphics bitmap", 0, (3*HEIGHT)/2);
|
||||
gc->DrawBitmap(gb, 0, HEIGHT, WIDTH, HEIGHT);
|
||||
}
|
||||
|
||||
wxImage m_image;
|
||||
wxBitmap m_bitmap;
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(MyGraphicsFrame);
|
||||
};
|
||||
|
||||
void MyFrame::OnTestGraphics(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
new MyGraphicsFrame(this);
|
||||
}
|
||||
|
||||
#endif // wxUSE_GRAPHICS_CONTEXT
|
||||
|
||||
#if wxUSE_CLIPBOARD
|
||||
|
||||
void MyFrame::OnCopy(wxCommandEvent& WXUNUSED(event))
|
||||
|
@@ -848,6 +848,13 @@ wxGraphicsBitmap wxGraphicsContext::CreateBitmap( const wxBitmap& bmp ) const
|
||||
return GetRenderer()->CreateBitmap(bmp);
|
||||
}
|
||||
|
||||
#if wxUSE_IMAGE
|
||||
wxGraphicsBitmap wxGraphicsContext::CreateBitmapFromImage(const wxImage& image) const
|
||||
{
|
||||
return GetRenderer()->CreateBitmapFromImage(image);
|
||||
}
|
||||
#endif // wxUSE_IMAGE
|
||||
|
||||
wxGraphicsBitmap wxGraphicsContext::CreateSubBitmap( const wxGraphicsBitmap &bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h ) const
|
||||
{
|
||||
return GetRenderer()->CreateSubBitmap(bmp,x,y,w,h);
|
||||
@@ -894,6 +901,13 @@ wxGraphicsContext* wxGraphicsContext::Create( wxWindow* window )
|
||||
return wxGraphicsRenderer::GetDefaultRenderer()->CreateContext(window);
|
||||
}
|
||||
|
||||
#if wxUSE_IMAGE
|
||||
/* static */ wxGraphicsContext* wxGraphicsContext::Create(wxImage& image)
|
||||
{
|
||||
return wxGraphicsRenderer::GetDefaultRenderer()->CreateContextFromImage(image);
|
||||
}
|
||||
#endif // wxUSE_IMAGE
|
||||
|
||||
wxGraphicsContext* wxGraphicsContext::Create()
|
||||
{
|
||||
return wxGraphicsRenderer::GetDefaultRenderer()->CreateMeasuringContext();
|
||||
|
@@ -311,6 +311,9 @@ class wxCairoBitmapData : public wxGraphicsObjectRefData
|
||||
{
|
||||
public:
|
||||
wxCairoBitmapData( wxGraphicsRenderer* renderer, const wxBitmap& bmp );
|
||||
#if wxUSE_IMAGE
|
||||
wxCairoBitmapData(wxGraphicsRenderer* renderer, const wxImage& image);
|
||||
#endif // wxUSE_IMAGE
|
||||
wxCairoBitmapData( wxGraphicsRenderer* renderer, cairo_surface_t* bitmap );
|
||||
~wxCairoBitmapData();
|
||||
|
||||
@@ -427,9 +430,9 @@ public:
|
||||
protected:
|
||||
virtual void DoDrawText( const wxString &str, wxDouble x, wxDouble y );
|
||||
|
||||
private:
|
||||
void Init(cairo_t *context);
|
||||
|
||||
private:
|
||||
cairo_t* m_context;
|
||||
|
||||
wxVector<float> m_layerOpacities;
|
||||
@@ -437,6 +440,35 @@ private:
|
||||
wxDECLARE_NO_COPY_CLASS(wxCairoContext);
|
||||
};
|
||||
|
||||
#if wxUSE_IMAGE
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxCairoImageContext: context associated with a wxImage.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class wxCairoImageContext : public wxCairoContext
|
||||
{
|
||||
public:
|
||||
wxCairoImageContext(wxGraphicsRenderer* renderer, wxImage& image) :
|
||||
wxCairoContext(renderer),
|
||||
m_image(image),
|
||||
m_data(renderer, image)
|
||||
{
|
||||
Init(cairo_create(m_data.GetCairoSurface()));
|
||||
}
|
||||
|
||||
virtual ~wxCairoImageContext()
|
||||
{
|
||||
m_image = m_data.ConvertToImage();
|
||||
}
|
||||
|
||||
private:
|
||||
wxImage& m_image;
|
||||
wxCairoBitmapData m_data;
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(wxCairoImageContext);
|
||||
};
|
||||
#endif // wxUSE_IMAGE
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// wxCairoPenData implementation
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -1283,7 +1315,7 @@ wxCairoBitmapData::wxCairoBitmapData(wxGraphicsRenderer* renderer,
|
||||
? CAIRO_FORMAT_ARGB32
|
||||
: CAIRO_FORMAT_RGB24;
|
||||
|
||||
InitBuffer(image.GetWidth(), image.GetHeight(), bufferFormat);
|
||||
int stride = InitBuffer(image.GetWidth(), image.GetHeight(), bufferFormat);
|
||||
|
||||
// Copy wxImage data into the buffer. Notice that we work with wxUint32
|
||||
// values and not bytes becase Cairo always works with buffers in native
|
||||
@@ -1297,6 +1329,8 @@ wxCairoBitmapData::wxCairoBitmapData(wxGraphicsRenderer* renderer,
|
||||
|
||||
for ( int y = 0; y < m_height; y++ )
|
||||
{
|
||||
wxUint32* const rowStartDst = dst;
|
||||
|
||||
for ( int x = 0; x < m_width; x++ )
|
||||
{
|
||||
const unsigned char a = *alpha++;
|
||||
@@ -1307,12 +1341,16 @@ wxCairoBitmapData::wxCairoBitmapData(wxGraphicsRenderer* renderer,
|
||||
Premultiply(a, src[2]);
|
||||
src += 3;
|
||||
}
|
||||
|
||||
dst = rowStartDst + stride / 4;
|
||||
}
|
||||
}
|
||||
else // RGB
|
||||
{
|
||||
for ( int y = 0; y < m_height; y++ )
|
||||
{
|
||||
wxUint32* const rowStartDst = dst;
|
||||
|
||||
for ( int x = 0; x < m_width; x++ )
|
||||
{
|
||||
*dst++ = src[0] << 16 |
|
||||
@@ -1320,10 +1358,12 @@ wxCairoBitmapData::wxCairoBitmapData(wxGraphicsRenderer* renderer,
|
||||
src[2];
|
||||
src += 3;
|
||||
}
|
||||
|
||||
dst = rowStartDst + stride / 4;
|
||||
}
|
||||
}
|
||||
|
||||
InitSurface(bufferFormat);
|
||||
InitSurface(bufferFormat, stride);
|
||||
}
|
||||
|
||||
wxImage wxCairoBitmapData::ConvertToImage() const
|
||||
@@ -2108,6 +2148,9 @@ public :
|
||||
virtual wxGraphicsContext * CreateContextFromNativeContext( void * context );
|
||||
|
||||
virtual wxGraphicsContext * CreateContextFromNativeWindow( void * window );
|
||||
#if wxUSE_IMAGE
|
||||
virtual wxGraphicsContext * CreateContextFromImage(wxImage& image);
|
||||
#endif // wxUSE_IMAGE
|
||||
|
||||
virtual wxGraphicsContext * CreateContext( wxWindow* window );
|
||||
|
||||
@@ -2147,6 +2190,9 @@ public :
|
||||
|
||||
// create a native bitmap representation
|
||||
virtual wxGraphicsBitmap CreateBitmap( const wxBitmap &bitmap );
|
||||
#if wxUSE_IMAGE
|
||||
virtual wxGraphicsBitmap CreateBitmapFromImage(const wxImage& image);
|
||||
#endif // wxUSE_IMAGE
|
||||
|
||||
// create a graphics bitmap from a native bitmap
|
||||
virtual wxGraphicsBitmap CreateBitmapFromNativeBitmap( void* bitmap );
|
||||
@@ -2257,6 +2303,13 @@ wxGraphicsContext * wxCairoRenderer::CreateContextFromNativeWindow( void * windo
|
||||
#endif
|
||||
}
|
||||
|
||||
#if wxUSE_IMAGE
|
||||
wxGraphicsContext * wxCairoRenderer::CreateContextFromImage(wxImage& image)
|
||||
{
|
||||
return new wxCairoImageContext(this, image);
|
||||
}
|
||||
#endif // wxUSE_IMAGE
|
||||
|
||||
wxGraphicsContext * wxCairoRenderer::CreateMeasuringContext()
|
||||
{
|
||||
ENSURE_LOADED_OR_RETURN(NULL);
|
||||
@@ -2377,6 +2430,24 @@ wxGraphicsBitmap wxCairoRenderer::CreateBitmap( const wxBitmap& bmp )
|
||||
return wxNullGraphicsBitmap;
|
||||
}
|
||||
|
||||
#if wxUSE_IMAGE
|
||||
|
||||
wxGraphicsBitmap wxCairoRenderer::CreateBitmapFromImage(const wxImage& image)
|
||||
{
|
||||
wxGraphicsBitmap bmp;
|
||||
|
||||
ENSURE_LOADED_OR_RETURN(bmp);
|
||||
|
||||
if ( image.IsOk() )
|
||||
{
|
||||
bmp.SetRefData(new wxCairoBitmapData(this, image));
|
||||
}
|
||||
|
||||
return bmp;
|
||||
}
|
||||
|
||||
#endif // wxUSE_IMAGE
|
||||
|
||||
wxGraphicsBitmap wxCairoRenderer::CreateBitmapFromNativeBitmap( void* bitmap )
|
||||
{
|
||||
ENSURE_LOADED_OR_RETURN(wxNullGraphicsBitmap);
|
||||
|
@@ -281,6 +281,10 @@ public:
|
||||
|
||||
virtual Bitmap* GetGDIPlusBitmap() { return m_bitmap; }
|
||||
|
||||
#if wxUSE_IMAGE
|
||||
wxImage ConvertToImage() const;
|
||||
#endif // wxUSE_IMAGE
|
||||
|
||||
private :
|
||||
Bitmap* m_bitmap;
|
||||
Bitmap* m_helper;
|
||||
@@ -404,6 +408,38 @@ private:
|
||||
wxDECLARE_NO_COPY_CLASS(wxGDIPlusContext);
|
||||
};
|
||||
|
||||
#if wxUSE_IMAGE
|
||||
|
||||
class wxGDIPlusImageContext : public wxGDIPlusContext
|
||||
{
|
||||
public:
|
||||
wxGDIPlusImageContext(wxGraphicsRenderer* renderer, wxImage& image) :
|
||||
wxGDIPlusContext(renderer),
|
||||
m_image(image),
|
||||
m_bitmap(renderer, image)
|
||||
{
|
||||
Init
|
||||
(
|
||||
new Graphics(m_bitmap.GetGDIPlusBitmap()),
|
||||
image.GetWidth(),
|
||||
image.GetHeight()
|
||||
);
|
||||
}
|
||||
|
||||
virtual ~wxGDIPlusImageContext()
|
||||
{
|
||||
m_image = m_bitmap.ConvertToImage();
|
||||
}
|
||||
|
||||
private:
|
||||
wxImage& m_image;
|
||||
wxGDIPlusBitmapData m_bitmap;
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(wxGDIPlusImageContext);
|
||||
};
|
||||
|
||||
#endif // wxUSE_IMAGE
|
||||
|
||||
class wxGDIPlusMeasuringContext : public wxGDIPlusContext
|
||||
{
|
||||
public:
|
||||
@@ -469,6 +505,10 @@ public :
|
||||
|
||||
virtual wxGraphicsContext * CreateContext( wxWindow* window );
|
||||
|
||||
#if wxUSE_IMAGE
|
||||
virtual wxGraphicsContext * CreateContextFromImage(wxImage& image);
|
||||
#endif // wxUSE_IMAGE
|
||||
|
||||
virtual wxGraphicsContext * CreateMeasuringContext();
|
||||
|
||||
// Path
|
||||
@@ -498,6 +538,9 @@ public :
|
||||
|
||||
// create a native bitmap representation
|
||||
virtual wxGraphicsBitmap CreateBitmap( const wxBitmap &bitmap );
|
||||
#if wxUSE_IMAGE
|
||||
virtual wxGraphicsBitmap CreateBitmapFromImage(const wxImage& image);
|
||||
#endif // wxUSE_IMAGE
|
||||
|
||||
// stub: should not be called directly
|
||||
virtual wxGraphicsFont CreateFont( const wxFont& WXUNUSED(font),
|
||||
@@ -1013,12 +1056,50 @@ wxGDIPlusBitmapData::wxGDIPlusBitmapData( wxGraphicsRenderer* renderer,
|
||||
m_bitmap = image;
|
||||
}
|
||||
|
||||
#if wxUSE_IMAGE
|
||||
|
||||
wxImage wxGDIPlusBitmapData::ConvertToImage() const
|
||||
{
|
||||
// We could use Bitmap::LockBits() and convert to wxImage directly but
|
||||
// passing by wxBitmap is easier. It would be nice to measure performance
|
||||
// of the two methods but for this the second one would need to be written
|
||||
// first...
|
||||
HBITMAP hbmp;
|
||||
if ( m_bitmap->GetHBITMAP(Color(0xffffffff), &hbmp) != Gdiplus::Ok )
|
||||
return wxNullImage;
|
||||
|
||||
wxBitmap bmp;
|
||||
bmp.SetWidth(m_bitmap->GetWidth());
|
||||
bmp.SetHeight(m_bitmap->GetHeight());
|
||||
bmp.SetHBITMAP(hbmp);
|
||||
bmp.SetDepth(IsAlphaPixelFormat(m_bitmap->GetPixelFormat()) ? 32 : 24);
|
||||
return bmp.ConvertToImage();
|
||||
}
|
||||
|
||||
#endif // wxUSE_IMAGE
|
||||
|
||||
wxGDIPlusBitmapData::~wxGDIPlusBitmapData()
|
||||
{
|
||||
delete m_bitmap;
|
||||
delete m_helper;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxGraphicsBitmap implementation
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if wxUSE_IMAGE
|
||||
|
||||
wxImage wxGraphicsBitmap::ConvertToImage() const
|
||||
{
|
||||
const wxGDIPlusBitmapData* const
|
||||
data = static_cast<wxGDIPlusBitmapData*>(GetGraphicsData());
|
||||
|
||||
return data ? data->ConvertToImage() : wxNullImage;
|
||||
}
|
||||
|
||||
#endif // wxUSE_IMAGE
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// wxGDIPlusPath implementation
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -1939,6 +2020,17 @@ wxGraphicsContext * wxGDIPlusRenderer::CreateContext( const wxMemoryDC& dc)
|
||||
return context;
|
||||
}
|
||||
|
||||
#if wxUSE_IMAGE
|
||||
wxGraphicsContext * wxGDIPlusRenderer::CreateContextFromImage(wxImage& image)
|
||||
{
|
||||
ENSURE_LOADED_OR_RETURN(NULL);
|
||||
wxGDIPlusContext* context = new wxGDIPlusImageContext(this, image);
|
||||
context->EnableOffset(true);
|
||||
return context;
|
||||
}
|
||||
|
||||
#endif // wxUSE_IMAGE
|
||||
|
||||
wxGraphicsContext * wxGDIPlusRenderer::CreateMeasuringContext()
|
||||
{
|
||||
ENSURE_LOADED_OR_RETURN(NULL);
|
||||
@@ -2071,6 +2163,29 @@ wxGraphicsBitmap wxGDIPlusRenderer::CreateBitmap( const wxBitmap &bitmap )
|
||||
return wxNullGraphicsBitmap;
|
||||
}
|
||||
|
||||
#if wxUSE_IMAGE
|
||||
|
||||
wxGraphicsBitmap wxGDIPlusRenderer::CreateBitmapFromImage(const wxImage& image)
|
||||
{
|
||||
ENSURE_LOADED_OR_RETURN(wxNullGraphicsBitmap);
|
||||
if ( image.IsOk() )
|
||||
{
|
||||
// Notice that we rely on conversion from wxImage to wxBitmap here but
|
||||
// we could probably do it more efficiently by converting from wxImage
|
||||
// to GDI+ Bitmap directly, i.e. copying wxImage pixels to the buffer
|
||||
// returned by Bitmap::LockBits(). However this would require writing
|
||||
// code specific for this task while like this we can reuse existing
|
||||
// code (see also wxGDIPlusBitmapData::ConvertToImage()).
|
||||
wxGraphicsBitmap gb;
|
||||
gb.SetRefData(new wxGDIPlusBitmapData(this, image));
|
||||
return gb;
|
||||
}
|
||||
else
|
||||
return wxNullGraphicsBitmap;
|
||||
}
|
||||
|
||||
#endif // wxUSE_IMAGE
|
||||
|
||||
wxGraphicsBitmap wxGDIPlusRenderer::CreateBitmapFromNativeBitmap( void *bitmap )
|
||||
{
|
||||
ENSURE_LOADED_OR_RETURN(wxNullGraphicsBitmap);
|
||||
|
@@ -2724,6 +2724,49 @@ wxGraphicsMatrix wxMacCoreGraphicsContext::GetTransform() const
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
#if wxUSE_IMAGE
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxMacCoreGraphicsImageContext
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// This is a GC that can be used to draw on wxImage. In this implementation we
|
||||
// simply draw on a wxBitmap using wxMemoryDC and then convert it to wxImage in
|
||||
// the end so it's not especially interesting and exists mainly for
|
||||
// compatibility with the other platforms.
|
||||
class wxMacCoreGraphicsImageContext : public wxMacCoreGraphicsContext
|
||||
{
|
||||
public:
|
||||
wxMacCoreGraphicsImageContext(wxGraphicsRenderer* renderer,
|
||||
wxImage& image) :
|
||||
wxMacCoreGraphicsContext(renderer),
|
||||
m_image(image),
|
||||
m_bitmap(image),
|
||||
m_memDC(m_bitmap)
|
||||
{
|
||||
SetNativeContext
|
||||
(
|
||||
(CGContextRef)(m_memDC.GetGraphicsContext()->GetNativeContext())
|
||||
);
|
||||
m_width = image.GetWidth();
|
||||
m_height = image.GetHeight();
|
||||
}
|
||||
|
||||
virtual ~wxMacCoreGraphicsImageContext()
|
||||
{
|
||||
m_memDC.SelectObject(wxNullBitmap);
|
||||
m_image = m_bitmap.ConvertToImage();
|
||||
}
|
||||
|
||||
private:
|
||||
wxImage& m_image;
|
||||
wxBitmap m_bitmap;
|
||||
wxMemoryDC m_memDC;
|
||||
};
|
||||
|
||||
#endif // wxUSE_IMAGE
|
||||
|
||||
//
|
||||
// Renderer
|
||||
//
|
||||
@@ -2753,6 +2796,10 @@ public :
|
||||
|
||||
virtual wxGraphicsContext * CreateContext( wxWindow* window );
|
||||
|
||||
#if wxUSE_IMAGE
|
||||
virtual wxGraphicsContext * CreateContextFromImage(wxImage& image);
|
||||
#endif // wxUSE_IMAGE
|
||||
|
||||
virtual wxGraphicsContext * CreateMeasuringContext();
|
||||
|
||||
// Path
|
||||
@@ -2786,6 +2833,10 @@ public :
|
||||
// create a native bitmap representation
|
||||
virtual wxGraphicsBitmap CreateBitmap( const wxBitmap &bitmap ) ;
|
||||
|
||||
#if wxUSE_IMAGE
|
||||
virtual wxGraphicsBitmap CreateBitmapFromImage(const wxImage& image);
|
||||
#endif // wxUSE_IMAGE
|
||||
|
||||
// create a graphics bitmap from a native bitmap
|
||||
virtual wxGraphicsBitmap CreateBitmapFromNativeBitmap( void* bitmap );
|
||||
|
||||
@@ -2895,6 +2946,16 @@ wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateMeasuringContext()
|
||||
return new wxMacCoreGraphicsContext(this);
|
||||
}
|
||||
|
||||
#if wxUSE_IMAGE
|
||||
|
||||
wxGraphicsContext*
|
||||
wxMacCoreGraphicsRenderer::CreateContextFromImage(wxImage& image)
|
||||
{
|
||||
return new wxMacCoreGraphicsImageContext(this, image);
|
||||
}
|
||||
|
||||
#endif // wxUSE_IMAGE
|
||||
|
||||
// Path
|
||||
|
||||
wxGraphicsPath wxMacCoreGraphicsRenderer::CreatePath()
|
||||
@@ -2953,6 +3014,20 @@ wxGraphicsBitmap wxMacCoreGraphicsRenderer::CreateBitmap( const wxBitmap& bmp )
|
||||
return wxNullGraphicsBitmap;
|
||||
}
|
||||
|
||||
#if wxUSE_IMAGE
|
||||
|
||||
wxGraphicsBitmap
|
||||
wxMacCoreGraphicsRenderer::CreateBitmapFromImage(const wxImage& image)
|
||||
{
|
||||
// We don't have any direct way to convert wxImage to CGImage so pass by
|
||||
// wxBitmap. This makes this function pretty useless in this implementation
|
||||
// but it allows to have the same API as with Cairo backend where we can
|
||||
// convert wxImage to a Cairo surface directly, bypassing wxBitmap.
|
||||
return CreateBitmap(wxBitmap(image));
|
||||
}
|
||||
|
||||
#endif // wxUSE_IMAGE
|
||||
|
||||
wxGraphicsBitmap wxMacCoreGraphicsRenderer::CreateBitmapFromNativeBitmap( void* bitmap )
|
||||
{
|
||||
if ( bitmap != NULL )
|
||||
|
Reference in New Issue
Block a user