Add FromSVG() overload taking const data

Passing non-const data is inconvenient and error-prone, as data can't be
used again after it was modified by Nano SVG, which resulted in the
button using SVG bitmap not working any longer in the toolbar sample
after recreating the toolbar.

So make it easier to do the right thing, while still keeping the
overload taking non-const data for the situations when avoiding an extra
copy is worth it.
This commit is contained in:
Vadim Zeitlin
2021-10-02 14:38:08 +01:00
parent 6783df71a7
commit ab619010bd
5 changed files with 23 additions and 9 deletions

View File

@@ -67,6 +67,9 @@ public:
// Notice that the data here is non-const because it can be temporarily // Notice that the data here is non-const because it can be temporarily
// modified while parsing it. // modified while parsing it.
static wxBitmapBundle FromSVG(char* data, const wxSize sizeDef); static wxBitmapBundle FromSVG(char* data, const wxSize sizeDef);
// This overload currently makes a copy of the data.
static wxBitmapBundle FromSVG(const char* data, const wxSize sizeDef);
#endif // wxHAS_RAW_BITMAP #endif // wxHAS_RAW_BITMAP
// Create from the resources: all existing versions of the bitmap of the // Create from the resources: all existing versions of the bitmap of the

View File

@@ -195,16 +195,21 @@ public:
@param data This data may, or not, have the XML document preamble, i.e. @param data This data may, or not, have the XML document preamble, i.e.
it can start either with @c "<?xml" processing instruction or it can start either with @c "<?xml" processing instruction or
directly with @c svg tag. Notice that the pointer is non-const as directly with @c svg tag. Notice that two overloads of this
the current implementation modifies it while parsing, i.e. do @a function, taking const and non-const data, are provided: as the
not use @c const_cast to pass data that is actually const to this current implementation modifies the data while parsing, using the
function. non-const variant is more efficient, as it avoids making copy of
the data, but the data is consumed by it and can't be reused any
more.
@param sizeDef The default size to return from GetDefaultSize() for @param sizeDef The default size to return from GetDefaultSize() for
this bundle. As SVG images usually don't have any natural this bundle. As SVG images usually don't have any natural
default size, it should be provided when creating the bundle. default size, it should be provided when creating the bundle.
*/ */
static wxBitmapBundle FromSVG(char* data, const wxSize sizeDef); static wxBitmapBundle FromSVG(char* data, const wxSize sizeDef);
/// @overload
static wxBitmapBundle FromSVG(const char* data, const wxSize sizeDef);
/** /**
Check if bitmap bundle is non-empty. Check if bitmap bundle is non-empty.

View File

@@ -75,7 +75,7 @@
// Real SVGs would typically be loaded from files, but to keep things as simple // Real SVGs would typically be loaded from files, but to keep things as simple
// as possible here, we embed this one directly in the program text. // as possible here, we embed this one directly in the program text.
static char svg_data[] = static const char svg_data[] =
"<svg version=\"1.1\" viewBox=\"0.0 0.0 360.0 360.0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns=\"http://www.w3.org/2000/svg\">" "<svg version=\"1.1\" viewBox=\"0.0 0.0 360.0 360.0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns=\"http://www.w3.org/2000/svg\">"
"<g>" "<g>"
"<path stroke=\"#000000\" fill=\"#ff0000\" d=\"m 10 170 c0 -12 10 -24 24 -24 l100 0 c6 0 12 2 17 7 c4 4 7 10 7 17 l0 100 c0 12 -10 24 -24 24 l-100 0c-12 0 -24 -10 -24 -24 z\"/>" "<path stroke=\"#000000\" fill=\"#ff0000\" d=\"m 10 170 c0 -12 10 -24 24 -24 l100 0 c6 0 12 2 17 7 c4 4 7 10 7 17 l0 100 c0 12 -10 24 -24 24 l-100 0c-12 0 -24 -10 -24 -24 z\"/>"

View File

@@ -172,4 +172,12 @@ wxBitmapBundle wxBitmapBundle::FromSVG(char* data, const wxSize sizeDef)
return wxBitmapBundle(new wxBitmapBundleImplSVG(svgImage, sizeDef)); return wxBitmapBundle(new wxBitmapBundleImplSVG(svgImage, sizeDef));
} }
/* static */
wxBitmapBundle wxBitmapBundle::FromSVG(const char* data, const wxSize sizeDef)
{
wxCharBuffer copy(data);
return FromSVG(copy.data(), sizeDef);
}
#endif // wxHAS_RAW_BITMAP #endif // wxHAS_RAW_BITMAP

View File

@@ -61,8 +61,7 @@ TEST_CASE("BitmapBundle::FromSVG", "[bmpbundle][svg]")
"</svg>" "</svg>"
; ;
wxCharBuffer buf(svg_data); wxBitmapBundle b = wxBitmapBundle::FromSVG(svg_data, wxSize(20, 20));
wxBitmapBundle b = wxBitmapBundle::FromSVG(buf.data(), wxSize(20, 20));
REQUIRE( b.IsOk() ); REQUIRE( b.IsOk() );
CHECK( b.GetDefaultSize() == wxSize(20, 20) ); CHECK( b.GetDefaultSize() == wxSize(20, 20) );
@@ -72,8 +71,7 @@ TEST_CASE("BitmapBundle::FromSVG", "[bmpbundle][svg]")
const char* svg_tag_start = strstr(svg_data, "<svg"); const char* svg_tag_start = strstr(svg_data, "<svg");
REQUIRE( svg_tag_start ); REQUIRE( svg_tag_start );
buf = wxCharBuffer(svg_data); b = wxBitmapBundle::FromSVG(svg_data, wxSize(20, 20));
b = wxBitmapBundle::FromSVG(buf.data(), wxSize(20, 20));
REQUIRE( b.IsOk() ); REQUIRE( b.IsOk() );
CHECK( b.GetBitmap(wxSize(16, 16)).GetSize() == wxSize(16, 16) ); CHECK( b.GetBitmap(wxSize(16, 16)).GetSize() == wxSize(16, 16) );
} }