From 5ba37d867cb4ed7adcf40cf5318c0bbb2c4f33ba Mon Sep 17 00:00:00 2001 From: PB Date: Wed, 26 Jan 2022 16:58:49 +0100 Subject: [PATCH] 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. --- include/wx/bmpbndl.h | 6 ++++++ interface/wx/bmpbndl.h | 22 ++++++++++++++++++++-- src/common/bmpbndl.cpp | 19 ++++++++++++++++++- src/msw/bmpbndl.cpp | 29 +++++++++++++++++++++++++++++ src/osx/core/bmpbndl.mm | 7 +++++++ 5 files changed, 80 insertions(+), 3 deletions(-) diff --git a/include/wx/bmpbndl.h b/include/wx/bmpbndl.h index 15083e01b4..ad57680687 100644 --- a/include/wx/bmpbndl.h +++ b/include/wx/bmpbndl.h @@ -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 diff --git a/interface/wx/bmpbndl.h b/interface/wx/bmpbndl.h index 18c93ed6f4..f052645577 100644 --- a/interface/wx/bmpbndl.h +++ b/interface/wx/bmpbndl.h @@ -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. diff --git a/src/common/bmpbndl.cpp b/src/common/bmpbndl.cpp index c2b66b3ea7..a746ae557c 100644 --- a/src/common/bmpbndl.cpp +++ b/src/common/bmpbndl.cpp @@ -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) diff --git a/src/msw/bmpbndl.cpp b/src/msw/bmpbndl.cpp index 12dfce9997..5f2a40c3ee 100644 --- a/src/msw/bmpbndl.cpp +++ b/src/msw/bmpbndl.cpp @@ -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 diff --git a/src/osx/core/bmpbndl.mm b/src/osx/core/bmpbndl.mm index 72e5ec007e..f5e364011e 100644 --- a/src/osx/core/bmpbndl.mm +++ b/src/osx/core/bmpbndl.mm @@ -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