add error checks and throw some exceptions

This commit is contained in:
Andrea Blankenstijn 2021-07-13 18:00:45 +02:00
parent 31370234df
commit 80184d8a35
2 changed files with 51 additions and 9 deletions

View file

@ -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

View file

@ -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;
}