Second try on linux platform with fontconfig
This commit is contained in:
parent
69aae0fab7
commit
68c4a396ac
@ -33,6 +33,10 @@
|
||||
#define USE_FONT_DIALOG
|
||||
#endif // apple
|
||||
|
||||
#ifdef __linux__
|
||||
#include <fontconfig/fontconfig.h>
|
||||
#endif // __linux__
|
||||
|
||||
#ifdef _WIN32
|
||||
#define USE_FONT_DIALOG
|
||||
#endif // _WIN32
|
||||
@ -70,6 +74,102 @@ public:
|
||||
// convert svg image to ExPolygons
|
||||
static ExPolygons to_ExPolygons(NSVGimage *image, float tessTol = 10., int max_level = 10);
|
||||
};
|
||||
|
||||
#ifdef __linux__
|
||||
class FontConfigHelp
|
||||
{
|
||||
public:
|
||||
FontConfigHelp() { FcInit(); }
|
||||
~FontConfigHelp() { FcFini(); }
|
||||
// inspired by wxpdfdoc - https://github.com/utelle/wxpdfdoc/blob/5bdcdb9953327d06dc50ec312685ccd9bc8400e0/src/pdffontmanager.cpp
|
||||
std::string get_font_path(const wxFont &font) {
|
||||
FcConfig *fc = FcInitLoadConfigAndFonts();
|
||||
if (fc == nullptr) return "";
|
||||
ScopeGuard sg_fc([fc]() { FcConfigDestroy(fc); });
|
||||
|
||||
wxString fontDesc = font.GetNativeFontInfoUserDesc();
|
||||
wxString faceName = font.GetFaceName();
|
||||
const wxScopedCharBuffer faceNameBuffer = faceName.ToUTF8();
|
||||
const char* fontFamily = faceNameBuffer;
|
||||
|
||||
// Check font slant
|
||||
int slant = FC_SLANT_ROMAN;
|
||||
if (fontDesc.Find(wxS("Oblique")) != wxNOT_FOUND) slant = FC_SLANT_OBLIQUE;
|
||||
else if (fontDesc.Find(wxS("Italic")) != wxNOT_FOUND) slant = FC_SLANT_ITALIC;
|
||||
|
||||
// Check font weight
|
||||
int weight = FC_WEIGHT_NORMAL;
|
||||
if (fontDesc.Find(wxS("Book")) != wxNOT_FOUND) weight = FC_WEIGHT_BOOK;
|
||||
else if (fontDesc.Find(wxS("Medium")) != wxNOT_FOUND) weight = FC_WEIGHT_MEDIUM;
|
||||
#ifdef FC_WEIGHT_ULTRALIGHT
|
||||
else if (fontDesc.Find(wxS("Ultra-Light")) != wxNOT_FOUND) weight = FC_WEIGHT_ULTRALIGHT;
|
||||
#endif
|
||||
else if (fontDesc.Find(wxS("Light")) != wxNOT_FOUND) weight = FC_WEIGHT_LIGHT;
|
||||
else if (fontDesc.Find(wxS("Semi-Bold")) != wxNOT_FOUND) weight = FC_WEIGHT_DEMIBOLD;
|
||||
#ifdef FC_WEIGHT_ULTRABOLD
|
||||
else if (fontDesc.Find(wxS("Ultra-Bold")) != wxNOT_FOUND) weight = FC_WEIGHT_ULTRABOLD;
|
||||
#endif
|
||||
else if (fontDesc.Find(wxS("Bold")) != wxNOT_FOUND) weight = FC_WEIGHT_BOLD;
|
||||
else if (fontDesc.Find(wxS("Heavy")) != wxNOT_FOUND) weight = FC_WEIGHT_BLACK;
|
||||
|
||||
// Check font width
|
||||
int width = FC_WIDTH_NORMAL;
|
||||
if (fontDesc.Find(wxS("Ultra-Condensed")) != wxNOT_FOUND) width = FC_WIDTH_ULTRACONDENSED;
|
||||
else if (fontDesc.Find(wxS("Extra-Condensed")) != wxNOT_FOUND) width = FC_WIDTH_EXTRACONDENSED;
|
||||
else if (fontDesc.Find(wxS("Semi-Condensed")) != wxNOT_FOUND) width = FC_WIDTH_SEMICONDENSED;
|
||||
else if (fontDesc.Find(wxS("Condensed")) != wxNOT_FOUND) width = FC_WIDTH_CONDENSED;
|
||||
else if (fontDesc.Find(wxS("Ultra-Expanded")) != wxNOT_FOUND) width = FC_WIDTH_ULTRAEXPANDED;
|
||||
else if (fontDesc.Find(wxS("Extra-Expanded")) != wxNOT_FOUND) width = FC_WIDTH_EXTRAEXPANDED;
|
||||
else if (fontDesc.Find(wxS("Semi-Expanded")) != wxNOT_FOUND) width = FC_WIDTH_SEMIEXPANDED;
|
||||
else if (fontDesc.Find(wxS("Expanded")) != wxNOT_FOUND) width = FC_WIDTH_EXPANDED;
|
||||
|
||||
FcResult res;
|
||||
FcPattern* matchPattern = FcPatternBuild(NULL, FC_FAMILY, FcTypeString, (FcChar8*) fontFamily, NULL);
|
||||
ScopeGuard sg_mp([matchPattern]() { FcPatternDestroy(matchPattern); });
|
||||
|
||||
FcPatternAddInteger(matchPattern, FC_SLANT, slant);
|
||||
FcPatternAddInteger(matchPattern, FC_WEIGHT, weight);
|
||||
FcPatternAddInteger(matchPattern, FC_WIDTH, width);
|
||||
|
||||
FcConfigSubstitute (NULL, matchPattern, FcMatchPattern);
|
||||
FcDefaultSubstitute (matchPattern);
|
||||
|
||||
FcPattern* resultPattern = FcFontMatch (NULL, matchPattern, &res);
|
||||
if (resultPattern == nullptr) return "";
|
||||
ScopeGuard sg_rp([resultPattern]() { FcPatternDestroy(resultPattern); });
|
||||
|
||||
|
||||
FcChar8 *fileName;
|
||||
if (FcPatternGetString(resultPattern, FC_FILE, 0, &fileName) != FcResultMatch) return "";
|
||||
wxString fontFileName = wxString::FromUTF8((char *) fileName);
|
||||
|
||||
if (fontFileName.IsEmpty()) return "";
|
||||
|
||||
// find full file path
|
||||
wxFileName myFileName(fontFileName);
|
||||
if (!myFileName.IsOk()) return "";
|
||||
|
||||
if (myFileName.IsRelative()) {
|
||||
// Check whether the file is relative to the current working directory
|
||||
if (!(myFileName.MakeAbsolute() && myFileName.FileExists())) {
|
||||
return "";
|
||||
// File not found, search in given search paths
|
||||
//wxString foundFileName = m_searchPaths.FindAbsoluteValidPath(fileName);
|
||||
//if (!foundFileName.IsEmpty()) {
|
||||
// myFileName.Assign(foundFileName);
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
if (!myFileName.FileExists() || !myFileName.IsFileReadable()) return "";
|
||||
|
||||
// File exists and is accessible
|
||||
wxString fullFileName = myFileName.GetFullPath();
|
||||
return fullFileName.c_str();
|
||||
}
|
||||
};
|
||||
#endif // __linux__
|
||||
|
||||
} // namespace Slic3r
|
||||
|
||||
using namespace Slic3r;
|
||||
@ -419,7 +519,7 @@ void GLGizmoEmboss::draw_window()
|
||||
void GLGizmoEmboss::draw_font_list()
|
||||
{
|
||||
const float& max_width = m_gui_cfg->max_font_name_width;
|
||||
std::optional<int> rename_index;
|
||||
std::optional<size_t> rename_index;
|
||||
std::string current_name = imgui_trunc(m_font_list[m_font_selected].name, max_width);
|
||||
ImGui::SetNextItemWidth(m_gui_cfg->combo_font_width);
|
||||
if (ImGui::BeginCombo("##font_selector", current_name.c_str())) {
|
||||
@ -443,12 +543,12 @@ void GLGizmoEmboss::draw_font_list()
|
||||
for (FontItem &f : m_font_list) {
|
||||
ImGui::PushID(f.name.c_str());
|
||||
std::string name = imgui_trunc(f.name, max_width);
|
||||
int index = &f - &m_font_list.front();
|
||||
bool is_selected = index == static_cast<int>(m_font_selected);
|
||||
size_t index = &f - &m_font_list.front();
|
||||
bool is_selected = index == m_font_selected;
|
||||
auto flags = ImGuiSelectableFlags_AllowItemOverlap; // allow clic buttons
|
||||
if (ImGui::Selectable(name.c_str(), is_selected, flags)) {
|
||||
size_t prev_font_selected = m_font_selected;
|
||||
m_font_selected = index;
|
||||
m_font_selected = index;
|
||||
if (!load_font()) {
|
||||
m_font_selected = prev_font_selected;
|
||||
} else {
|
||||
@ -475,7 +575,7 @@ void GLGizmoEmboss::draw_font_list()
|
||||
|
||||
// rename modal window popup
|
||||
const char *rename_popup_id = "Rename_font";
|
||||
static int rename_id;
|
||||
static size_t rename_id;
|
||||
if (rename_index.has_value() && !ImGui::IsPopupOpen(rename_popup_id)) {
|
||||
ImGui::OpenPopup(rename_popup_id);
|
||||
rename_id = *rename_index;
|
||||
@ -967,8 +1067,10 @@ std::optional<Emboss::Font> WxFontUtils::load_font(const FontItem &fi)
|
||||
return Emboss::load_font(fi.path.c_str());
|
||||
case FontItem::Type::wx_font_descr:
|
||||
return WxFontUtils::load_font(WxFontUtils::load_wxFont(fi.path));
|
||||
case FontItem::Type::undefined:
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::optional<Emboss::Font> WxFontUtils::load_font(const wxFont &font)
|
||||
@ -977,6 +1079,11 @@ std::optional<Emboss::Font> WxFontUtils::load_font(const wxFont &font)
|
||||
#ifdef _WIN32
|
||||
return Emboss::load_font(font.GetHFONT());
|
||||
#elif __linux__ // if defined(__WXGTK__)
|
||||
static FontConfigHelp help;
|
||||
std::string font_path = help.get_font_path(font);
|
||||
if (font_path.empty()) return {};
|
||||
return Emboss::load_font(font_path.c_str());
|
||||
|
||||
// HERE is place to add implementation for linux to
|
||||
// convert from wxFont to filePath(as MacOS) or fontData pointer(as WinOs)
|
||||
return {};
|
||||
|
Loading…
Reference in New Issue
Block a user