diff --git a/src/yfontxft.cc b/src/yfontxft.cc index 4d09c9d3..66350dd0 100644 --- a/src/yfontxft.cc +++ b/src/yfontxft.cc @@ -9,6 +9,7 @@ #include "yfontbase.h" #include "ylocale.h" #include "ybidi.h" +#include "ascii.h" #include "intl.h" #include #include @@ -21,6 +22,7 @@ public: YXftFont(XftFont* font); virtual ~YXftFont(); + XftFont* load(const char* name, const char* lang, bool xlfd); bool valid() const override { return 0 < fFontCount; } int descent() const override { return fDescent; } int ascent() const override { return fAscent; } @@ -95,22 +97,46 @@ private: /******************************************************************************/ -YXftFont::YXftFont(mstring name, bool use_xlfd): +static bool getLang(char* buf, size_t size) { + char* env = getenv("LANG"); + if (env == nullptr) + env = getenv("LC_ALL"); + if (env) { + strlcpy(buf, env, size); + int k = ASCII::spanLower(buf); + if (k == 2 || k == 3) { + if ((buf[k] == '_' || buf[k] == '-') && + ASCII::spanUpper(buf + k + 1) == 2) + { + buf[k] = '-'; + buf[k + 1] = ASCII::toLower(buf[k + 1]); + buf[k + 2] = ASCII::toLower(buf[k + 2]); + k += 3; + } + buf[k] = '\0'; + return true; + } + } + buf[0] = '\0'; + return false; +} + +YXftFont::YXftFont(mstring name, bool xlfd): fFontCount(1 + name.count(',')), fAscent(0), fDescent(0), fFonts(new XftFont* [fFontCount]) { + char lang[8] = ""; + if (xlfd == false) { + getLang(lang, sizeof(lang)); + } + int count = 0; for (mstring s(name), r; s.splitall(',', &s, &r); s = r) { mstring fname = s.trim(); if (fname.nonempty() && count < fFontCount) { - XftFont* font; - if (use_xlfd) { - font = XftFontOpenXlfd(xapp->display(), xapp->screen(), fname); - } else { - font = XftFontOpenName(xapp->display(), xapp->screen(), fname); - } + XftFont* font = load(fname, lang, xlfd); if (font) { fFonts[count++] = font; } else { @@ -144,12 +170,32 @@ YXftFont::YXftFont(XftFont* font) : YXftFont::~YXftFont() { if (xapp) { - for (int i = fFontCount; 0 < i--; ) + for (int i = fFontCount; 0 < i--; ) { XftFontClose(xapp->display(), fFonts[i]); + fFonts[i] = nullptr; + } } delete[] fFonts; } +XftFont* YXftFont::load(const char* name, const char* lang, bool xlfd) { + XftFont* font = nullptr; + if (xlfd) { + font = XftFontOpenXlfd(xapp->display(), xapp->screen(), name); + } + else { + if (*lang && strstr(name, ":lang=") == nullptr) { + char buf[1234]; + snprintf(buf, sizeof buf, "%s:lang=%s", name, lang); + font = XftFontOpenName(xapp->display(), xapp->screen(), buf); + } + if (font == nullptr) { + font = XftFontOpenName(xapp->display(), xapp->screen(), name); + } + } + return font; +} + int YXftFont::textWidth(wchar_t* text, int length) const { TextParts parts = partitions(text, length); parts.discard();