| @@ -43,10 +43,11 @@ struct Svg { | |||||
| void loadFile(const std::string& filename); | void loadFile(const std::string& filename); | ||||
| /** Loads SVG data from a string. */ | /** Loads SVG data from a string. */ | ||||
| void loadString(const std::string& str); | void loadString(const std::string& str); | ||||
| void draw(NVGcontext* vg); | |||||
| math::Vec getSize(); | |||||
| int getNumShapes(); | int getNumShapes(); | ||||
| int getNumPaths(); | int getNumPaths(); | ||||
| int getNumPoints(); | int getNumPoints(); | ||||
| void draw(NVGcontext* vg); | |||||
| /** Loads Svg from a cache. */ | /** Loads Svg from a cache. */ | ||||
| static std::shared_ptr<Svg> load(const std::string& filename); | static std::shared_ptr<Svg> load(const std::string& filename); | ||||
| @@ -24,21 +24,20 @@ void RackRail::draw(const DrawArgs& args) { | |||||
| // Rails | // Rails | ||||
| for (float y = 0; y < box.size.y; y += RACK_GRID_HEIGHT) { | for (float y = 0; y < box.size.y; y += RACK_GRID_HEIGHT) { | ||||
| const float busBoardWidth = busBoardSvg->handle->width; | |||||
| const float busBoardHeight = busBoardSvg->handle->height; | |||||
| const float busBoardY = y + (RACK_GRID_HEIGHT - busBoardHeight) / 2; | |||||
| const math::Vec busBoardSize = busBoardSvg->getSize(); | |||||
| const float busBoardY = y + (RACK_GRID_HEIGHT - busBoardSize.y) / 2; | |||||
| const NVGcolor shadowColor = nvgRGBA(0, 0, 0, 0x20); | const NVGcolor shadowColor = nvgRGBA(0, 0, 0, 0x20); | ||||
| // Bus board shadow | // Bus board shadow | ||||
| nvgBeginPath(args.vg); | nvgBeginPath(args.vg); | ||||
| const float busBoardShadowY = busBoardY + busBoardHeight; | |||||
| const float busBoardShadowY = busBoardY + busBoardSize.y; | |||||
| const float busBoardShadowHeight = 10; | const float busBoardShadowHeight = 10; | ||||
| nvgRect(args.vg, 0, busBoardShadowY, box.size.x, busBoardShadowHeight); | nvgRect(args.vg, 0, busBoardShadowY, box.size.x, busBoardShadowHeight); | ||||
| nvgFillPaint(args.vg, nvgLinearGradient(args.vg, 0, busBoardShadowY, 0, busBoardShadowY + busBoardShadowHeight, shadowColor, color::BLACK_TRANSPARENT)); | nvgFillPaint(args.vg, nvgLinearGradient(args.vg, 0, busBoardShadowY, 0, busBoardShadowY + busBoardShadowHeight, shadowColor, color::BLACK_TRANSPARENT)); | ||||
| nvgFill(args.vg); | nvgFill(args.vg); | ||||
| // Bus board | // Bus board | ||||
| for (float x = 0; x < box.size.x; x += busBoardWidth) { | |||||
| for (float x = 0; x < box.size.x; x += busBoardSize.x) { | |||||
| nvgSave(args.vg); | nvgSave(args.vg); | ||||
| nvgTranslate(args.vg, x, busBoardY); | nvgTranslate(args.vg, x, busBoardY); | ||||
| busBoardSvg->draw(args.vg); | busBoardSvg->draw(args.vg); | ||||
| @@ -18,6 +18,9 @@ Svg::~Svg() { | |||||
| void Svg::loadFile(const std::string& filename) { | void Svg::loadFile(const std::string& filename) { | ||||
| if (handle) | |||||
| nsvgDelete(handle); | |||||
| handle = nsvgParseFromFile(filename.c_str(), "px", SVG_DPI); | handle = nsvgParseFromFile(filename.c_str(), "px", SVG_DPI); | ||||
| if (!handle) | if (!handle) | ||||
| throw Exception("Failed to load SVG %s", filename.c_str()); | throw Exception("Failed to load SVG %s", filename.c_str()); | ||||
| @@ -26,6 +29,9 @@ void Svg::loadFile(const std::string& filename) { | |||||
| void Svg::loadString(const std::string& str) { | void Svg::loadString(const std::string& str) { | ||||
| if (handle) | |||||
| nsvgDelete(handle); | |||||
| // nsvgParse modifies the input string | // nsvgParse modifies the input string | ||||
| std::string strCopy = str; | std::string strCopy = str; | ||||
| handle = nsvgParse(&strCopy[0], "px", SVG_DPI); | handle = nsvgParse(&strCopy[0], "px", SVG_DPI); | ||||
| @@ -36,8 +42,10 @@ void Svg::loadString(const std::string& str) { | |||||
| } | } | ||||
| void Svg::draw(NVGcontext* vg) { | |||||
| svgDraw(vg, handle); | |||||
| math::Vec Svg::getSize() { | |||||
| if (!handle) | |||||
| return math::Vec(); | |||||
| return math::Vec(handle->width, handle->height); | |||||
| } | } | ||||
| @@ -78,6 +86,13 @@ int Svg::getNumPoints() { | |||||
| } | } | ||||
| void Svg::draw(NVGcontext* vg) { | |||||
| if (!handle) | |||||
| return; | |||||
| svgDraw(vg, handle); | |||||
| } | |||||
| static std::map<std::string, std::shared_ptr<Svg>> svgCache; | static std::map<std::string, std::shared_ptr<Svg>> svgCache; | ||||
| @@ -7,8 +7,8 @@ namespace widget { | |||||
| void SvgWidget::wrap() { | void SvgWidget::wrap() { | ||||
| if (svg && svg->handle) { | |||||
| box.size = math::Vec(svg->handle->width, svg->handle->height); | |||||
| if (svg) { | |||||
| box.size = svg->getSize(); | |||||
| } | } | ||||
| else { | else { | ||||
| box.size = math::Vec(); | box.size = math::Vec(); | ||||
| @@ -23,8 +23,6 @@ void SvgWidget::setSvg(std::shared_ptr<Svg> svg) { | |||||
| void SvgWidget::draw(const DrawArgs& args) { | void SvgWidget::draw(const DrawArgs& args) { | ||||
| if (!svg) | if (!svg) | ||||
| return; | return; | ||||
| if (!svg->handle) | |||||
| return; | |||||
| svgDraw(args.vg, svg->handle); | svgDraw(args.vg, svg->handle); | ||||
| } | } | ||||