add error checks and throw some exceptions
This commit is contained in:
parent
31370234df
commit
80184d8a35
|
@ -6,7 +6,15 @@
|
|||
|
||||
namespace bwidgets::exception
|
||||
{
|
||||
struct NotFound : std::exception {};
|
||||
struct FontconfigError final : std::exception
|
||||
{
|
||||
const char* file;
|
||||
int line;
|
||||
const char* what;
|
||||
|
||||
FontconfigError(const char* f="", int l=-1, const char* w="?")
|
||||
: file(f), line(l), what(w) {}
|
||||
};
|
||||
}
|
||||
|
||||
namespace bwidgets::utils::font
|
||||
|
|
|
@ -1,19 +1,54 @@
|
|||
#include <iostream>
|
||||
#include <any>
|
||||
#include <vector>
|
||||
|
||||
#include <fontconfig/fontconfig.h>
|
||||
|
||||
#include <basic_widgets/utils/font.hpp>
|
||||
|
||||
using namespace bwidgets;
|
||||
|
||||
namespace bwidgets::utils::font
|
||||
{
|
||||
std::string find(const std::string& pat)
|
||||
{
|
||||
std::vector<std::any> ptrs;
|
||||
|
||||
auto clean = [&ptrs](int lvl) mutable
|
||||
{
|
||||
switch (lvl)
|
||||
{
|
||||
case 2:
|
||||
FcPatternDestroy(std::any_cast<FcPattern*>(ptrs.at(1)));
|
||||
[[fallthrough]];
|
||||
case 1:
|
||||
FcConfigDestroy(std::any_cast<FcConfig*>(ptrs.at(0)));
|
||||
FcFini();
|
||||
}
|
||||
};
|
||||
|
||||
FcConfig* conf = FcInitLoadConfigAndFonts();
|
||||
if (conf == nullptr)
|
||||
{
|
||||
throw exception::FontconfigError {__FILE__, __LINE__, "fontconfig init failed"};
|
||||
}
|
||||
else ptrs.push_back(conf);
|
||||
|
||||
FcPattern* pattern = FcNameParse((FcChar8*)pat.c_str());
|
||||
FcConfigSubstitute(conf, pattern, FcMatchPattern);
|
||||
if (pattern == nullptr)
|
||||
{
|
||||
clean(ptrs.size());
|
||||
throw exception::FontconfigError {__FILE__, __LINE__, "FcNameParse failed"};
|
||||
}
|
||||
else ptrs.push_back(pattern);
|
||||
|
||||
if(FcConfigSubstitute(conf, pattern, FcMatchPattern) == FcFalse)
|
||||
{
|
||||
clean(ptrs.size());
|
||||
throw exception::FontconfigError {__FILE__, __LINE__, "FcConfigSubstitute failed"};
|
||||
}
|
||||
|
||||
FcDefaultSubstitute(pattern);
|
||||
|
||||
bool found = false;
|
||||
std::string file_path;
|
||||
FcResult res;
|
||||
FcPattern* font = FcFontMatch(conf, pattern, &res);
|
||||
|
@ -23,15 +58,14 @@ namespace bwidgets::utils::font
|
|||
if (FcPatternGetString(font, FC_FILE, 0, &file) == FcResultMatch)
|
||||
{
|
||||
file_path = (char*)file;
|
||||
found = true;
|
||||
}
|
||||
FcPatternDestroy(font);
|
||||
}
|
||||
FcConfigDestroy(conf);
|
||||
FcFini();
|
||||
|
||||
if (!found)
|
||||
throw exception::NotFound();
|
||||
clean(ptrs.size());
|
||||
|
||||
if (file_path.empty())
|
||||
throw exception::FontconfigError {__FILE__, __LINE__, "no font found"};
|
||||
|
||||
return file_path;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue