Support creating wxBitmapBundle from SVG in application resource

Allow creating wxBitmapBitmap from SVG image stored in an application
resource on the platforms where wxHAS_IMAGE_RESOURCES is defined.

On Windows, load the bundle from a resource with RT_RCDATA type and on
MacOS from a file with an extension "svg" placed in the "Resources"
subdirectory of the application bundle.

Closes #22061.
This commit is contained in:
PB
2022-01-26 16:58:49 +01:00
committed by Vadim Zeitlin
parent 3f3561e2c6
commit 5ba37d867c
5 changed files with 80 additions and 3 deletions

View File

@@ -78,6 +78,12 @@ public:
// Load SVG image from the given file (must be a local file, not an URL).
static wxBitmapBundle FromSVGFile(const wxString& path, const wxSize& sizeDef);
// Create from SVG image stored as an application resource.
// On Windows, name must be a resource with RT_RCDATA type.
// On MacOS, name must be a file with an extension "svg" placed in the
// "Resources" subdirectory of the application bundle.
static wxBitmapBundle FromSVGResource(const wxString& name, const wxSize& sizeDef);
#endif // wxHAS_SVG
// Create from the resources: all existing versions of the bitmap of the

View File

@@ -76,6 +76,7 @@
wxBITMAP_BUNDLE_2() macro which can avoid the need to check for
wxHAS_IMAGE_RESOURCES explicitly in the code in a common case of having
only 2 embedded resources (for standard and high DPI).
See also FromSVGResource().
Also note that the existing code using wxBitmap is compatible with the
functions taking wxBitmapBundle in wxWidgets 3.1.6 and later because
@@ -187,14 +188,16 @@ public:
Create a bundle from the bitmaps in the application resources.
This function can only be used on the platforms supporting storing
bitmaps in resources, and currently only works under MSW and simply
returns an empty bundle on the other platforms.
bitmaps in resources, and currently only works under MSW and MacOS
and returns an empty bundle on the other platforms.
Under MSW, for this function to create a valid bundle, you must have @c
RCDATA resource with the given @a name in your application resource
file (with the extension @c .rc) containing PNG file, and any other
resources using @a name as prefix and suffix with the scale, e.g. "_2x"
or "_1_5x" (for 150% DPI) will be also loaded as part of the bundle.
@see FromSVGResource()
*/
static wxBitmapBundle FromResources(const wxString& name);
@@ -261,6 +264,21 @@ public:
*/
static wxBitmapBundle FromSVGFile(const wxString& path, const wxSize& sizeDef);
/**
Create a bundle from the SVG image loaded from an application resource.
Available only on the platforms supporting images in resources, i.e.,
MSW and MacOS.
@param name On MSW, it must be a resource with @c RT_RCDATA type.
On MacOS, it must be a file with an extension "svg" placed in
the "Resources" subdirectory of the application bundle.
@param sizeDef The default size to return from GetDefaultSize() for
this bundle.
@see FromResources(), FromSVGFile()
*/
static wxBitmapBundle FromSVGResource(const wxString& name, const wxSize& sizeDef);
/**
Check if bitmap bundle is non-empty.

View File

@@ -358,7 +358,7 @@ wxBitmapBundle wxBitmapBundle::FromImpl(wxBitmapBundleImpl* impl)
}
// MSW has its own, actually working, version, in MSW-specific code.
// MSW and MacOS have their own, actually working, version, in their platform-specific code.
#if !defined( __WXMSW__ ) && !defined( __WXOSX__ )
/* static */
@@ -374,6 +374,23 @@ wxBitmapBundle wxBitmapBundle::FromResources(const wxString& WXUNUSED(name))
return wxBitmapBundle();
}
#ifdef wxHAS_SVG
/* static */
wxBitmapBundle wxBitmapBundle::FromSVGResource(const wxString& WXUNUSED(name), const wxSize& WXUNUSED(sizeDef))
{
wxFAIL_MSG
(
"Loading an SVG from a resource not available on this platform, "
"don't use this function and call wxBitmapBundle::FromSVG(File)() "
"instead."
);
return wxBitmapBundle();
}
#endif // wxHAS_SVG
#endif // !__WXMSW__ && !__WXOSX__
wxBitmapBundle wxBitmapBundle::FromFiles(const wxString& filename)

View File

@@ -18,9 +18,12 @@
// for compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#include "wx/utils.h"
#ifndef WX_PRECOMP
#include "wx/log.h"
#include "wx/msw/private.h"
#include "wx/msw/wrapwin.h"
#endif // WX_PRECOMP
@@ -352,3 +355,29 @@ wxBitmapBundle wxBitmapBundle::FromResources(const wxString& name)
return wxBitmapBundle(new wxBitmapBundleImplRC(resourceInfos, bitmap));
}
#ifdef wxHAS_SVG
/* static */
wxBitmapBundle wxBitmapBundle::FromSVGResource(const wxString& name, const wxSize& sizeDef)
{
// Currently we hardcode RCDATA resource type as this is what is usually
// used for the embedded images. We could allow specifying the type as part
// of the name in the future (e.g. "type:name" or something like this) if
// really needed.
wxCharBuffer svgData = wxCharBuffer::CreateOwned(wxLoadUserResource(name, RT_RCDATA, NULL, wxGetInstance()));
if ( !svgData.data() )
{
wxLogError(wxS("SVG image \"%s\" not found, check ")
wxS("that the resource file contains \"RCDATA\" ")
wxS("resource with this name."),
name);
return wxBitmapBundle();
}
return wxBitmapBundle::FromSVG(svgData.data(), sizeDef);
}
#endif // wxHAS_SVG

View File

@@ -281,3 +281,10 @@ WXImage wxOSXGetImageFromBundle(const wxBitmapBundle& bundle)
return image;
}
#ifdef wxHAS_SVG
wxBitmapBundle wxBitmapBundle::FromSVGResource(const wxString& name, const wxSize &sizeDef)
{
return wxBitmapBundle::FromSVGFile(wxFileName(wxStandardPaths::Get().GetResourcesDir(), name, "svg").GetFullPath(), sizeDef);
}
#endif // #ifdef wxHAS_SVG