Browse Source

Make fonts and images be permanently cached. Use font cache in LedDisplay.

tags/v2.0.0
Andrew Belt 4 years ago
parent
commit
c545995fb1
5 changed files with 88 additions and 57 deletions
  1. +2
    -2
      include/app/LedDisplay.hpp
  2. +0
    -4
      include/window.hpp
  3. +22
    -10
      src/app/LedDisplay.cpp
  4. +24
    -18
      src/svg.cpp
  5. +40
    -23
      src/window.cpp

+ 2
- 2
include/app/LedDisplay.hpp View File

@@ -20,7 +20,7 @@ struct LedDisplaySeparator : widget::Widget {


struct LedDisplayChoice : widget::OpaqueWidget { struct LedDisplayChoice : widget::OpaqueWidget {
std::string text; std::string text;
std::shared_ptr<Font> font;
std::string fontPath;
math::Vec textOffset; math::Vec textOffset;
NVGcolor color; NVGcolor color;
NVGcolor bgColor; NVGcolor bgColor;
@@ -30,7 +30,7 @@ struct LedDisplayChoice : widget::OpaqueWidget {
}; };


struct LedDisplayTextField : ui::TextField { struct LedDisplayTextField : ui::TextField {
std::shared_ptr<Font> font;
std::string fontPath;
math::Vec textOffset; math::Vec textOffset;
NVGcolor color; NVGcolor color;
LedDisplayTextField(); LedDisplayTextField();


+ 0
- 4
include/window.hpp View File

@@ -58,10 +58,6 @@ struct Window {
float windowRatio = 1.f; float windowRatio = 1.f;
std::shared_ptr<Font> uiFont; std::shared_ptr<Font> uiFont;


/** Use load*() instead of modifying these directly. */
std::map<std::string, std::weak_ptr<Font>> fontCache;
std::map<std::string, std::weak_ptr<Image>> imageCache;

Window(); Window();
~Window(); ~Window();
void run(); void run();


+ 22
- 10
src/app/LedDisplay.cpp View File

@@ -24,6 +24,7 @@ LedDisplaySeparator::LedDisplaySeparator() {
box.size = math::Vec(); box.size = math::Vec();
} }



void LedDisplaySeparator::draw(const DrawArgs& args) { void LedDisplaySeparator::draw(const DrawArgs& args) {
nvgBeginPath(args.vg); nvgBeginPath(args.vg);
nvgMoveTo(args.vg, 0, 0); nvgMoveTo(args.vg, 0, 0);
@@ -36,12 +37,13 @@ void LedDisplaySeparator::draw(const DrawArgs& args) {


LedDisplayChoice::LedDisplayChoice() { LedDisplayChoice::LedDisplayChoice() {
box.size = mm2px(math::Vec(0, 28.0 / 3)); box.size = mm2px(math::Vec(0, 28.0 / 3));
font = APP->window->loadFont(asset::system("res/fonts/ShareTechMono-Regular.ttf"));
fontPath = asset::system("res/fonts/ShareTechMono-Regular.ttf");
color = nvgRGB(0xff, 0xd7, 0x14); color = nvgRGB(0xff, 0xd7, 0x14);
bgColor = nvgRGBAf(0, 0, 0, 0); bgColor = nvgRGBAf(0, 0, 0, 0);
textOffset = math::Vec(10, 18); textOffset = math::Vec(10, 18);
} }



void LedDisplayChoice::draw(const DrawArgs& args) { void LedDisplayChoice::draw(const DrawArgs& args) {
nvgScissor(args.vg, RECT_ARGS(args.clipBox)); nvgScissor(args.vg, RECT_ARGS(args.clipBox));
if (bgColor.a > 0.0) { if (bgColor.a > 0.0) {
@@ -51,7 +53,8 @@ void LedDisplayChoice::draw(const DrawArgs& args) {
nvgFill(args.vg); nvgFill(args.vg);
} }


if (font->handle >= 0) {
std::shared_ptr<Font> font = APP->window->loadFont(fontPath);
if (font && font->handle >= 0) {
nvgFillColor(args.vg, color); nvgFillColor(args.vg, color);
nvgFontFaceId(args.vg, font->handle); nvgFontFaceId(args.vg, font->handle);
nvgTextLetterSpacing(args.vg, 0.0); nvgTextLetterSpacing(args.vg, 0.0);
@@ -62,6 +65,7 @@ void LedDisplayChoice::draw(const DrawArgs& args) {
nvgResetScissor(args.vg); nvgResetScissor(args.vg);
} }



void LedDisplayChoice::onButton(const ButtonEvent& e) { void LedDisplayChoice::onButton(const ButtonEvent& e) {
OpaqueWidget::onButton(e); OpaqueWidget::onButton(e);


@@ -74,7 +78,7 @@ void LedDisplayChoice::onButton(const ButtonEvent& e) {




LedDisplayTextField::LedDisplayTextField() { LedDisplayTextField::LedDisplayTextField() {
font = APP->window->loadFont(asset::system("res/fonts/ShareTechMono-Regular.ttf"));
fontPath = asset::system("res/fonts/ShareTechMono-Regular.ttf");
color = nvgRGB(0xff, 0xd7, 0x14); color = nvgRGB(0xff, 0xd7, 0x14);
textOffset = math::Vec(5, 5); textOffset = math::Vec(5, 5);
} }
@@ -90,16 +94,18 @@ void LedDisplayTextField::draw(const DrawArgs& args) {
nvgFill(args.vg); nvgFill(args.vg);


// Text // Text
if (font->handle >= 0) {
std::shared_ptr<Font> font = APP->window->loadFont(fontPath);
if (font && font->handle >= 0) {
bndSetFont(font->handle); bndSetFont(font->handle);


NVGcolor highlightColor = color; NVGcolor highlightColor = color;
highlightColor.a = 0.5; highlightColor.a = 0.5;
int begin = std::min(cursor, selection); int begin = std::min(cursor, selection);
int end = (this == APP->event->selectedWidget) ? std::max(cursor, selection) : -1; int end = (this == APP->event->selectedWidget) ? std::max(cursor, selection) : -1;
bndIconLabelCaret(args.vg, textOffset.x, textOffset.y,
box.size.x - 2 * textOffset.x, box.size.y - 2 * textOffset.y,
-1, color, 12, text.c_str(), highlightColor, begin, end);
bndIconLabelCaret(args.vg,
textOffset.x, textOffset.y,
box.size.x - 2 * textOffset.x, box.size.y - 2 * textOffset.y,
-1, color, 12, text.c_str(), highlightColor, begin, end);


bndSetFont(APP->window->uiFont->handle); bndSetFont(APP->window->uiFont->handle);
} }
@@ -107,11 +113,17 @@ void LedDisplayTextField::draw(const DrawArgs& args) {
nvgResetScissor(args.vg); nvgResetScissor(args.vg);
} }



int LedDisplayTextField::getTextPosition(math::Vec mousePos) { int LedDisplayTextField::getTextPosition(math::Vec mousePos) {
std::shared_ptr<Font> font = APP->window->loadFont(fontPath);
if (!font || !font->handle)
return 0;

bndSetFont(font->handle); bndSetFont(font->handle);
int textPos = bndIconLabelTextPosition(APP->window->vg, textOffset.x, textOffset.y,
box.size.x - 2 * textOffset.x, box.size.y - 2 * textOffset.y,
-1, 12, text.c_str(), mousePos.x, mousePos.y);
int textPos = bndIconLabelTextPosition(APP->window->vg,
textOffset.x, textOffset.y,
box.size.x - 2 * textOffset.x, box.size.y - 2 * textOffset.y,
-1, 12, text.c_str(), mousePos.x, mousePos.y);
bndSetFont(APP->window->uiFont->handle); bndSetFont(APP->window->uiFont->handle);
return textPos; return textPos;
} }


+ 24
- 18
src/svg.cpp View File

@@ -1,6 +1,7 @@
#include <svg.hpp> #include <svg.hpp>
#include <map> #include <map>
#include <math.hpp> #include <math.hpp>
#include <string.hpp>




// #define DEBUG_ONLY(x) x // #define DEBUG_ONLY(x) x
@@ -18,12 +19,9 @@ Svg::~Svg() {


void Svg::loadFile(const std::string& filename) { void Svg::loadFile(const std::string& filename) {
handle = nsvgParseFromFile(filename.c_str(), "px", SVG_DPI); handle = nsvgParseFromFile(filename.c_str(), "px", SVG_DPI);
if (handle) {
INFO("Loaded SVG %s", filename.c_str());
}
else {
WARN("Failed to load SVG %s", filename.c_str());
}
if (!handle)
throw Exception("Failed to load SVG %s", filename.c_str());
INFO("Loaded SVG %s", filename.c_str());
} }




@@ -31,12 +29,10 @@ void Svg::loadString(const std::string& str) {
// 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);
if (handle) {
INFO("Loaded SVG");
}
else {
WARN("Failed to load SVG");
}
std::string strEllip = string::ellipsize(str, 40);
if (!handle)
throw Exception("Failed to load SVG \"%s\"", strEllip.c_str());
INFO("Loaded SVG \"%s\"", strEllip.c_str());
} }




@@ -46,16 +42,26 @@ void Svg::draw(NVGcontext* vg) {






static std::map<std::string, std::weak_ptr<Svg>> svgCache;
static std::map<std::string, std::shared_ptr<Svg>> svgCache;




std::shared_ptr<Svg> Svg::load(const std::string& filename) { 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->loadFile(filename);
const auto& pair = svgCache.find(filename);
if (pair != svgCache.end())
return pair->second;

// Load svg
std::shared_ptr<Svg> svg;
try {
svg = std::make_shared<Svg>();
svg->loadFile(filename);
}
catch (Exception& e) {
WARN("%s", e.what());
svg = NULL;
} }
return sp;
svgCache[filename] = svg;
return svg;
} }






+ 40
- 23
src/window.cpp View File

@@ -29,12 +29,9 @@ namespace rack {
void Font::loadFile(const std::string& filename, NVGcontext* vg) { void Font::loadFile(const std::string& filename, NVGcontext* vg) {
this->vg = vg; this->vg = vg;
handle = nvgCreateFont(vg, filename.c_str(), filename.c_str()); handle = nvgCreateFont(vg, filename.c_str(), filename.c_str());
if (handle >= 0) {
INFO("Loaded font %s", filename.c_str());
}
else {
WARN("Failed to load font %s", filename.c_str());
}
if (handle < 0)
throw Exception("Failed to load font %s", filename.c_str());
INFO("Loaded font %s", filename.c_str());
} }




@@ -51,12 +48,9 @@ std::shared_ptr<Font> Font::load(const std::string& filename) {
void Image::loadFile(const std::string& filename, NVGcontext* vg) { void Image::loadFile(const std::string& filename, NVGcontext* vg) {
this->vg = vg; this->vg = vg;
handle = nvgCreateImage(vg, filename.c_str(), NVG_IMAGE_REPEATX | NVG_IMAGE_REPEATY); handle = nvgCreateImage(vg, filename.c_str(), NVG_IMAGE_REPEATX | NVG_IMAGE_REPEATY);
if (handle > 0) {
INFO("Loaded image %s", filename.c_str());
}
else {
WARN("Failed to load image %s", filename.c_str());
}
if (handle <= 0)
throw Exception("Failed to load image %s", filename.c_str());
INFO("Loaded image %s", filename.c_str());
} }




@@ -88,6 +82,9 @@ struct Window::Internal {
double lastFrameTime = 0.0; double lastFrameTime = 0.0;


math::Vec lastMousePos; math::Vec lastMousePos;

std::map<std::string, std::shared_ptr<Font>> fontCache;
std::map<std::string, std::shared_ptr<Image>> imageCache;
}; };




@@ -611,22 +608,42 @@ double Window::getFrameTimeOverdue() {




std::shared_ptr<Font> Window::loadFont(const std::string& filename) { std::shared_ptr<Font> Window::loadFont(const std::string& filename) {
auto sp = fontCache[filename].lock();
if (!sp) {
fontCache[filename] = sp = std::make_shared<Font>();
sp->loadFile(filename, vg);
const auto& pair = internal->fontCache.find(filename);
if (pair != internal->fontCache.end())
return pair->second;

// Load font
std::shared_ptr<Font> font;
try {
font = std::make_shared<Font>();
font->loadFile(filename, vg);
} }
return sp;
catch (Exception& e) {
WARN("%s", e.what());
font = NULL;
}
internal->fontCache[filename] = font;
return font;
} }




std::shared_ptr<Image> Window::loadImage(const std::string& filename) { std::shared_ptr<Image> Window::loadImage(const std::string& filename) {
auto sp = imageCache[filename].lock();
if (!sp) {
imageCache[filename] = sp = std::make_shared<Image>();
sp->loadFile(filename, vg);
}
return sp;
const auto& pair = internal->imageCache.find(filename);
if (pair != internal->imageCache.end())
return pair->second;

// Load image
std::shared_ptr<Image> image;
try {
image = std::make_shared<Image>();
image->loadFile(filename, vg);
}
catch (Exception& e) {
WARN("%s", e.what());
image = NULL;
}
internal->imageCache[filename] = image;
return image;
} }






Loading…
Cancel
Save