28#include <wx/tokenzr.h>
31#include "OCPNPlatform.h"
37 wxFontStyle style_req;
38 wxFontWeight weight_req;
45 wxFont *FindOrCreateFont(
int pointSize, wxFontFamily family,
46 wxFontStyle style, wxFontWeight weight,
47 bool underline =
false,
48 const wxString &face = wxEmptyString,
49 wxFontEncoding encoding = wxFONTENCODING_DEFAULT);
54 wxFontStyle style, wxFontWeight weight,
bool underline,
55 const wxString &facename, wxFontEncoding encoding);
57 std::vector<font_cache_record> m_fontVector;
60extern wxString g_locale;
78int g_default_font_size;
79wxString g_default_font_facename;
81FontMgr *FontMgr::instance = NULL;
84 if (!instance) instance =
new FontMgr;
88void FontMgr::Shutdown() {
95FontMgr::FontMgr() : m_wxFontCache(NULL), m_fontlist(NULL), pDefFont(NULL) {
97 m_fontlist =
new FontList;
98 m_fontlist->DeleteContents(
true);
103 pDefFont = FindOrCreateFont(12, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL,
104 wxFONTWEIGHT_BOLD, FALSE, wxString(_T (
"" )),
105 wxFONTENCODING_SYSTEM);
112 delete m_wxFontCache;
115void FontMgr::SetLocale(wxString &newLocale) { s_locale = newLocale; }
119 return pmfd ? pmfd->
m_color : wxColour(0, 0, 0);
123 const wxColour color)
const {
138 configkey = s_locale;
139 configkey.Append(_T(
"-"));
143 const collate<char> &coll = use_facet<collate<char> >(loc);
148 wxCharBuffer abuf = description.ToUTF8();
150 int fdLen = strlen(abuf);
152 configkey.Append(wxString::Format(
153 _T(
"%08lx"), coll.hash(abuf.data(), abuf.data() + fdLen)));
157int FontMgr::GetSystemFontSize() {
158 static int sys_font_size = 0;
159 if (!sys_font_size) {
160 wxFont sys_font = *wxNORMAL_FONT;
161 sys_font_size = sys_font.GetPointSize();
163 return sys_font_size;
166wxString FontMgr::GetSystemFontFaceName() {
167 static wxString sys_font_facename;
168 if (sys_font_facename.IsEmpty()) {
169 wxFont sys_font = *wxNORMAL_FONT;
170 sys_font_facename = sys_font.GetFaceName();
172 return sys_font_facename;
175bool FontMgr::IsDefaultFontEntry(
const MyFontDesc *font_desc)
const {
187wxFont *FontMgr::GetFontLegacy(
const wxString &TextElement,
188 int user_default_size) {
191 auto node = m_fontlist->GetFirst();
193 pmfd = node->GetData();
198 node = node->GetNext();
200 return GetFont(TextElement, user_default_size);
206 auto node = m_fontlist->GetFirst();
209 pmfd = node->GetData();
213 if (requested_font_size == 0 && IsDefaultFontEntry(pmfd)) {
218 }
else if (requested_font_size != 0 &&
219 pmfd->
m_font->GetPointSize() == requested_font_size) {
223 node = node->GetNext();
233 if (0 == requested_font_size) {
234 new_size = g_default_font_size ? g_default_font_size : GetSystemFontSize();
236 new_size = requested_font_size;
238 wxString face_name = g_default_font_facename.Length()
239 ? g_default_font_facename
240 : GetSystemFontFaceName();
242 wxString nativefont = GetSimpleNativeFont(new_size, face_name);
243 wxFont *nf = wxFont::New(nativefont);
247 bool is_default = (requested_font_size == 0);
249 new MyFontDesc(TextElement, configkey, nf, color, is_default);
250 m_fontlist->Append(pnewfd);
255MyFontDesc *FontMgr::GetFontDesc(
const wxString &TextElement)
const {
258 auto node = m_fontlist->GetFirst();
260 pmfd = node->GetData();
265 node = node->GetNext();
269 node = m_fontlist->GetFirst();
271 pmfd = node->GetData();
276 node = node->GetNext();
283 wxColor defaultColor = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
286 if (TextElement.IsSameAs(_(
"Console Legend")))
287 defaultColor = wxColour(0, 255, 0);
288 else if (TextElement.IsSameAs(_(
"Console Value")))
289 defaultColor = wxColour(0, 255, 0);
290 else if (TextElement.IsSameAs(_(
"Marks")))
291 defaultColor = wxColour(0, 0, 0);
292 else if (TextElement.IsSameAs(_(
"RouteLegInfoRollover")))
293 defaultColor = wxColour(0, 0, 0);
294 else if (TextElement.IsSameAs(_(
"AISRollover")))
295 defaultColor = wxColour(0, 0, 0);
296 else if (TextElement.IsSameAs(_(
"ExtendedTideIcon")))
297 defaultColor = wxColour(0, 0, 0);
298 else if (TextElement.IsSameAs(_(
"ChartTexts")))
299 defaultColor = wxColour(0, 0, 0);
300 else if (TextElement.IsSameAs(_(
"AIS Target Name")))
301 defaultColor = wxColour(0, 0, 0);
304 return wxColour(0, 0, 0);
310wxString FontMgr::GetSimpleNativeFont(
int size, wxString face) {
315 nativefont = wxFont(size, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL,
316 wxFONTWEIGHT_NORMAL,
false, face)
317 .GetNativeFontInfoDesc();
345 MyFontDesc *pfd = m_fontlist->Item(i)->GetData();
350 MyFontDesc *pfd = m_fontlist->Item(i)->GetData();
355 std::set<wxString> uniqueStrings;
357 auto node = m_fontlist->GetFirst();
360 if (locale.IsEmpty() || pmfd->
m_configstring.BeforeFirst(
'-') == locale) {
363 node = node->GetNext();
365 wxArrayString strings;
366 strings.reserve(uniqueStrings.size());
367 for (
const auto &str : uniqueStrings) {
375 MyFontDesc *pfd = m_fontlist->Item(i)->GetData();
380 MyFontDesc *pfd = m_fontlist->Item(i)->GetData();
382 ret.Append(_T (
":" ));
384 ret.Append(_T (
":" ));
386 wxString cols(_T(
"rgb(0,0,0)"));
387 if (pfd->
m_color.IsOk()) cols = pfd->
m_color.GetAsString(wxC2S_CSS_SYNTAX);
396 auto node = m_fontlist->GetFirst();
399 pmfd = node->GetData();
403 node = node->GetNext();
412 wxStringTokenizer tk(*pNativeDesc, _T (
":" ));
413 wxString dialogstring = tk.GetNextToken();
414 wxString nativefont = tk.GetNextToken();
416 wxString c = tk.GetNextToken();
421 auto node = m_fontlist->GetFirst();
424 pmfd = node->GetData();
433 node = node->GetNext();
438 wxFont *nf0 =
new wxFont();
440#ifdef __OCPN__ANDROID__
441 wxFont *nf =
new wxFont(nativefont);
443 wxFont *nf = nf0->New(nativefont);
446 double font_size = nf->GetPointSize();
447 wxString s = nf->GetNativeFontInfoDesc();
451 wxString face = nf->GetFaceName();
452 const wxChar *t = face.c_str();
455 wxString substitute_native = GetSimpleNativeFont(12, _T(
""));
456 nf = nf0->New(substitute_native);
462 new MyFontDesc(dialogstring, *pConfigString, nf, color);
463 m_fontlist->Append(pnewfd);
468 wxFontStyle style, wxFontWeight weight,
469 bool underline,
const wxString &facename,
470 wxFontEncoding encoding) {
472 return m_wxFontCache->FindOrCreateFont(point_size, family, style, weight,
473 underline, facename, encoding);
477 wxFontFamily family, wxFontStyle style,
478 wxFontWeight weight,
bool underline,
479 const wxString &facename,
480 wxFontEncoding encoding) {
481 if (record.pointsize_req == pointSize && record.style_req == style &&
482 record.weight_req == weight && record.underline_req == underline) {
485 wxFont *font = record.font;
491 if (!facename.empty()) {
492 const wxString &fontFace = font->GetFaceName();
495 same = !fontFace || fontFace == facename;
497 same = font->GetFamily() == family;
499 if (same && (encoding != wxFONTENCODING_DEFAULT)) {
501 same = font->GetEncoding() == encoding;
508wxFont *OCPNwxFontList::FindOrCreateFont(
int pointSize, wxFontFamily family,
509 wxFontStyle style, wxFontWeight weight,
511 const wxString &facename,
512 wxFontEncoding encoding) {
521 if (family == wxFONTFAMILY_DEFAULT) family = wxFONTFAMILY_SWISS;
525 for (
size_t i = 0; i < m_fontVector.size(); i++) {
527 if (isCached(record, pointSize, family, style, weight, underline, facename,
537 weight, underline, facename, encoding);
538 if (fontTmp.IsOk()) {
539 font =
new wxFont(fontTmp);
542 record.pointsize_req = pointSize;
543 record.style_req = style;
544 record.weight_req = weight;
545 record.underline_req = underline;
546 m_fontVector.push_back(record);
552void OCPNwxFontList::FreeAll(
void) {
554 for (
size_t i = 0; i < m_fontVector.size(); i++) {
559 m_fontVector.clear();
562static wxString FontCandidates[] = {_(
"AISTargetAlert"),
565 _(
"AIS Target Name"),
567 _(
"RouteLegInfoRollover"),
568 _(
"ExtendedTideIcon"),
573 _(
"TideCurrentGraphRollover"),
583 wxString now_locale = g_locale;
584 wxArrayString string_array;
587 wxArrayString candidateArray;
592 wxString candidate = FontCandidates[i];
593 if (candidate == _T(
"END_OF_LIST")) {
597 candidateArray.Add(candidate);
602 for (
unsigned int i = 0; i < m_AuxKeyArray.GetCount(); i++) {
603 candidateArray.Add(m_AuxKeyArray[i]);
606 for (
unsigned int i = 0; i < candidateArray.GetCount(); i++) {
607 wxString candidate = candidateArray[i];
615 wxString trans = wxGetTranslation(candidate);
618 auto node = m_fontlist->GetFirst();
620 pmfd = node->GetData();
622 if (tlocale == now_locale) {
628 node = node->GetNext();
638 auto node = m_fontlist->GetFirst();
640 pmfd = node->GetData();
642 if (tlocale == now_locale) {
644 for (
unsigned int i = 0; i < string_array.GetCount(); i++) {
656 node = node->GetNext();
660 node = m_fontlist->GetFirst();
662 pmfd = node->GetData();
664 bool bd = m_fontlist->DeleteObject(pmfd);
665 if (bd) node = m_fontlist->GetFirst();
667 node = node->GetNext();
674 wxString candidate = FontCandidates[i];
675 if (candidate == _T(
"END_OF_LIST")) {
679 GetFont(wxGetTranslation(candidate));
685 for (
unsigned int i = 0; i < m_AuxKeyArray.GetCount(); i++) {
686 if (m_AuxKeyArray[i] == key)
return false;
688 m_AuxKeyArray.Add(key);
694 int size = g_default_font_size ? g_default_font_size : GetSystemFontSize();
695 wxString face = g_default_font_facename.Length() ? g_default_font_facename
696 : GetSystemFontFaceName();
697 wxString native = GetSimpleNativeFont(size, face);
698 wxFont *defaultFont = wxFont::New(native);
704 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)
Gets 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.
PlugIn Object Definition/API.
double OCPN_GetDisplayContentScaleFactor()
Gets content scaling factor for current display.