Avoid bitmap scaling in wxArtProvider::GetBitmapBundle()
Instead of immediately constructing the bitmap with the requested size, possibly by downscaling a higher-resolution bitmap, and then potentially having to upscale it if we actually need a bitmap of a bigger size, just retrieve the bitmap in the actually needed size from wxArtProvider when needed. This makes bitmaps obtained from wxArtProvider::GetBitmapBundle() look good, rather than fuzzy and ugly, in high DPI if they're actually available in the appropriate size.
This commit is contained in:
@@ -234,14 +234,11 @@ protected:
|
||||
return wxNullBitmap;
|
||||
}
|
||||
|
||||
// Derived classes must override CreateBitmapBundle if they provide
|
||||
// a bundle that cannot be represented through an ordinary bitmap.
|
||||
// Default implementation creates a wxBitmapBundle which returns the
|
||||
// specified art resource in whichever size it is being asked for.
|
||||
virtual wxBitmapBundle CreateBitmapBundle(const wxArtID& id,
|
||||
const wxArtClient& client,
|
||||
const wxSize& size)
|
||||
{
|
||||
return wxBitmapBundle(CreateBitmap(id, client, size));
|
||||
}
|
||||
const wxSize& size);
|
||||
|
||||
virtual wxIconBundle CreateIconBundle(const wxArtID& WXUNUSED(id),
|
||||
const wxArtClient& WXUNUSED(client))
|
||||
|
||||
@@ -307,7 +307,9 @@ public:
|
||||
@param client
|
||||
wxArtClient identifier of the client (i.e. who is asking for the bitmap).
|
||||
@param size
|
||||
Default size for the returned bundle.
|
||||
Default size for the returned bundle, i.e. the size of the bitmap
|
||||
in normal DPI (this implies that wxWindow::FromDIP() must @e not be
|
||||
used with it).
|
||||
|
||||
@return If any of the registered providers recognizes the ID in its
|
||||
CreateBitmapBundle(), this bundle is returned. Otherwise, if any of
|
||||
|
||||
@@ -138,6 +138,77 @@ wxArtProviderCache::ConstructHashID(const wxArtID& id,
|
||||
wxString::Format(wxT("%d-%d"), size.x, size.y);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxBitmapBundleImplArt: uses art provider to get the bitmaps
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
class wxBitmapBundleImplArt : public wxBitmapBundleImpl
|
||||
{
|
||||
public:
|
||||
wxBitmapBundleImplArt(const wxArtID& id,
|
||||
const wxArtClient& client,
|
||||
const wxSize& size)
|
||||
: m_artId(id),
|
||||
m_artClient(client),
|
||||
m_sizeDefault(GetValidSize(id, client, size))
|
||||
{
|
||||
}
|
||||
|
||||
virtual wxSize GetDefaultSize() const wxOVERRIDE
|
||||
{
|
||||
return m_sizeDefault;
|
||||
}
|
||||
|
||||
virtual wxSize GetPreferredSizeAtScale(double scale) const wxOVERRIDE
|
||||
{
|
||||
// We have no preferred sizes.
|
||||
return m_sizeDefault*scale;
|
||||
}
|
||||
|
||||
virtual wxBitmap GetBitmap(const wxSize& size) wxOVERRIDE
|
||||
{
|
||||
return wxArtProvider::GetBitmap(m_artId, m_artClient, size);
|
||||
}
|
||||
|
||||
private:
|
||||
static wxSize GetValidSize(const wxArtID& id,
|
||||
const wxArtClient& client,
|
||||
const wxSize& size)
|
||||
{
|
||||
// If valid size is provided, just use it.
|
||||
if ( size != wxDefaultSize )
|
||||
return size;
|
||||
|
||||
// Otherwise, try to get the size we'd use without creating a bitmap
|
||||
// immediately.
|
||||
const wxSize sizeHint = wxArtProvider::GetSizeHint(client);
|
||||
if ( sizeHint != wxDefaultSize )
|
||||
return sizeHint;
|
||||
|
||||
// If we really have to, do create a bitmap just to get its size. Note
|
||||
// we need the size in logical pixels here, it will be scaled later if
|
||||
// necessary, so use GetScaledSize() and not GetSize().
|
||||
const wxBitmap bitmap = wxArtProvider::GetBitmap(id, client);
|
||||
if ( bitmap.IsOk() )
|
||||
return bitmap.GetScaledSize();
|
||||
|
||||
// We really need some default size, so just return this hardcoded
|
||||
// value if all else fails -- what else can we do.
|
||||
return wxSize(16, 16);
|
||||
}
|
||||
|
||||
const wxArtID m_artId;
|
||||
const wxArtClient m_artClient;
|
||||
const wxSize m_sizeDefault;
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(wxBitmapBundleImplArt);
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// ============================================================================
|
||||
// wxArtProvider class
|
||||
// ============================================================================
|
||||
@@ -305,7 +376,7 @@ wxBitmapBundle wxArtProvider::GetBitmapBundle(const wxArtID& id,
|
||||
|
||||
wxCHECK_MSG( sm_providers, wxNullBitmap, wxT("no wxArtProvider exists") );
|
||||
|
||||
wxString hashId = wxArtProviderCache::ConstructHashID(id, client);
|
||||
wxString hashId = wxArtProviderCache::ConstructHashID(id, client, size);
|
||||
|
||||
wxBitmapBundle bitmapbundle; // (DoGetIconBundle(id, client));
|
||||
|
||||
@@ -325,6 +396,12 @@ wxBitmapBundle wxArtProvider::GetBitmapBundle(const wxArtID& id,
|
||||
return bitmapbundle;
|
||||
}
|
||||
|
||||
wxBitmapBundle wxArtProvider::CreateBitmapBundle(const wxArtID& id,
|
||||
const wxArtClient& client,
|
||||
const wxSize& size)
|
||||
{
|
||||
return wxBitmapBundle::FromImpl(new wxBitmapBundleImplArt(id, client, size));
|
||||
}
|
||||
|
||||
/*static*/
|
||||
wxIconBundle wxArtProvider::GetIconBundle(const wxArtID& id, const wxArtClient& client)
|
||||
|
||||
Reference in New Issue
Block a user