From ac02ae877fecad23a88854da4b93c9ebdb08252a Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 28 Sep 2021 18:03:55 +0100 Subject: [PATCH] Add simple wxBitmapBundle::FromSVG() implementation using NanoSVG Add nanosvg submodule and use it in the generic implementation of this function. This is incomplete yet and, notably, doesn't cache the rasterized images, but already shows that using SVG images works (at least in the toolbar sample). --- .gitmodules | 4 + 3rdparty/nanosvg | 1 + Makefile.in | 36 +++++-- build/bakefiles/files.bkl | 1 + build/cmake/files.cmake | 1 + build/files | 1 + build/msw/makefile.gcc | 44 +++++++-- build/msw/makefile.vc | 44 +++++++-- build/msw/wx_core.vcxproj | 1 + build/msw/wx_core.vcxproj.filters | 3 + build/msw/wx_vc8_core.vcproj | 4 + build/msw/wx_vc9_core.vcproj | 4 + include/wx/bmpbndl.h | 10 ++ interface/wx/bmpbndl.h | 29 ++++++ samples/toolbar/toolbar.cpp | 24 ++++- src/generic/bmpsvg.cpp | 156 ++++++++++++++++++++++++++++++ tests/graphics/bmpbundle.cpp | 33 +++++++ 17 files changed, 369 insertions(+), 27 deletions(-) create mode 160000 3rdparty/nanosvg create mode 100644 src/generic/bmpsvg.cpp diff --git a/.gitmodules b/.gitmodules index cd26719f6e..eccca68800 100644 --- a/.gitmodules +++ b/.gitmodules @@ -26,3 +26,7 @@ path = 3rdparty/pcre url = https://github.com/wxWidgets/pcre branch = wx +[submodule "3rdparty/nanosvg"] + path = 3rdparty/nanosvg + url = https://github.com/wxWidgets/nanosvg + branch = wx diff --git a/3rdparty/nanosvg b/3rdparty/nanosvg new file mode 160000 index 0000000000..ccdb199513 --- /dev/null +++ b/3rdparty/nanosvg @@ -0,0 +1 @@ +Subproject commit ccdb1995134d340a93fb20e3a3d323ccb3838dd0 diff --git a/Makefile.in b/Makefile.in index 40586a21e1..e2790da9dd 100644 --- a/Makefile.in +++ b/Makefile.in @@ -4711,7 +4711,8 @@ COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS = \ monodll_calctrlg.o \ monodll_creddlgg.o \ monodll_rowheightcache.o \ - monodll_common_bmpbndl.o + monodll_common_bmpbndl.o \ + monodll_bmpsvg.o @COND_USE_GUI_1_WXUNIV_0@__CORE_SRC_OBJECTS = $(COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS) COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS = \ $(__LOWLEVEL_SRC_OBJECTS_1) \ @@ -4974,7 +4975,8 @@ COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS = \ monodll_calctrlg.o \ monodll_creddlgg.o \ monodll_rowheightcache.o \ - monodll_common_bmpbndl.o + monodll_common_bmpbndl.o \ + monodll_bmpsvg.o @COND_USE_GUI_1_WXUNIV_1@__CORE_SRC_OBJECTS = $(COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS) COND_TOOLKIT_DFB___LOWLEVEL_SRC_OBJECTS = \ monodll_fontmgrcmn.o \ @@ -6711,7 +6713,8 @@ COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS_1 = \ monolib_calctrlg.o \ monolib_creddlgg.o \ monolib_rowheightcache.o \ - monolib_common_bmpbndl.o + monolib_common_bmpbndl.o \ + monolib_bmpsvg.o @COND_USE_GUI_1_WXUNIV_0@__CORE_SRC_OBJECTS_1 = $(COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS_1) COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_1 = \ $(__LOWLEVEL_SRC_OBJECTS_3) \ @@ -6974,7 +6977,8 @@ COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_1 = \ monolib_calctrlg.o \ monolib_creddlgg.o \ monolib_rowheightcache.o \ - monolib_common_bmpbndl.o + monolib_common_bmpbndl.o \ + monolib_bmpsvg.o @COND_USE_GUI_1_WXUNIV_1@__CORE_SRC_OBJECTS_1 = $(COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_1) COND_TOOLKIT_DFB___LOWLEVEL_SRC_OBJECTS_2 = \ monolib_fontmgrcmn.o \ @@ -8864,7 +8868,8 @@ COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS_2 = \ coredll_calctrlg.o \ coredll_creddlgg.o \ coredll_rowheightcache.o \ - coredll_common_bmpbndl.o + coredll_common_bmpbndl.o \ + coredll_bmpsvg.o @COND_USE_GUI_1_WXUNIV_0@__CORE_SRC_OBJECTS_2 = $(COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS_2) COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_2 = \ $(__LOWLEVEL_SRC_OBJECTS_5) \ @@ -9127,7 +9132,8 @@ COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_2 = \ coredll_calctrlg.o \ coredll_creddlgg.o \ coredll_rowheightcache.o \ - coredll_common_bmpbndl.o + coredll_common_bmpbndl.o \ + coredll_bmpsvg.o @COND_USE_GUI_1_WXUNIV_1@__CORE_SRC_OBJECTS_2 = $(COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_2) COND_TOOLKIT_DFB___LOWLEVEL_SRC_OBJECTS_4 = \ coredll_fontmgrcmn.o \ @@ -10593,7 +10599,8 @@ COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS_3 = \ corelib_calctrlg.o \ corelib_creddlgg.o \ corelib_rowheightcache.o \ - corelib_common_bmpbndl.o + corelib_common_bmpbndl.o \ + corelib_bmpsvg.o @COND_USE_GUI_1_WXUNIV_0@__CORE_SRC_OBJECTS_3 = $(COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS_3) COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_3 = \ $(__LOWLEVEL_SRC_OBJECTS_7) \ @@ -10856,7 +10863,8 @@ COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_3 = \ corelib_calctrlg.o \ corelib_creddlgg.o \ corelib_rowheightcache.o \ - corelib_common_bmpbndl.o + corelib_common_bmpbndl.o \ + corelib_bmpsvg.o @COND_USE_GUI_1_WXUNIV_1@__CORE_SRC_OBJECTS_3 = $(COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_3) COND_TOOLKIT_DFB___LOWLEVEL_SRC_OBJECTS_6 = \ corelib_fontmgrcmn.o \ @@ -21047,6 +21055,9 @@ monodll_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONODLL_ODEP) @COND_USE_GUI_1@monodll_common_bmpbndl.o: $(srcdir)/src/common/bmpbndl.cpp $(MONODLL_ODEP) @COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/common/bmpbndl.cpp +@COND_USE_GUI_1@monodll_bmpsvg.o: $(srcdir)/src/generic/bmpsvg.cpp $(MONODLL_ODEP) +@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/generic/bmpsvg.cpp + @COND_TOOLKIT_OSX_COCOA_USE_GUI_1@monodll_osx_cocoa_mediactrl.o: $(srcdir)/src/osx/cocoa/mediactrl.mm $(MONODLL_ODEP) @COND_TOOLKIT_OSX_COCOA_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_OBJCXXFLAGS) $(srcdir)/src/osx/cocoa/mediactrl.mm @@ -26348,6 +26359,9 @@ monolib_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONOLIB_ODEP) @COND_USE_GUI_1@monolib_common_bmpbndl.o: $(srcdir)/src/common/bmpbndl.cpp $(MONOLIB_ODEP) @COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/common/bmpbndl.cpp +@COND_USE_GUI_1@monolib_bmpsvg.o: $(srcdir)/src/generic/bmpsvg.cpp $(MONOLIB_ODEP) +@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/generic/bmpsvg.cpp + @COND_TOOLKIT_OSX_COCOA_USE_GUI_1@monolib_osx_cocoa_mediactrl.o: $(srcdir)/src/osx/cocoa/mediactrl.mm $(MONOLIB_ODEP) @COND_TOOLKIT_OSX_COCOA_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_OBJCXXFLAGS) $(srcdir)/src/osx/cocoa/mediactrl.mm @@ -31754,6 +31768,9 @@ coredll_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(COREDLL_ODEP) @COND_USE_GUI_1@coredll_common_bmpbndl.o: $(srcdir)/src/common/bmpbndl.cpp $(COREDLL_ODEP) @COND_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/common/bmpbndl.cpp +@COND_USE_GUI_1@coredll_bmpsvg.o: $(srcdir)/src/generic/bmpsvg.cpp $(COREDLL_ODEP) +@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/generic/bmpsvg.cpp + corelib_event.o: $(srcdir)/src/common/event.cpp $(CORELIB_ODEP) $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/common/event.cpp @@ -36020,6 +36037,9 @@ corelib_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(CORELIB_ODEP) @COND_USE_GUI_1@corelib_common_bmpbndl.o: $(srcdir)/src/common/bmpbndl.cpp $(CORELIB_ODEP) @COND_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/common/bmpbndl.cpp +@COND_USE_GUI_1@corelib_bmpsvg.o: $(srcdir)/src/generic/bmpsvg.cpp $(CORELIB_ODEP) +@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/generic/bmpsvg.cpp + advdll_version_rc.o: $(srcdir)/src/msw/version.rc $(ADVDLL_ODEP) $(WINDRES) -i$< -o$@ $(__INC_TIFF_BUILD_p_54) $(__INC_TIFF_p_54) $(__INC_JPEG_p_54) $(__INC_PNG_p_53) $(__INC_ZLIB_p_67) $(__INC_REGEX_p_65) $(__INC_EXPAT_p_65) --define __WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p_66) $(__DEBUG_DEFINE_p_66) $(__EXCEPTIONS_DEFINE_p_65) $(__RTTI_DEFINE_p_65) $(__THREAD_DEFINE_p_65) --define WXBUILDING --define WXDLLNAME=$(WXDLLNAMEPREFIXGUI)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_adv$(WXCOMPILER)$(VENDORTAG)$(WXDLLVERSIONTAG) $(__RCDEFDIR_p) --include-dir $(top_srcdir)/include --define WXUSINGDLL --define WXMAKINGDLL_ADV diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index 4972cc72f4..4652c90077 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -1016,6 +1016,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! src/generic/creddlgg.cpp src/generic/rowheightcache.cpp src/common/bmpbndl.cpp + src/generic/bmpsvg.cpp wx/affinematrix2dbase.h diff --git a/build/cmake/files.cmake b/build/cmake/files.cmake index 032091d0de..e15621a957 100644 --- a/build/cmake/files.cmake +++ b/build/cmake/files.cmake @@ -919,6 +919,7 @@ set(GUI_CMN_SRC src/generic/rowheightcache.cpp src/generic/animateg.cpp src/common/bmpbndl.cpp + src/generic/bmpsvg.cpp ) set(GUI_CMN_HDR diff --git a/build/files b/build/files index 2112c0f6be..01cd181731 100644 --- a/build/files +++ b/build/files @@ -872,6 +872,7 @@ GUI_CMN_SRC = src/generic/animateg.cpp src/generic/bannerwindow.cpp src/generic/bmpcboxg.cpp + src/generic/bmpsvg.cpp src/generic/busyinfo.cpp src/generic/buttonbar.cpp src/generic/calctrlg.cpp diff --git a/build/msw/makefile.gcc b/build/msw/makefile.gcc index 8eda39d271..e590bc8161 100644 --- a/build/msw/makefile.gcc +++ b/build/msw/makefile.gcc @@ -2203,7 +2203,8 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_calctrlg.o \ $(OBJS)\monodll_creddlgg.o \ $(OBJS)\monodll_rowheightcache.o \ - $(OBJS)\monodll_common_bmpbndl.o + $(OBJS)\monodll_common_bmpbndl.o \ + $(OBJS)\monodll_bmpsvg.o endif endif ifeq ($(USE_GUI),1) @@ -2535,7 +2536,8 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_calctrlg.o \ $(OBJS)\monodll_creddlgg.o \ $(OBJS)\monodll_rowheightcache.o \ - $(OBJS)\monodll_common_bmpbndl.o + $(OBJS)\monodll_common_bmpbndl.o \ + $(OBJS)\monodll_bmpsvg.o endif endif ifeq ($(USE_STC),1) @@ -3049,7 +3051,8 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_calctrlg.o \ $(OBJS)\monolib_creddlgg.o \ $(OBJS)\monolib_rowheightcache.o \ - $(OBJS)\monolib_common_bmpbndl.o + $(OBJS)\monolib_common_bmpbndl.o \ + $(OBJS)\monolib_bmpsvg.o endif endif ifeq ($(USE_GUI),1) @@ -3381,7 +3384,8 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_calctrlg.o \ $(OBJS)\monolib_creddlgg.o \ $(OBJS)\monolib_rowheightcache.o \ - $(OBJS)\monolib_common_bmpbndl.o + $(OBJS)\monolib_common_bmpbndl.o \ + $(OBJS)\monolib_bmpsvg.o endif endif ifeq ($(USE_STC),1) @@ -3778,7 +3782,8 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_calctrlg.o \ $(OBJS)\coredll_creddlgg.o \ $(OBJS)\coredll_rowheightcache.o \ - $(OBJS)\coredll_common_bmpbndl.o + $(OBJS)\coredll_common_bmpbndl.o \ + $(OBJS)\coredll_bmpsvg.o endif endif ifeq ($(USE_GUI),1) @@ -4110,7 +4115,8 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_calctrlg.o \ $(OBJS)\coredll_creddlgg.o \ $(OBJS)\coredll_rowheightcache.o \ - $(OBJS)\coredll_common_bmpbndl.o + $(OBJS)\coredll_common_bmpbndl.o \ + $(OBJS)\coredll_bmpsvg.o endif endif ifeq ($(MONOLITHIC),0) @@ -4465,7 +4471,8 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_calctrlg.o \ $(OBJS)\corelib_creddlgg.o \ $(OBJS)\corelib_rowheightcache.o \ - $(OBJS)\corelib_common_bmpbndl.o + $(OBJS)\corelib_common_bmpbndl.o \ + $(OBJS)\corelib_bmpsvg.o endif endif ifeq ($(USE_GUI),1) @@ -4797,7 +4804,8 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_calctrlg.o \ $(OBJS)\corelib_creddlgg.o \ $(OBJS)\corelib_rowheightcache.o \ - $(OBJS)\corelib_common_bmpbndl.o + $(OBJS)\corelib_common_bmpbndl.o \ + $(OBJS)\corelib_bmpsvg.o endif endif ifeq ($(SHARED),1) @@ -9482,6 +9490,11 @@ $(OBJS)\monodll_common_bmpbndl.o: ../../src/common/bmpbndl.cpp $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< endif +ifeq ($(USE_GUI),1) +$(OBJS)\monodll_bmpsvg.o: ../../src/generic/bmpsvg.cpp + $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< +endif + $(OBJS)\monodll_version_rc.o: ../../src/msw/version.rc $(WINDRES) -i$< -o$@ --include-dir ../../src/tiff/libtiff --include-dir ../../src/jpeg --include-dir ../../src/png --include-dir ../../src/zlib --include-dir ../../3rdparty/pcre/src/wx --include-dir ../../src/expat/expat/lib --define __WXMSW__ $(__WXUNIV_DEFINE_p_66) $(__DEBUG_DEFINE_p_66) $(__NDEBUG_DEFINE_p_65) $(__EXCEPTIONS_DEFINE_p_65) $(__RTTI_DEFINE_p_65) $(__THREAD_DEFINE_p_65) $(__UNICODE_DEFINE_p_67) --include-dir $(SETUPHDIR) --include-dir ../../include $(__CAIRO_INCLUDEDIR_p) --define WXBUILDING --define WXDLLNAME=wx$(PORTNAME)$(WXUNIVNAME)$(WX_VERSION_NODOT)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)$(WXCOMPILER)$(VENDORTAG) --include-dir ../../src/stc/scintilla/include --include-dir ../../src/stc/scintilla/lexlib --include-dir ../../src/stc/scintilla/src --define __WX__ --define SCI_LEXER --define NO_CXX11_REGEX --define LINK_LEXERS --define wxUSE_BASE=1 --define WXMAKINGDLL @@ -12066,6 +12079,11 @@ $(OBJS)\monolib_common_bmpbndl.o: ../../src/common/bmpbndl.cpp $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< endif +ifeq ($(USE_GUI),1) +$(OBJS)\monolib_bmpsvg.o: ../../src/generic/bmpsvg.cpp + $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< +endif + $(OBJS)\basedll_dummy.o: ../../src/common/dummy.cpp $(CXX) -c -o $@ $(BASEDLL_CXXFLAGS) $(CPPDEPS) $< @@ -14623,6 +14641,11 @@ $(OBJS)\coredll_common_bmpbndl.o: ../../src/common/bmpbndl.cpp $(CXX) -c -o $@ $(COREDLL_CXXFLAGS) $(CPPDEPS) $< endif +ifeq ($(USE_GUI),1) +$(OBJS)\coredll_bmpsvg.o: ../../src/generic/bmpsvg.cpp + $(CXX) -c -o $@ $(COREDLL_CXXFLAGS) $(CPPDEPS) $< +endif + $(OBJS)\corelib_dummy.o: ../../src/common/dummy.cpp $(CXX) -c -o $@ $(CORELIB_CXXFLAGS) $(CPPDEPS) $< @@ -16373,6 +16396,11 @@ $(OBJS)\corelib_common_bmpbndl.o: ../../src/common/bmpbndl.cpp $(CXX) -c -o $@ $(CORELIB_CXXFLAGS) $(CPPDEPS) $< endif +ifeq ($(USE_GUI),1) +$(OBJS)\corelib_bmpsvg.o: ../../src/generic/bmpsvg.cpp + $(CXX) -c -o $@ $(CORELIB_CXXFLAGS) $(CPPDEPS) $< +endif + $(OBJS)\advdll_dummy.o: ../../src/common/dummy.cpp $(CXX) -c -o $@ $(ADVDLL_CXXFLAGS) $(CPPDEPS) $< diff --git a/build/msw/makefile.vc b/build/msw/makefile.vc index 76456b188c..e7b8a7b9a1 100644 --- a/build/msw/makefile.vc +++ b/build/msw/makefile.vc @@ -2533,7 +2533,8 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_calctrlg.obj \ $(OBJS)\monodll_creddlgg.obj \ $(OBJS)\monodll_rowheightcache.obj \ - $(OBJS)\monodll_common_bmpbndl.obj + $(OBJS)\monodll_common_bmpbndl.obj \ + $(OBJS)\monodll_bmpsvg.obj !endif !if "$(USE_GUI)" == "1" && "$(WXUNIV)" == "1" ____CORE_SRC_FILENAMES_OBJECTS = \ @@ -2863,7 +2864,8 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_calctrlg.obj \ $(OBJS)\monodll_creddlgg.obj \ $(OBJS)\monodll_rowheightcache.obj \ - $(OBJS)\monodll_common_bmpbndl.obj + $(OBJS)\monodll_common_bmpbndl.obj \ + $(OBJS)\monodll_bmpsvg.obj !endif !if "$(USE_STC)" == "1" ____MONOLIB_STC_SRC_FILENAMES_OBJECTS = \ @@ -3379,7 +3381,8 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_calctrlg.obj \ $(OBJS)\monolib_creddlgg.obj \ $(OBJS)\monolib_rowheightcache.obj \ - $(OBJS)\monolib_common_bmpbndl.obj + $(OBJS)\monolib_common_bmpbndl.obj \ + $(OBJS)\monolib_bmpsvg.obj !endif !if "$(USE_GUI)" == "1" && "$(WXUNIV)" == "1" ____CORE_SRC_FILENAMES_1_OBJECTS = \ @@ -3709,7 +3712,8 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_calctrlg.obj \ $(OBJS)\monolib_creddlgg.obj \ $(OBJS)\monolib_rowheightcache.obj \ - $(OBJS)\monolib_common_bmpbndl.obj + $(OBJS)\monolib_common_bmpbndl.obj \ + $(OBJS)\monolib_bmpsvg.obj !endif !if "$(USE_STC)" == "1" ____MONOLIB_STC_SRC_FILENAMES_1_OBJECTS = \ @@ -4158,7 +4162,8 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_calctrlg.obj \ $(OBJS)\coredll_creddlgg.obj \ $(OBJS)\coredll_rowheightcache.obj \ - $(OBJS)\coredll_common_bmpbndl.obj + $(OBJS)\coredll_common_bmpbndl.obj \ + $(OBJS)\coredll_bmpsvg.obj !endif !if "$(USE_GUI)" == "1" && "$(WXUNIV)" == "1" ____CORE_SRC_FILENAMES_2_OBJECTS = \ @@ -4488,7 +4493,8 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_calctrlg.obj \ $(OBJS)\coredll_creddlgg.obj \ $(OBJS)\coredll_rowheightcache.obj \ - $(OBJS)\coredll_common_bmpbndl.obj + $(OBJS)\coredll_common_bmpbndl.obj \ + $(OBJS)\coredll_bmpsvg.obj !endif !if "$(MONOLITHIC)" == "0" && "$(SHARED)" == "0" && "$(USE_GUI)" == "1" __corelib___depname = \ @@ -4843,7 +4849,8 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_calctrlg.obj \ $(OBJS)\corelib_creddlgg.obj \ $(OBJS)\corelib_rowheightcache.obj \ - $(OBJS)\corelib_common_bmpbndl.obj + $(OBJS)\corelib_common_bmpbndl.obj \ + $(OBJS)\corelib_bmpsvg.obj !endif !if "$(USE_GUI)" == "1" && "$(WXUNIV)" == "1" ____CORE_SRC_FILENAMES_3_OBJECTS = \ @@ -5173,7 +5180,8 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_calctrlg.obj \ $(OBJS)\corelib_creddlgg.obj \ $(OBJS)\corelib_rowheightcache.obj \ - $(OBJS)\corelib_common_bmpbndl.obj + $(OBJS)\corelib_common_bmpbndl.obj \ + $(OBJS)\corelib_bmpsvg.obj !endif !if "$(SHARED)" == "1" ____wxcore_namedll_DEP = $(__coredll___depname) @@ -9913,6 +9921,11 @@ $(OBJS)\monodll_common_bmpbndl.obj: ..\..\src\common\bmpbndl.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\common\bmpbndl.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\monodll_bmpsvg.obj: ..\..\src\generic\bmpsvg.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\generic\bmpsvg.cpp +!endif + $(OBJS)\monodll_version.res: ..\..\src\msw\version.rc rc /fo$@ /d WIN32 /i ..\..\src\tiff\libtiff /i ..\..\src\jpeg /i ..\..\src\png /i ..\..\src\zlib /i ..\..\3rdparty\pcre\src\wx /i ..\..\src\expat\expat\lib $(____DEBUGRUNTIME_6) /d _CRT_SECURE_NO_DEPRECATE=1 /d _CRT_NON_CONFORMING_SWPRINTFS=1 /d _SCL_SECURE_NO_WARNINGS=1 $(__NO_VC_CRTDBG_p_72) $(__TARGET_CPU_COMPFLAG_p_72) /d __WXMSW__ $(__WXUNIV_DEFINE_p_66) $(__DEBUG_DEFINE_p_66) $(__NDEBUG_DEFINE_p_65) $(__EXCEPTIONS_DEFINE_p_65) $(__RTTI_DEFINE_p_65) $(__THREAD_DEFINE_p_65) $(__UNICODE_DEFINE_p_67) /i $(SETUPHDIR) /i ..\..\include $(____CAIRO_INCLUDEDIR_FILENAMES_4) /d WXBUILDING /d WXDLLNAME=wx$(PORTNAME)$(WXUNIVNAME)$(WX_VERSION_NODOT)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)$(WXCOMPILER)$(VENDORTAG) /i ..\..\src\stc\scintilla\include /i ..\..\src\stc\scintilla\lexlib /i ..\..\src\stc\scintilla\src /d __WX__ /d SCI_LEXER /d NO_CXX11_REGEX /d LINK_LEXERS /d wxUSE_BASE=1 /d WXMAKINGDLL ..\..\src\msw\version.rc @@ -12497,6 +12510,11 @@ $(OBJS)\monolib_common_bmpbndl.obj: ..\..\src\common\bmpbndl.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\common\bmpbndl.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\monolib_bmpsvg.obj: ..\..\src\generic\bmpsvg.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\generic\bmpsvg.cpp +!endif + $(OBJS)\basedll_dummy.obj: ..\..\src\common\dummy.cpp $(CXX) /c /nologo /TP /Fo$@ $(BASEDLL_CXXFLAGS) /Ycwx/wxprec.h ..\..\src\common\dummy.cpp @@ -15054,6 +15072,11 @@ $(OBJS)\coredll_common_bmpbndl.obj: ..\..\src\common\bmpbndl.cpp $(CXX) /c /nologo /TP /Fo$@ $(COREDLL_CXXFLAGS) ..\..\src\common\bmpbndl.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\coredll_bmpsvg.obj: ..\..\src\generic\bmpsvg.cpp + $(CXX) /c /nologo /TP /Fo$@ $(COREDLL_CXXFLAGS) ..\..\src\generic\bmpsvg.cpp +!endif + $(OBJS)\corelib_dummy.obj: ..\..\src\common\dummy.cpp $(CXX) /c /nologo /TP /Fo$@ $(CORELIB_CXXFLAGS) /Ycwx/wxprec.h ..\..\src\common\dummy.cpp @@ -16804,6 +16827,11 @@ $(OBJS)\corelib_common_bmpbndl.obj: ..\..\src\common\bmpbndl.cpp $(CXX) /c /nologo /TP /Fo$@ $(CORELIB_CXXFLAGS) ..\..\src\common\bmpbndl.cpp !endif +!if "$(USE_GUI)" == "1" +$(OBJS)\corelib_bmpsvg.obj: ..\..\src\generic\bmpsvg.cpp + $(CXX) /c /nologo /TP /Fo$@ $(CORELIB_CXXFLAGS) ..\..\src\generic\bmpsvg.cpp +!endif + $(OBJS)\advdll_dummy.obj: ..\..\src\common\dummy.cpp $(CXX) /c /nologo /TP /Fo$@ $(ADVDLL_CXXFLAGS) /Ycwx/wxprec.h ..\..\src\common\dummy.cpp diff --git a/build/msw/wx_core.vcxproj b/build/msw/wx_core.vcxproj index 6a396f1fc0..36eb3274d4 100644 --- a/build/msw/wx_core.vcxproj +++ b/build/msw/wx_core.vcxproj @@ -592,6 +592,7 @@ + $(IntDir)msw_%(Filename).obj diff --git a/build/msw/wx_core.vcxproj.filters b/build/msw/wx_core.vcxproj.filters index f6e858df48..60190f8aa9 100644 --- a/build/msw/wx_core.vcxproj.filters +++ b/build/msw/wx_core.vcxproj.filters @@ -1074,6 +1074,9 @@ MSW Sources + + Generic Sources + diff --git a/build/msw/wx_vc8_core.vcproj b/build/msw/wx_vc8_core.vcproj index 5673f9fe19..1455ea33ce 100644 --- a/build/msw/wx_vc8_core.vcproj +++ b/build/msw/wx_vc8_core.vcproj @@ -2087,6 +2087,10 @@ RelativePath="..\..\src\generic\bmpcboxg.cpp" > + + diff --git a/build/msw/wx_vc9_core.vcproj b/build/msw/wx_vc9_core.vcproj index fa37b4e5f4..0a0da78478 100644 --- a/build/msw/wx_vc9_core.vcproj +++ b/build/msw/wx_vc9_core.vcproj @@ -2083,6 +2083,10 @@ RelativePath="..\..\src\generic\bmpcboxg.cpp" > + + diff --git a/include/wx/bmpbndl.h b/include/wx/bmpbndl.h index 924b99bcf5..b73d192056 100644 --- a/include/wx/bmpbndl.h +++ b/include/wx/bmpbndl.h @@ -59,6 +59,16 @@ public: static wxBitmapBundle FromBitmap(const wxBitmap& bitmap); static wxBitmapBundle FromImage(const wxImage& image); + // It should be possible to implement SVG rasterizing without raw bitmap + // support using wxDC::DrawSpline(), but currently we don't do it and so + // FromSVG() is only available in the ports providing raw bitmap access. +#ifdef wxHAS_RAW_BITMAP + // Create from the SVG data (data is supposed to be in UTF-8 encoding). + // Notice that the data here is non-const because it can be temporarily + // modified while parsing it. + static wxBitmapBundle FromSVG(char* data, const wxSize sizeDef); +#endif // wxHAS_RAW_BITMAP + // Create from the resources: all existing versions of the bitmap of the // form name_2x or name@2x (and also using other factors) will be used. static wxBitmapBundle FromResources(const wxString& name); diff --git a/interface/wx/bmpbndl.h b/interface/wx/bmpbndl.h index 8f28a630dc..4d4b22c893 100644 --- a/interface/wx/bmpbndl.h +++ b/interface/wx/bmpbndl.h @@ -176,6 +176,35 @@ public: */ static wxBitmapBundle FromResources(const wxString& name); + /** + Create a bundle from the SVG image. + + Please note that the current implementation uses NanoSVG library + (https://github.com/memononen/nanosvg) for parsing and rasterizing SVG + images which imposes the following limitations: + + - Text elements are not supported at all. + - SVG 1.1 filters are not supported. + + These limitations will be relaxed in the future wxWidgets versions. + + Please also note that this method is only available in the ports + providing raw bitmap access via wxPixelData and so defining + wxHAS_RAW_BITMAP symbol. Currently SVG images are not supported in the + ports without it, e.g. wxX11. + + @param data This data may, or not, have the XML document preamble, i.e. + it can start either with @c "" +"" +"" +"" +"" +"" +"" +; + enum Positions { TOOLBAR_LEFT, @@ -231,14 +243,14 @@ enum // event tables // ---------------------------------------------------------------------------- -// Notice that wxID_HELP will be processed for the 'About' menu and the toolbar +// Notice that wxID_ABOUT will be processed for the 'About' menu and the toolbar // help button. wxBEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_SIZE(MyFrame::OnSize) EVT_MENU(wxID_EXIT, MyFrame::OnQuit) - EVT_MENU(wxID_HELP, MyFrame::OnAbout) + EVT_MENU(wxID_ABOUT, MyFrame::OnAbout) EVT_MENU(IDM_TOOLBAR_TOGGLE_TOOLBAR, MyFrame::OnToggleToolbar) EVT_MENU(IDM_TOOLBAR_TOGGLE_ANOTHER_TOOLBAR, MyFrame::OnToggleAnotherToolbar) @@ -378,6 +390,7 @@ void MyFrame::PopulateToolbar(wxToolBarBase* toolBar) Tool_paste, Tool_print, Tool_help, + Tool_about, Tool_Max }; @@ -408,6 +421,9 @@ void MyFrame::PopulateToolbar(wxToolBarBase* toolBar) const wxSize sizeBitmap = toolBarBitmaps[Tool_new].GetDefaultSize() * (m_smallToolbar ? 1 : 2); + // Use vector SVG image for this button for demonstration purposes. + toolBarBitmaps[Tool_about] = wxBitmapBundle::FromSVG(svg_data, sizeBitmap); + // Note that there is no need for FromDIP() here, wxMSW will adjust the // size on its own and under the other platforms there is no need for // scaling the coordinates anyhow. @@ -479,6 +495,8 @@ void MyFrame::PopulateToolbar(wxToolBarBase* toolBar) toolBar->AddStretchableSpace(); toolBar->AddTool(wxID_HELP, "Help", toolBarBitmaps[Tool_help], "Help button", wxITEM_CHECK); + toolBar->AddTool(wxID_ABOUT, "About", toolBarBitmaps[Tool_about], "About"); + if ( !m_pathBmp.empty() ) { // create a tool with a custom bitmap for testing @@ -601,7 +619,7 @@ MyFrame::MyFrame() fileMenu->Append(wxID_EXIT, "E&xit\tAlt-X", "Quit toolbar sample" ); wxMenu *helpMenu = new wxMenu; - helpMenu->Append(wxID_HELP, "&About", "About toolbar sample"); + helpMenu->Append(wxID_ABOUT, "&About", "About toolbar sample"); wxMenuBar* menuBar = new wxMenuBar( wxMB_DOCKABLE ); diff --git a/src/generic/bmpsvg.cpp b/src/generic/bmpsvg.cpp new file mode 100644 index 0000000000..7f5198b082 --- /dev/null +++ b/src/generic/bmpsvg.cpp @@ -0,0 +1,156 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: src/generic/bmpsvg.cpp +// Purpose: Generic wxBitmapBundle::FromSVG() implementation +// Author: Vadim Zeitlin, Gunter Königsmann +// Created: 2021-09-28 +// Copyright: (c) 2019 Gunter Königsmann +// (c) 2021 Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +// for compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef wxHAS_RAW_BITMAP + +#ifndef WX_PRECOMP + #include "wx/utils.h" // Only for wxMin() +#endif // WX_PRECOMP + +#include "wx/bmpbndl.h" +#include "wx/rawbmp.h" + +#include "wx/private/bmpbndl.h" + +// Disable some warnings inside NanoSVG code that we're not interested in. +#ifdef __VISUALC__ + #pragma warning(push) + #pragma warning(disable:4456) + #pragma warning(disable:4702) + + // Also make nanosvg.h compile with older MSVC versions which didn't have + // strtoll(). + #if _MSC_VER < 1800 + #define strtoll _strtoi64 + #endif +#endif + +#define NANOSVG_IMPLEMENTATION +#define NANOSVGRAST_IMPLEMENTATION +#include "../../3rdparty/nanosvg/src/nanosvg.h" +#include "../../3rdparty/nanosvg/src/nanosvgrast.h" + +#ifdef __VISUALC__ + #pragma warning(pop) +#endif + +// ---------------------------------------------------------------------------- +// private helpers +// ---------------------------------------------------------------------------- + +namespace +{ + +class wxBitmapBundleImplSVG : public wxBitmapBundleImpl +{ +public: + // Ctor must be passed a valid NSVGimage and takes ownership of it. + wxBitmapBundleImplSVG(NSVGimage* svgImage, const wxSize& sizeDef) + : m_svgImage(svgImage), + m_svgRasterizer(nsvgCreateRasterizer()), + m_sizeDef(sizeDef) + { + } + + ~wxBitmapBundleImplSVG() + { + nsvgDeleteRasterizer(m_svgRasterizer); + nsvgDelete(m_svgImage); + } + + virtual wxSize GetDefaultSize() const wxOVERRIDE; + virtual wxBitmap GetBitmap(const wxSize size) wxOVERRIDE; + +private: + NSVGimage* const m_svgImage; + NSVGrasterizer* const m_svgRasterizer; + + const wxSize m_sizeDef; + + wxDECLARE_NO_COPY_CLASS(wxBitmapBundleImplSVG); +}; + +} // anonymous namespace + +// ============================================================================ +// wxBitmapBundleImplSVG implementation +// ============================================================================ + +wxSize wxBitmapBundleImplSVG::GetDefaultSize() const +{ + return m_sizeDef; +} + +wxBitmap wxBitmapBundleImplSVG::GetBitmap(const wxSize size) +{ + // TODO: Cache. + + wxVector buffer(size.x*size.y*4); + nsvgRasterize + ( + m_svgRasterizer, + m_svgImage, + 0.0, 0.0, // no offset + wxMin + ( + size.x/m_svgImage->width, + size.y/m_svgImage->height + ), // scale + &buffer[0], + size.x, size.y, + size.x*4 // stride -- we have no gaps between lines + ); + + wxBitmap bitmap(size, 32); + wxAlphaPixelData bmpdata(bitmap); + wxAlphaPixelData::Iterator dst(bmpdata); + + const unsigned char* src = &buffer[0]; + for ( int y = 0; y < size.y; ++y ) + { + dst.MoveTo(bmpdata, 0, y); + for ( int x = 0; x < size.x; ++x ) + { + const unsigned char a = src[3]; + dst.Red() = src[0] * a / 255; + dst.Green() = src[1] * a / 255; + dst.Blue() = src[2] * a / 255; + dst.Alpha() = a; + + ++dst; + src += 4; + } + } + + return bitmap; +} + +/* static */ +wxBitmapBundle wxBitmapBundle::FromSVG(char* data, const wxSize sizeDef) +{ + NSVGimage* const svgImage = nsvgParse(data, "px", 96); + if ( !svgImage ) + return wxBitmapBundle(); + + return wxBitmapBundle(new wxBitmapBundleImplSVG(svgImage, sizeDef)); +} + +#endif // wxHAS_RAW_BITMAP diff --git a/tests/graphics/bmpbundle.cpp b/tests/graphics/bmpbundle.cpp index aa79c4a560..3d0f58eedd 100644 --- a/tests/graphics/bmpbundle.cpp +++ b/tests/graphics/bmpbundle.cpp @@ -46,3 +46,36 @@ TEST_CASE("BitmapBundle::FromBitmaps", "[bmpbundle]") CHECK( b.GetBitmap(wxSize(20, 20)).GetSize() == wxSize(20, 20) ); CHECK( b.GetBitmap(wxSize(24, 24)).GetSize() == wxSize(24, 24) ); } + +#ifdef wxHAS_RAW_BITMAP + +TEST_CASE("BitmapBundle::FromSVG", "[bmpbundle][svg]") +{ + static const char svg_data[] = +"" +"" +"" +"" +"" +"" +"" + ; + + wxCharBuffer buf(svg_data); + wxBitmapBundle b = wxBitmapBundle::FromSVG(buf.data(), wxSize(20, 20)); + REQUIRE( b.IsOk() ); + CHECK( b.GetDefaultSize() == wxSize(20, 20) ); + + CHECK( b.GetBitmap(wxSize(32, 32)).GetSize() == wxSize(32, 32) ); + + // Check that not using XML header works too. + const char* svg_tag_start = strstr(svg_data, "