29#include <wx/tokenzr.h>
39 wxFontStyle style_req;
40 wxFontWeight weight_req;
47 wxFont *FindOrCreateFont(
int pointSize, wxFontFamily family,
48 wxFontStyle style, wxFontWeight weight,
49 bool underline =
false,
50 const wxString &face = wxEmptyString,
51 wxFontEncoding encoding = wxFONTENCODING_DEFAULT);
56 wxFontStyle style, wxFontWeight weight,
bool underline,
57 const wxString &facename, wxFontEncoding encoding);
59 std::vector<font_cache_record> m_fontVector;
70static wxString s_locale;
72FontMgr *FontMgr::instance = NULL;
75 if (!instance) instance =
new FontMgr;
79void FontMgr::Shutdown() {
86FontMgr::FontMgr() : m_wxFontCache(NULL), m_fontlist(NULL), pDefFont(NULL) {
88 m_fontlist =
new FontList;
93 pDefFont = FindOrCreateFont(12, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL,
94 wxFONTWEIGHT_BOLD, FALSE, wxString(
""),
95 wxFONTENCODING_SYSTEM);
99 for (
auto it = m_fontlist->begin(); it != m_fontlist->end(); it++)
delete *it;
103 delete m_wxFontCache;
106void FontMgr::SetLocale(wxString &newLocale) { s_locale = newLocale; }
110 return pmfd ? pmfd->
m_color : wxColour(0, 0, 0);
114 const wxColour color)
const {
129 configkey = s_locale;
130 configkey.Append(
"-");
134 const collate<char> &coll = use_facet<collate<char> >(loc);
139 wxCharBuffer abuf = description.ToUTF8();
141 int fdLen = strlen(abuf);
144 wxString::Format(
"%08lx", coll.hash(abuf.data(), abuf.data() + fdLen)));
148int FontMgr::GetSystemFontSize() {
149 static int sys_font_size = 0;
150 if (!sys_font_size) {
151 wxFont sys_font = *wxNORMAL_FONT;
152 sys_font_size = sys_font.GetPointSize();
154 return sys_font_size;
157wxString FontMgr::GetSystemFontFaceName() {
158 static wxString sys_font_facename;
159 if (sys_font_facename.IsEmpty()) {
160 wxFont sys_font = *wxNORMAL_FONT;
161 sys_font_facename = sys_font.GetFaceName();
163 return sys_font_facename;
166bool FontMgr::IsDefaultFontEntry(
const MyFontDesc *font_desc)
const {
178wxFont *FontMgr::GetFontLegacy(
const wxString &TextElement,
179 int user_default_size) {
181 for (
auto node = m_fontlist->begin(); node != m_fontlist->end(); ++node) {
188 return GetFont(TextElement, user_default_size);
193 for (
auto node = m_fontlist->begin(); node != m_fontlist->end(); ++node) {
198 if (requested_font_size == 0 && IsDefaultFontEntry(pmfd)) {
203 }
else if (requested_font_size != 0 &&
204 pmfd->
m_font->GetPointSize() == requested_font_size) {
217 if (0 == requested_font_size) {
218 new_size = g_default_font_size ? g_default_font_size : GetSystemFontSize();
220 new_size = requested_font_size;
224 : GetSystemFontFaceName();
226 wxString nativefont = GetSimpleNativeFont(new_size, face_name);
227 wxFont *nf = wxFont::New(nativefont);
231 bool is_default = (requested_font_size == 0);
233 new MyFontDesc(TextElement, configkey, nf, color, is_default);
234 m_fontlist->push_back(pnewfd);
239MyFontDesc *FontMgr::GetFontDesc(
const wxString &TextElement)
const {
241 for (
auto node = m_fontlist->begin(); node != m_fontlist->end(); ++node) {
250 for (
auto node = m_fontlist->begin(); node != m_fontlist->end(); ++node) {
261 wxColor defaultColor = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
264 if (TextElement.IsSameAs(_(
"Console Legend")))
265 defaultColor = wxColour(0, 255, 0);
266 else if (TextElement.IsSameAs(_(
"Console Value")))
267 defaultColor = wxColour(0, 255, 0);
268 else if (TextElement.IsSameAs(_(
"Marks")))
269 defaultColor = wxColour(0, 0, 0);
270 else if (TextElement.IsSameAs(_(
"RouteLegInfoRollover")))
271 defaultColor = wxColour(0, 0, 0);
272 else if (TextElement.IsSameAs(_(
"AISRollover")))
273 defaultColor = wxColour(0, 0, 0);
274 else if (TextElement.IsSameAs(_(
"ExtendedTideIcon")))
275 defaultColor = wxColour(0, 0, 0);
276 else if (TextElement.IsSameAs(_(
"ChartTexts")))
277 defaultColor = wxColour(0, 0, 0);
278 else if (TextElement.IsSameAs(_(
"AIS Target Name")))
279 defaultColor = wxColour(0, 0, 0);
282 return wxColour(0, 0, 0);
288wxString FontMgr::GetSimpleNativeFont(
int size, wxString face) {
293 nativefont = wxFont(size, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL,
294 wxFONTWEIGHT_NORMAL,
false, face)
295 .GetNativeFontInfoDesc();
323 auto it = m_fontlist->begin();
325 return (*it)->m_configstring;
329 auto it = m_fontlist->begin();
331 return (*it)->m_dialogstring;
335 std::set<wxString> uniqueStrings;
337 for (
auto node = m_fontlist->begin(); node != m_fontlist->end(); ++node) {
339 if (locale.IsEmpty() || pmfd->
m_configstring.BeforeFirst(
'-') == locale) {
343 wxArrayString strings;
344 strings.reserve(uniqueStrings.size());
345 for (
const auto &str : uniqueStrings) {
353 auto it = m_fontlist->begin();
355 return (*it)->m_nativeInfo;
359 auto it = m_fontlist->begin();
367 wxString cols(
"rgb(0,0,0)");
368 if (pfd->
m_color.IsOk()) cols = pfd->
m_color.GetAsString(wxC2S_CSS_SYNTAX);
376 for (
auto node = m_fontlist->begin(); node != m_fontlist->end(); ++node) {
388 wxStringTokenizer tk(*pNativeDesc,
":");
389 wxString dialogstring = tk.GetNextToken();
390 wxString nativefont = tk.GetNextToken();
392 wxString c = tk.GetNextToken();
396 auto node = m_fontlist->begin();
397 for (; node != m_fontlist->end(); ++node) {
410 if (node == m_fontlist->end()) {
411 wxFont *nf0 =
new wxFont();
414 wxFont *nf =
new wxFont(nativefont);
416 wxFont *nf = nf0->New(nativefont);
419 double font_size = nf->GetPointSize();
420 wxString s = nf->GetNativeFontInfoDesc();
424 wxString face = nf->GetFaceName();
425 const wxChar *t = face.c_str();
428 wxString substitute_native = GetSimpleNativeFont(12,
"");
429 nf = nf0->New(substitute_native);
435 new MyFontDesc(dialogstring, *pConfigString, nf, color);
436 m_fontlist->push_back(pnewfd);
441 wxFontStyle style, wxFontWeight weight,
442 bool underline,
const wxString &facename,
443 wxFontEncoding encoding) {
445 return m_wxFontCache->FindOrCreateFont(point_size, family, style, weight,
446 underline, facename, encoding);
450 wxFontFamily family, wxFontStyle style,
451 wxFontWeight weight,
bool underline,
452 const wxString &facename,
453 wxFontEncoding encoding) {
454 if (record.pointsize_req == pointSize && record.style_req == style &&
455 record.weight_req == weight && record.underline_req == underline) {
458 wxFont *font = record.font;
464 if (!facename.empty()) {
465 const wxString &fontFace = font->GetFaceName();
468 same = !fontFace || fontFace == facename;
470 same = font->GetFamily() == family;
472 if (same && (encoding != wxFONTENCODING_DEFAULT)) {
474 same = font->GetEncoding() == encoding;
481wxFont *OCPNwxFontList::FindOrCreateFont(
int pointSize, wxFontFamily family,
482 wxFontStyle style, wxFontWeight weight,
484 const wxString &facename,
485 wxFontEncoding encoding) {
494 if (family == wxFONTFAMILY_DEFAULT) family = wxFONTFAMILY_SWISS;
498 for (
size_t i = 0; i < m_fontVector.size(); i++) {
500 if (isCached(record, pointSize, family, style, weight, underline, facename,
510 weight, underline, facename, encoding);
511 if (fontTmp.IsOk()) {
512 font =
new wxFont(fontTmp);
515 record.pointsize_req = pointSize;
516 record.style_req = style;
517 record.weight_req = weight;
518 record.underline_req = underline;
519 m_fontVector.push_back(record);
525void OCPNwxFontList::FreeAll() {
527 for (
size_t i = 0; i < m_fontVector.size(); i++) {
532 m_fontVector.clear();
535static wxString FontCandidates[] = {_(
"AISTargetAlert"),
538 _(
"AIS Target Name"),
540 _(
"RouteLegInfoRollover"),
541 _(
"ExtendedTideIcon"),
546 _(
"TideCurrentGraphRollover"),
556 wxString now_locale = g_locale;
557 wxArrayString string_array;
560 wxArrayString candidateArray;
565 wxString candidate = FontCandidates[i];
566 if (candidate ==
"END_OF_LIST") {
570 candidateArray.Add(candidate);
575 for (
unsigned int i = 0; i < m_AuxKeyArray.GetCount(); i++) {
576 candidateArray.Add(m_AuxKeyArray[i]);
579 for (
unsigned int i = 0; i < candidateArray.GetCount(); i++) {
580 wxString candidate = candidateArray[i];
588 wxString trans = wxGetTranslation(candidate);
590 for (
auto node = m_fontlist->begin(); node != m_fontlist->end(); node++) {
593 if (tlocale == now_locale) {
606 for (
auto node = m_fontlist->begin(); node != m_fontlist->end(); node++) {
609 if (tlocale == now_locale) {
611 for (
unsigned int i = 0; i < string_array.GetCount(); i++) {
625 auto node = m_fontlist->begin();
626 while (node != m_fontlist->end()) {
629 auto found = std::find(m_fontlist->begin(), m_fontlist->end(), pmfd);
630 if (found != m_fontlist->end()) m_fontlist->erase(found);
631 node = m_fontlist->begin();
641 wxString candidate = FontCandidates[i];
642 if (candidate ==
"END_OF_LIST") {
646 GetFont(wxGetTranslation(candidate));
652 for (
unsigned int i = 0; i < m_AuxKeyArray.GetCount(); i++) {
653 if (m_AuxKeyArray[i] == key)
return false;
655 m_AuxKeyArray.Add(key);
661 int size = g_default_font_size ? g_default_font_size : GetSystemFontSize();
663 : GetSystemFontFaceName();
664 wxString native = GetSimpleNativeFont(size, face);
665 wxFont *defaultFont = wxFont::New(native);
671 desc->
m_font = defaultFont;
wxFont * FindOrCreateFont(int point_size, wxFontFamily family, wxFontStyle style, wxFontWeight weight, bool underline=false, const wxString &facename=wxEmptyString, wxFontEncoding encoding=wxFONTENCODING_DEFAULT)
Creates or finds a matching font in the font cache.
wxString GetFullConfigDesc(int i) const
Gets description of font at index i.
wxColour GetFontColor(const wxString &TextElement) const
Gets the text color for a UI element.
bool AddAuxKey(wxString key)
Adds new plugin-defined font configuration key.
bool ResetFontToDefault(const wxString &TextElement)
Resets the font configuration for a UI element back to system defaults.
void LoadFontNative(wxString *pConfigString, wxString *pNativeDesc)
Loads font settings from a string descriptor.
bool SetFontColor(const wxString &TextElement, const wxColour color) const
Sets the text color for a UI element.
static wxString GetFontConfigKey(const wxString &description)
Creates configuration key from UI element name by combining locale with hash.
bool SetFont(const wxString &TextElement, wxFont *pFont, wxColour color)
Sets the default font properties for a UI element.
int GetNumFonts(void) const
Gets the total number of font configurations currently loaded.
wxColour GetDefaultFontColor(const wxString &TextElement)
Gets the default text color for a UI element.
void ScrubList()
Cleans up stale font entries after a locale change.
wxArrayString GetDialogStrings(const wxString &locale=wxEmptyString) const
Gets the list of unique dialog strings.
MyFontDesc * FindFontByConfigString(wxString pConfigString)
Finds font descriptor by its configuration key.
const wxString & GetNativeDesc(int i) const
Gets the native font descriptor string for the font at index i.
const wxString & GetConfigString(int i) const
Gets the locale-specific configuration key for a font at index i.
wxFont * GetFont(const wxString &TextElement, int requested_font_size=0)
Get a font object for a UI element.
const wxString & GetDialogString(int i) const
Gets the UI element identifier string for the font at index i.
wxString m_nativeInfo
Platform-specific font descriptor string.
wxString m_dialogstring
UI element identifier, e.g., "AISTargetAlert", "StatusBar".
wxString m_configstring
Configuration key in "locale-hash" format.
wxFont * m_font
Font object.
wxColour m_color
Text color.
bool m_is_default
Indicates if this is the default font entry for the TextElement.
wxString g_default_font_facename
Default font size for user interface elements such as menus, dialogs, etc.
Global variables stored in configuration file.
PlugIn Object Definition/API.
double OCPN_GetDisplayContentScaleFactor()
Gets content scaling factor for current display.