{
Rect drawRect((REAL) x, (REAL)y, (REAL)w, (REAL)h);
m_context->SetPixelOffsetMode( PixelOffsetModeNone );
+ m_context->SetInterpolationMode(InterpolationModeHighQualityBicubic);
m_context->DrawImage(image, drawRect, 0 , 0 , image->GetWidth()-1, image->GetHeight()-1, UnitPixel ) ;
m_context->SetPixelOffsetMode( PixelOffsetModeHalf );
}
public :
wxGDIPlusRenderer()
{
- m_loaded = false;
+ m_loaded = -1;
m_gditoken = 0;
}
virtual ~wxGDIPlusRenderer()
{
- if (m_loaded)
+ if ( m_loaded == 1 )
{
Unload();
}
virtual wxGraphicsBitmap CreateSubBitmap( const wxGraphicsBitmap &bitmap, wxDouble x, wxDouble y, wxDouble w, wxDouble h );
protected :
- void EnsureIsLoaded();
+ bool EnsureIsLoaded();
void Load();
void Unload();
friend class wxGDIPlusRendererModule;
private :
- bool m_loaded;
+ int m_loaded;
ULONG_PTR m_gditoken;
DECLARE_DYNAMIC_CLASS_NO_COPY(wxGDIPlusRenderer)
return &gs_GDIPlusRenderer;
}
-void wxGDIPlusRenderer::EnsureIsLoaded()
+bool wxGDIPlusRenderer::EnsureIsLoaded()
{
- if (!m_loaded)
+ // load gdiplus.dll if not yet loaded, but don't bother doing it again
+ // if we already tried and failed (we don't want to spend lot of time
+ // returning NULL from wxGraphicsContext::Create(), which may be called
+ // relatively frequently):
+ if ( m_loaded == -1 )
{
Load();
}
+
+ return m_loaded == 1;
}
+// call EnsureIsLoaded() and return returnOnFail value if it fails
+#define ENSURE_LOADED_OR_RETURN(returnOnFail) \
+ if ( !EnsureIsLoaded() ) \
+ return (returnOnFail)
+
+
void wxGDIPlusRenderer::Load()
{
GdiplusStartupInput input;
GdiplusStartupOutput output;
- GdiplusStartup(&m_gditoken,&input,&output);
- m_loaded = true;
+ if ( GdiplusStartup(&m_gditoken,&input,&output) == Gdiplus::Ok )
+ {
+ wxLogTrace("gdiplus", "successfully initialized GDI+");
+ m_loaded = 1;
+ }
+ else
+ {
+ wxLogTrace("gdiplus", "failed to initialize GDI+, missing gdiplus.dll?");
+ m_loaded = 0;
+ }
}
void wxGDIPlusRenderer::Unload()
GdiplusShutdown(m_gditoken);
m_gditoken = NULL;
}
- m_loaded = false;
+ m_loaded = -1; // next Load() will try again
}
wxGraphicsContext * wxGDIPlusRenderer::CreateContext( const wxWindowDC& dc)
{
- EnsureIsLoaded();
+ ENSURE_LOADED_OR_RETURN(NULL);
wxMSWDCImpl *msw = wxDynamicCast( dc.GetImpl() , wxMSWDCImpl );
return new wxGDIPlusContext(this,(HDC) msw->GetHDC());
}
wxGraphicsContext * wxGDIPlusRenderer::CreateContext( const wxPrinterDC& dc)
{
- EnsureIsLoaded();
+ ENSURE_LOADED_OR_RETURN(NULL);
wxMSWDCImpl *msw = wxDynamicCast( dc.GetImpl() , wxMSWDCImpl );
return new wxGDIPlusContext(this,(HDC) msw->GetHDC());
}
wxGraphicsContext * wxGDIPlusRenderer::CreateContext( const wxMemoryDC& dc)
{
- EnsureIsLoaded();
+ ENSURE_LOADED_OR_RETURN(NULL);
wxMSWDCImpl *msw = wxDynamicCast( dc.GetImpl() , wxMSWDCImpl );
return new wxGDIPlusContext(this,(HDC) msw->GetHDC());
}
wxGraphicsContext * wxGDIPlusRenderer::CreateMeasuringContext()
{
- EnsureIsLoaded();
+ ENSURE_LOADED_OR_RETURN(NULL);
return new wxGDIPlusMeasuringContext(this);
}
wxGraphicsContext * wxGDIPlusRenderer::CreateContextFromNativeContext( void * context )
{
- EnsureIsLoaded();
+ ENSURE_LOADED_OR_RETURN(NULL);
return new wxGDIPlusContext(this,(Graphics*) context);
}
wxGraphicsContext * wxGDIPlusRenderer::CreateContextFromNativeWindow( void * window )
{
- EnsureIsLoaded();
+ ENSURE_LOADED_OR_RETURN(NULL);
return new wxGDIPlusContext(this,(HWND) window);
}
wxGraphicsContext * wxGDIPlusRenderer::CreateContext( wxWindow* window )
{
- EnsureIsLoaded();
+ ENSURE_LOADED_OR_RETURN(NULL);
return new wxGDIPlusContext(this, (HWND) window->GetHWND() );
}
wxGraphicsPath wxGDIPlusRenderer::CreatePath()
{
- EnsureIsLoaded();
+ ENSURE_LOADED_OR_RETURN(wxNullGraphicsPath);
wxGraphicsPath m;
m.SetRefData( new wxGDIPlusPathData(this));
return m;
wxDouble tx, wxDouble ty)
{
- EnsureIsLoaded();
+ ENSURE_LOADED_OR_RETURN(wxNullGraphicsMatrix);
wxGraphicsMatrix m;
wxGDIPlusMatrixData* data = new wxGDIPlusMatrixData( this );
data->Set( a,b,c,d,tx,ty ) ;
wxGraphicsPen wxGDIPlusRenderer::CreatePen(const wxPen& pen)
{
- EnsureIsLoaded();
+ ENSURE_LOADED_OR_RETURN(wxNullGraphicsPen);
if ( !pen.Ok() || pen.GetStyle() == wxTRANSPARENT )
return wxNullGraphicsPen;
else
wxGraphicsBrush wxGDIPlusRenderer::CreateBrush(const wxBrush& brush )
{
- EnsureIsLoaded();
+ ENSURE_LOADED_OR_RETURN(wxNullGraphicsBrush);
if ( !brush.Ok() || brush.GetStyle() == wxTRANSPARENT )
return wxNullGraphicsBrush;
else
wxGraphicsBrush wxGDIPlusRenderer::CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2,
const wxColour&c1, const wxColour&c2)
{
- EnsureIsLoaded();
+ ENSURE_LOADED_OR_RETURN(wxNullGraphicsBrush);
wxGraphicsBrush p;
wxGDIPlusBrushData* d = new wxGDIPlusBrushData( this );
d->CreateLinearGradientBrush(x1, y1, x2, y2, c1, c2);
wxGraphicsBrush wxGDIPlusRenderer::CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius,
const wxColour &oColor, const wxColour &cColor)
{
- EnsureIsLoaded();
+ ENSURE_LOADED_OR_RETURN(wxNullGraphicsBrush);
wxGraphicsBrush p;
wxGDIPlusBrushData* d = new wxGDIPlusBrushData( this );
d->CreateRadialGradientBrush(xo,yo,xc,yc,radius,oColor,cColor);
// sets the font
wxGraphicsFont wxGDIPlusRenderer::CreateFont( const wxFont &font , const wxColour &col )
{
- EnsureIsLoaded();
+ ENSURE_LOADED_OR_RETURN(wxNullGraphicsFont);
if ( font.Ok() )
{
wxGraphicsFont p;
wxGraphicsBitmap wxGDIPlusRenderer::CreateBitmap( const wxBitmap &bitmap )
{
- EnsureIsLoaded();
+ ENSURE_LOADED_OR_RETURN(wxNullGraphicsBitmap);
if ( bitmap.Ok() )
{
wxGraphicsBitmap p;
wxGraphicsBitmap wxGDIPlusRenderer::CreateSubBitmap( const wxGraphicsBitmap &bitmap, wxDouble x, wxDouble y, wxDouble w, wxDouble h )
{
- EnsureIsLoaded();
+ ENSURE_LOADED_OR_RETURN(wxNullGraphicsBitmap);
Bitmap* image = static_cast<wxGDIPlusBitmapData*>(bitmap.GetRefData())->GetGDIPlusBitmap();
if ( image )
{