Merge branch 'more-icon-fixes'
More icon fixes in wxMSW: fix transparency in wxImageList and size in wxArtProvider. See #22487.
This commit is contained in:
@@ -304,6 +304,30 @@ void wxArtProvider::RescaleBitmap(wxBitmap& bmp, const wxSize& sizeNeeded)
|
||||
}
|
||||
#endif // WXWIN_COMPATIBILITY_3_0
|
||||
|
||||
#if wxUSE_IMAGE
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
bool CanUpscaleByInt(int w, int h, const wxSize& sizeNeeded)
|
||||
{
|
||||
return !(sizeNeeded.x % w) && !(sizeNeeded.y % h);
|
||||
}
|
||||
|
||||
void ExtendBitmap(wxBitmap& bmp, const wxSize& sizeNeeded)
|
||||
{
|
||||
const wxSize size = bmp.GetSize();
|
||||
|
||||
wxPoint offset((sizeNeeded.x - size.x)/2, (sizeNeeded.y - size.y)/2);
|
||||
wxImage img = bmp.ConvertToImage();
|
||||
img.Resize(sizeNeeded, offset);
|
||||
bmp = wxBitmap(img);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
#endif // wxUSE_IMAGE
|
||||
|
||||
void
|
||||
wxArtProvider::RescaleOrResizeIfNeeded(wxBitmap& bmp, const wxSize& sizeNeeded)
|
||||
{
|
||||
@@ -317,25 +341,42 @@ wxArtProvider::RescaleOrResizeIfNeeded(wxBitmap& bmp, const wxSize& sizeNeeded)
|
||||
return;
|
||||
|
||||
#if wxUSE_IMAGE
|
||||
// Allow upscaling by an integer factor: this looks not too horribly and is
|
||||
// needed to use reasonably-sized bitmaps in the code not yet updated to
|
||||
// use wxBitmapBundle but using custom art providers.
|
||||
if ((bmp_w <= sizeNeeded.x) && (bmp_h <= sizeNeeded.y) &&
|
||||
(sizeNeeded.x % bmp_w || sizeNeeded.y % bmp_h))
|
||||
// Check if we need to increase or decrease the image size (mixed case is
|
||||
// handled as decreasing).
|
||||
if ((bmp_w <= sizeNeeded.x) && (bmp_h <= sizeNeeded.y))
|
||||
{
|
||||
// Allow upscaling by an integer factor: this looks not too horribly and is
|
||||
// needed to use reasonably-sized bitmaps in the code not yet updated to
|
||||
// use wxBitmapBundle but using custom art providers.
|
||||
bool shouldUpscale = CanUpscaleByInt(bmp_w, bmp_h, sizeNeeded);
|
||||
|
||||
// And account for the common case of 16x15 bitmaps used for many wxMSW
|
||||
// images: those can be resized to 16x16 and then upscaled if possible
|
||||
// (and if 16x16 is the required size, there is no need to upscale, so
|
||||
// don't handle this sub-case specially at all).
|
||||
if (!shouldUpscale && bmp_w == 16 && bmp_h == 15 && sizeNeeded.y != 16)
|
||||
{
|
||||
// If we can't upscale it with its current height, perhaps we can
|
||||
// if we resize it to 16 first?
|
||||
if (CanUpscaleByInt(bmp_w, 16, sizeNeeded))
|
||||
{
|
||||
ExtendBitmap(bmp, wxSize(16, 16));
|
||||
shouldUpscale = true;
|
||||
}
|
||||
}
|
||||
|
||||
// the caller wants default size, which is larger than
|
||||
// the image we have; to avoid degrading it visually by
|
||||
// scaling it up, paste it into transparent image instead:
|
||||
wxPoint offset((sizeNeeded.x - bmp_w)/2, (sizeNeeded.y - bmp_h)/2);
|
||||
wxImage img = bmp.ConvertToImage();
|
||||
img.Resize(sizeNeeded, offset);
|
||||
bmp = wxBitmap(img);
|
||||
if (!shouldUpscale)
|
||||
{
|
||||
ExtendBitmap(bmp, sizeNeeded);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else // scale (down or mixed, but not up, or at least not by an int factor)
|
||||
#endif // wxUSE_IMAGE
|
||||
{
|
||||
wxBitmap::Rescale(bmp, sizeNeeded);
|
||||
}
|
||||
|
||||
wxBitmap::Rescale(bmp, sizeNeeded);
|
||||
}
|
||||
|
||||
/*static*/ wxBitmap wxArtProvider::GetBitmap(const wxArtID& id,
|
||||
|
||||
@@ -328,26 +328,11 @@ int wxImageList::Add(const wxBitmap& bitmap, const wxColour& maskColour)
|
||||
// Adds a bitmap and mask from an icon.
|
||||
int wxImageList::Add(const wxIcon& icon)
|
||||
{
|
||||
// ComCtl32 prior 6.0 doesn't support images with alpha
|
||||
// channel so if we have 32-bit icon with transparency
|
||||
// we need to add it as a wxBitmap via dedicated method
|
||||
// where alpha channel will be converted to the mask.
|
||||
if ( wxApp::GetComCtl32Version() < 600 )
|
||||
{
|
||||
wxBitmap bmp(icon);
|
||||
if ( bmp.HasAlpha() )
|
||||
{
|
||||
return Add(bmp);
|
||||
}
|
||||
}
|
||||
|
||||
int index = ImageList_AddIcon(GetHImageList(), GetHiconOf(icon));
|
||||
if ( index == -1 )
|
||||
{
|
||||
wxLogError(_("Couldn't add an image to the image list."));
|
||||
}
|
||||
|
||||
return index;
|
||||
// We don't use ImageList_AddIcon() here as this only works for icons with
|
||||
// masks when using ILC_MASK, which we usually don't do, so reuse the
|
||||
// bitmap function instead -- even if it's slightly less efficient due to
|
||||
// extra conversions, it's simpler than handling all the various cases here.
|
||||
return Add(wxBitmap(icon));
|
||||
}
|
||||
|
||||
// Replaces a bitmap, optionally passing a mask bitmap.
|
||||
@@ -372,26 +357,9 @@ bool wxImageList::Replace(int index,
|
||||
// Replaces a bitmap and mask from an icon.
|
||||
bool wxImageList::Replace(int i, const wxIcon& icon)
|
||||
{
|
||||
// ComCtl32 prior 6.0 doesn't support images with alpha
|
||||
// channel so if we have 32-bit icon with transparency
|
||||
// we need to replace it as a wxBitmap via dedicated method
|
||||
// where alpha channel will be converted to the mask.
|
||||
if ( wxApp::GetComCtl32Version() < 600 )
|
||||
{
|
||||
wxBitmap bmp(icon);
|
||||
if ( bmp.HasAlpha() )
|
||||
{
|
||||
return Replace(i, bmp);
|
||||
}
|
||||
}
|
||||
|
||||
bool ok = ImageList_ReplaceIcon(GetHImageList(), i, GetHiconOf(icon)) != -1;
|
||||
if ( !ok )
|
||||
{
|
||||
wxLogLastError(wxT("ImageList_ReplaceIcon()"));
|
||||
}
|
||||
|
||||
return ok;
|
||||
// Same as in Add() above, just reuse the existing function for simplicity
|
||||
// even if it means an extra conversion.
|
||||
return Replace(i, wxBitmap(icon));
|
||||
}
|
||||
|
||||
// Removes the image at the given index.
|
||||
|
||||
Reference in New Issue
Block a user