From ae2efc3cdb677bce1d9ee3d809a1b4801686c701 Mon Sep 17 00:00:00 2001 From: Bert Gijsbers Date: Sun, 10 Nov 2024 13:51:34 +0100 Subject: [PATCH] Support locales with three letter language codes. --- src/yfontxft.cc | 30 ++++++++++++++++++++---------- src/ylocale.cc | 21 +++++++++++---------- src/ylocale.h | 2 +- 3 files changed, 32 insertions(+), 21 deletions(-) diff --git a/src/yfontxft.cc b/src/yfontxft.cc index 0737f270b..d7e5bc842 100644 --- a/src/yfontxft.cc +++ b/src/yfontxft.cc @@ -2,6 +2,7 @@ #ifdef CONFIG_XFREETYPE +#include "ascii.h" #include "ypaint.h" #include "yprefs.h" #include "ystring.h" @@ -109,16 +110,25 @@ YXftFont::YXftFont(mstring name, bool use_xlfd): if (use_xlfd) { font = XftFontOpenXlfd(xapp->display(), xapp->screen(), fname); } else { - - if (fname.find(":lang=") < 0) - { - auto lclocale = mstring(YLocale::getCheckedExplicitLocale(true)); - if (lclocale) { - fname = (fname + ":lang=" + lclocale.substring(0,2) + "-" - + lclocale.substring(3,2)).lower(); + if (fname.find(":lang=") < 0) { + const char* yloc = YLocale::getCheckedLocaleName(); + const char* unsc = yloc ? strchr(yloc, '_') : nullptr; + const int prefix = unsc ? int(unsc - yloc) : 0; + if (prefix == 2 || prefix == 3) { + char buf[10]; + memcpy(buf, yloc, prefix); + int len = prefix; + buf[len] = '-'; + len++; + buf[len] = ASCII::toLower(yloc[len]); + len++; + buf[len] = ASCII::toLower(yloc[len]); + len++; + buf[len] = '\0'; + fname += ":lang="; + fname += buf; } } - font = XftFontOpenName(xapp->display(), xapp->screen(), fname); } if (font) { @@ -288,7 +298,7 @@ void YXftFont::drawLimitLeft(Graphics& g, XftFont* font, int x, int y, lo -= 1; if (0 < ew) { const int size = lo + 2; - asmart copy(new wchar_t[size]); + wchar_t copy[size]; memcpy(copy, str, lo * sizeof(wchar_t)); copy[lo] = el; @@ -321,7 +331,7 @@ void YXftFont::drawLimitRight(Graphics& g, XftFont* font, int x, int y, } if (0 < ew) { const int size = lo + 2; - asmart copy(new wchar_t[size]); + wchar_t copy[size]; memcpy(copy + 1, str + len - lo, lo * sizeof(wchar_t)); copy[0] = el; copy[lo + 1] = 0; diff --git a/src/ylocale.cc b/src/ylocale.cc index becd044ae..85798ab72 100644 --- a/src/ylocale.cc +++ b/src/ylocale.cc @@ -314,16 +314,17 @@ char* YLocale::narrowString(const wchar_t* uStr, size_t uLen, size_t& lLen) { return dest; } -const char *YLocale::getCheckedExplicitLocale(bool lctype) -{ - auto loc = setlocale(lctype ? LC_CTYPE : LC_MESSAGES, NULL); - if (loc == NULL) - return NULL; - return (islower(*loc & 0xff) - && islower(loc[1] & 0xff) - && !isalpha(loc[2] & 0xff)) - ? loc - : NULL; +const char* YLocale::getCheckedLocaleName() { + using namespace ASCII; + const char* loc = getLocaleName(); + if (loc && isLower(*loc) && isLower(loc[1])) { + int i = 2; + if (isLower(loc[i])) + i++; + if (loc[i] == '_' && isUpper(loc[i + 1]) && isUpper(loc[i + 2])) + return loc; + } + return nullptr; } const char *YLocale::getLocaleName() { diff --git a/src/ylocale.h b/src/ylocale.h index 47b8a8177..11b60afaf 100644 --- a/src/ylocale.h +++ b/src/ylocale.h @@ -27,7 +27,7 @@ class YLocale { static wchar_t* wideCharString(const char* str, size_t len, size_t& out); #endif static char* narrowString(const wchar_t* uStr, size_t uLen, size_t& lLen); - static const char* getCheckedExplicitLocale(bool lctype=true); + static const char* getCheckedLocaleName(); private: class YConverter* converter;