| @@ -58,7 +58,7 @@ TWidget* createWidgetCentered(math::Vec pos) { | |||||
| inline app::SvgPanel* createPanel(std::string svgPath) { | inline app::SvgPanel* createPanel(std::string svgPath) { | ||||
| app::SvgPanel* panel = new app::SvgPanel; | app::SvgPanel* panel = new app::SvgPanel; | ||||
| std::shared_ptr<Svg> svg = APP->window->loadSvg(svgPath); | |||||
| std::shared_ptr<Svg> svg = Svg::load(svgPath); | |||||
| panel->setBackground(svg); | panel->setBackground(svg); | ||||
| return panel; | return panel; | ||||
| } | } | ||||
| @@ -1,4 +1,6 @@ | |||||
| #pragma once | #pragma once | ||||
| #include <memory> | |||||
| #include <nanovg.h> | #include <nanovg.h> | ||||
| #include <nanosvg.h> | #include <nanosvg.h> | ||||
| @@ -8,6 +10,19 @@ | |||||
| namespace rack { | namespace rack { | ||||
| struct Svg { | |||||
| NSVGimage* handle = NULL; | |||||
| /** Don't call this directly. Use `Svg::load()` for caching. */ | |||||
| void loadFile(const std::string& filename); | |||||
| ~Svg(); | |||||
| /** Loads Svg from a cache. */ | |||||
| static std::shared_ptr<Svg> load(const std::string& filename); | |||||
| }; | |||||
| DEPRECATED typedef Svg SVG; | |||||
| void svgDraw(NVGcontext* vg, NSVGimage* svg); | void svgDraw(NVGcontext* vg, NSVGimage* svg); | ||||
| @@ -12,6 +12,7 @@ | |||||
| #include <nanovg_gl.h> | #include <nanovg_gl.h> | ||||
| #include <nanovg_gl_utils.h> | #include <nanovg_gl_utils.h> | ||||
| #include <nanosvg.h> | #include <nanosvg.h> | ||||
| #include <svg.hpp> | |||||
| #include <common.hpp> | #include <common.hpp> | ||||
| #include <math.hpp> | #include <math.hpp> | ||||
| @@ -42,17 +43,6 @@ struct Image { | |||||
| DEPRECATED static std::shared_ptr<Image> load(const std::string& filename); | DEPRECATED static std::shared_ptr<Image> load(const std::string& filename); | ||||
| }; | }; | ||||
| struct Svg { | |||||
| NSVGimage* handle = NULL; | |||||
| /** Don't call this directly but instead use `APP->window->loadSvg()` */ | |||||
| void loadFile(const std::string& filename); | |||||
| ~Svg(); | |||||
| /** Use `APP->window->loadSvg()` instead. */ | |||||
| DEPRECATED static std::shared_ptr<Svg> load(const std::string& filename); | |||||
| }; | |||||
| DEPRECATED typedef Svg SVG; | |||||
| struct Window { | struct Window { | ||||
| struct Internal; | struct Internal; | ||||
| @@ -71,7 +61,6 @@ struct Window { | |||||
| /** Use load*() instead of modifying these directly. */ | /** Use load*() instead of modifying these directly. */ | ||||
| std::map<std::string, std::weak_ptr<Font>> fontCache; | std::map<std::string, std::weak_ptr<Font>> fontCache; | ||||
| std::map<std::string, std::weak_ptr<Image>> imageCache; | std::map<std::string, std::weak_ptr<Image>> imageCache; | ||||
| std::map<std::string, std::weak_ptr<Svg>> svgCache; | |||||
| Window(); | Window(); | ||||
| ~Window(); | ~Window(); | ||||
| @@ -100,7 +89,11 @@ struct Window { | |||||
| std::shared_ptr<Font> loadFont(const std::string& filename); | std::shared_ptr<Font> loadFont(const std::string& filename); | ||||
| std::shared_ptr<Image> loadImage(const std::string& filename); | std::shared_ptr<Image> loadImage(const std::string& filename); | ||||
| std::shared_ptr<Svg> loadSvg(const std::string& filename); | |||||
| /** Use `Svg::load(filename)` in new code. */ | |||||
| DEPRECATED std::shared_ptr<Svg> loadSvg(const std::string& filename) { | |||||
| return Svg::load(filename); | |||||
| } | |||||
| }; | }; | ||||
| @@ -1,5 +1,7 @@ | |||||
| #include <svg.hpp> | #include <svg.hpp> | ||||
| #include <map> | |||||
| #include <math.hpp> | #include <math.hpp> | ||||
| #include <app/common.hpp> | |||||
| // #define DEBUG_ONLY(x) x | // #define DEBUG_ONLY(x) x | ||||
| @@ -8,6 +10,37 @@ | |||||
| namespace rack { | namespace rack { | ||||
| void Svg::loadFile(const std::string& filename) { | |||||
| handle = nsvgParseFromFile(filename.c_str(), "px", app::SVG_DPI); | |||||
| if (handle) { | |||||
| INFO("Loaded SVG %s", filename.c_str()); | |||||
| } | |||||
| else { | |||||
| WARN("Failed to load SVG %s", filename.c_str()); | |||||
| } | |||||
| } | |||||
| Svg::~Svg() { | |||||
| if (handle) | |||||
| nsvgDelete(handle); | |||||
| } | |||||
| static std::map<std::string, std::weak_ptr<Svg>> svgCache; | |||||
| std::shared_ptr<Svg> Svg::load(const std::string& filename) { | |||||
| auto sp = svgCache[filename].lock(); | |||||
| if (!sp) { | |||||
| svgCache[filename] = sp = std::make_shared<Svg>(); | |||||
| sp->load(filename); | |||||
| } | |||||
| return sp; | |||||
| } | |||||
| static NVGcolor getNVGColor(uint32_t color) { | static NVGcolor getNVGColor(uint32_t color) { | ||||
| return nvgRGBA( | return nvgRGBA( | ||||
| (color >> 0) & 0xff, | (color >> 0) & 0xff, | ||||
| @@ -72,28 +72,6 @@ std::shared_ptr<Image> Image::load(const std::string& filename) { | |||||
| } | } | ||||
| void Svg::loadFile(const std::string& filename) { | |||||
| handle = nsvgParseFromFile(filename.c_str(), "px", app::SVG_DPI); | |||||
| if (handle) { | |||||
| INFO("Loaded SVG %s", filename.c_str()); | |||||
| } | |||||
| else { | |||||
| WARN("Failed to load SVG %s", filename.c_str()); | |||||
| } | |||||
| } | |||||
| Svg::~Svg() { | |||||
| if (handle) | |||||
| nsvgDelete(handle); | |||||
| } | |||||
| std::shared_ptr<Svg> Svg::load(const std::string& filename) { | |||||
| return APP->window->loadSvg(filename); | |||||
| } | |||||
| struct Window::Internal { | struct Window::Internal { | ||||
| std::string lastWindowTitle; | std::string lastWindowTitle; | ||||
| @@ -652,16 +630,6 @@ std::shared_ptr<Image> Window::loadImage(const std::string& filename) { | |||||
| } | } | ||||
| std::shared_ptr<Svg> Window::loadSvg(const std::string& filename) { | |||||
| auto sp = svgCache[filename].lock(); | |||||
| if (!sp) { | |||||
| svgCache[filename] = sp = std::make_shared<Svg>(); | |||||
| sp->loadFile(filename); | |||||
| } | |||||
| return sp; | |||||
| } | |||||
| void windowInit() { | void windowInit() { | ||||
| int err; | int err; | ||||