Fix caching source bitmap in wxD2DBitmapResourceHolder (Direct2D)

Because cached wxBitmap is used only to help in representing native D2D
bitmap in some operations it shouldn't be exposed directly and dedicated
methods should be implemented instead.
This commit is contained in:
Artur Wieczorek
2021-02-06 00:01:34 +01:00
parent 8c599408ab
commit 46302896e1

View File

@@ -2370,9 +2370,48 @@ public:
wxD2DBitmapResourceHolder(const wxBitmap& sourceBitmap) : wxD2DBitmapResourceHolder(const wxBitmap& sourceBitmap) :
m_sourceBitmap(sourceBitmap) m_sourceBitmap(sourceBitmap)
{ {
m_sourceBitmap.MSWBlendMaskWithAlpha();
} }
const wxBitmap& GetSourceBitmap() const { return m_sourceBitmap; } #if wxUSE_IMAGE
wxImage ConvertToImage() const
{
// Never return image with mask because native bitmaps don't have masks
wxImage img = m_sourceBitmap.ConvertToImage();
if ( img.HasMask() )
{
if ( !img.HasAlpha() )
{
img.InitAlpha();
}
else
{
// This case should never happen because cached source
// bitmap has mask blended with alpha values (in ctor).
}
}
// We need also to remove mask colour from transparent pixels
// for compatibility with native D2D bitmap.
if ( img.HasAlpha() )
{
for ( int y = 0; y < img.GetHeight(); y++ )
for ( int x = 0; x < img.GetWidth(); x++ )
{
if ( img.GetAlpha(x, y) == wxALPHA_TRANSPARENT )
{
img.SetRGB(x, y, 0, 0, 0);
}
}
}
return img;
}
#endif // wxUSE_IMAGE
wxD2DBitmapResourceHolder* GetSubBitmap(wxDouble x, wxDouble y, wxDouble w, wxDouble h) const
{
return new wxD2DBitmapResourceHolder(m_sourceBitmap.GetSubBitmap(wxRect(x, y, w, h)));
}
protected: protected:
void DoAcquireResource() wxOVERRIDE void DoAcquireResource() wxOVERRIDE
@@ -2443,7 +2482,7 @@ protected:
} }
private: private:
const wxBitmap m_sourceBitmap; wxBitmap m_sourceBitmap;
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -2456,10 +2495,15 @@ public:
typedef wxD2DBitmapResourceHolder NativeType; typedef wxD2DBitmapResourceHolder NativeType;
wxD2DBitmapData(wxGraphicsRenderer* renderer, const wxBitmap& bitmap) : wxD2DBitmapData(wxGraphicsRenderer* renderer, const wxBitmap& bitmap) :
wxGraphicsBitmapData(renderer), m_bitmapHolder(bitmap) {} wxGraphicsBitmapData(renderer)
{
m_bitmapHolder = new NativeType(bitmap);
}
wxD2DBitmapData(wxGraphicsRenderer* renderer, const void* pseudoNativeBitmap) : wxD2DBitmapData(wxGraphicsRenderer* renderer, NativeType* pseudoNativeBitmap) :
wxGraphicsBitmapData(renderer), m_bitmapHolder(*static_cast<const NativeType*>(pseudoNativeBitmap)) {} wxGraphicsBitmapData(renderer), m_bitmapHolder(pseudoNativeBitmap) {}
~wxD2DBitmapData();
// returns the native representation // returns the native representation
void* GetNativeBitmap() const wxOVERRIDE; void* GetNativeBitmap() const wxOVERRIDE;
@@ -2468,25 +2512,30 @@ public:
wxD2DManagedObject* GetManagedObject() wxOVERRIDE wxD2DManagedObject* GetManagedObject() wxOVERRIDE
{ {
return &m_bitmapHolder; return m_bitmapHolder;
} }
private: private:
NativeType m_bitmapHolder; NativeType* m_bitmapHolder;
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// wxD2DBitmapData implementation // wxD2DBitmapData implementation
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
wxD2DBitmapData::~wxD2DBitmapData()
{
delete m_bitmapHolder;
}
void* wxD2DBitmapData::GetNativeBitmap() const void* wxD2DBitmapData::GetNativeBitmap() const
{ {
return (void*)&m_bitmapHolder; return static_cast<void*>(m_bitmapHolder);
} }
wxCOMPtr<ID2D1Bitmap> wxD2DBitmapData::GetD2DBitmap() wxCOMPtr<ID2D1Bitmap> wxD2DBitmapData::GetD2DBitmap()
{ {
return m_bitmapHolder.GetD2DResource(); return m_bitmapHolder->GetD2DResource();
} }
wxD2DBitmapData* wxGetD2DBitmapData(const wxGraphicsBitmap& bitmap) wxD2DBitmapData* wxGetD2DBitmapData(const wxGraphicsBitmap& bitmap)
@@ -4490,11 +4539,12 @@ void wxD2DContext::DrawBitmap(const wxGraphicsBitmap& bmp, wxDouble x, wxDouble
wxD2DBitmapData* bitmapData = wxGetD2DBitmapData(bmp); wxD2DBitmapData* bitmapData = wxGetD2DBitmapData(bmp);
bitmapData->Bind(this); bitmapData->Bind(this);
wxBitmap const& bitmap = static_cast<wxD2DBitmapData::NativeType*>(bitmapData->GetNativeBitmap())->GetSourceBitmap();
wxCOMPtr<ID2D1Bitmap> d2dBmp = bitmapData->GetD2DBitmap();
D2D1_SIZE_F d2dBmpSize = d2dBmp->GetSize();
m_renderTargetHolder->DrawBitmap( m_renderTargetHolder->DrawBitmap(
bitmapData->GetD2DBitmap(), d2dBmp,
D2D1::RectF(0, 0, bitmap.GetWidth(), bitmap.GetHeight()), D2D1::RectF(0, 0, d2dBmpSize.width, d2dBmpSize.height),
D2D1::RectF(x, y, x + w, y + h), D2D1::RectF(x, y, x + w, y + h),
GetInterpolationQuality(), GetInterpolationQuality(),
GetCompositionMode()); GetCompositionMode());
@@ -5127,7 +5177,7 @@ wxGraphicsBitmap wxD2DRenderer::CreateBitmap(const wxBitmap& bitmap)
// create a graphics bitmap from a native bitmap // create a graphics bitmap from a native bitmap
wxGraphicsBitmap wxD2DRenderer::CreateBitmapFromNativeBitmap(void* bitmap) wxGraphicsBitmap wxD2DRenderer::CreateBitmapFromNativeBitmap(void* bitmap)
{ {
wxD2DBitmapData* bitmapData = new wxD2DBitmapData(this, bitmap); wxD2DBitmapData* bitmapData = new wxD2DBitmapData(this, static_cast<wxD2DBitmapResourceHolder*>(bitmap));
wxGraphicsBitmap graphicsBitmap; wxGraphicsBitmap graphicsBitmap;
graphicsBitmap.SetRefData(bitmapData); graphicsBitmap.SetRefData(bitmapData);
@@ -5144,7 +5194,7 @@ wxGraphicsBitmap wxD2DRenderer::CreateBitmapFromImage(const wxImage& image)
wxImage wxD2DRenderer::CreateImageFromBitmap(const wxGraphicsBitmap& bmp) wxImage wxD2DRenderer::CreateImageFromBitmap(const wxGraphicsBitmap& bmp)
{ {
return static_cast<wxD2DBitmapData::NativeType*>(bmp.GetNativeBitmap()) return static_cast<wxD2DBitmapData::NativeType*>(bmp.GetNativeBitmap())
->GetSourceBitmap().ConvertToImage(); ->ConvertToImage();
} }
#endif #endif
@@ -5192,8 +5242,11 @@ wxGraphicsFont wxD2DRenderer::CreateFontAtDPI(const wxFont& font,
wxGraphicsBitmap wxD2DRenderer::CreateSubBitmap(const wxGraphicsBitmap& bitmap, wxDouble x, wxDouble y, wxDouble w, wxDouble h) wxGraphicsBitmap wxD2DRenderer::CreateSubBitmap(const wxGraphicsBitmap& bitmap, wxDouble x, wxDouble y, wxDouble w, wxDouble h)
{ {
typedef wxD2DBitmapData::NativeType* NativeBitmap; typedef wxD2DBitmapData::NativeType* NativeBitmap;
wxBitmap sourceBitmap = static_cast<NativeBitmap>(bitmap.GetNativeBitmap())->GetSourceBitmap();
return CreateBitmap(sourceBitmap.GetSubBitmap(wxRect(x, y, w, h))); NativeBitmap natBmp = static_cast<NativeBitmap>(bitmap.GetNativeBitmap())->GetSubBitmap(x, y, w, h);
wxGraphicsBitmap bmpRes;
bmpRes.SetRefData(new wxD2DBitmapData(this, natBmp));
return bmpRes;
} }
wxString wxD2DRenderer::GetName() const wxString wxD2DRenderer::GetName() const