summaryrefslogtreecommitdiff
path: root/indra/llwindow/llwindowsdl.cpp
diff options
context:
space:
mode:
authorAdam Moss <moss@lindenlab.com>2008-04-17 14:56:00 +0000
committerAdam Moss <moss@lindenlab.com>2008-04-17 14:56:00 +0000
commit669d1162f4c7529296d7018ec65960f120cc1c3e (patch)
tree807a035b4ee593587923e040b49bd5a6a8dc42cf /indra/llwindow/llwindowsdl.cpp
parenta3f3ab7e113e44309461b26399d627814f0ce4f9 (diff)
QAR-460 Automatic XUI selection & Kick-ass Linux Fonts MergeMe
svn merge svn+ssh://svn.lindenlab.com/svn/linden/release@84983 svn+ssh://svn.lindenlab.com/svn/linden/branches/moss/fontconfig-merge1
Diffstat (limited to 'indra/llwindow/llwindowsdl.cpp')
-rw-r--r--indra/llwindow/llwindowsdl.cpp98
1 files changed, 95 insertions, 3 deletions
diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp
index 519e0e8ec8..5ed6094f4a 100644
--- a/indra/llwindow/llwindowsdl.cpp
+++ b/indra/llwindow/llwindowsdl.cpp
@@ -39,6 +39,7 @@
#include "llgl.h"
#include "llstring.h"
#include "lldir.h"
+#include "llfindlocale.h"
#include "llglheaders.h"
@@ -51,6 +52,10 @@ extern "C" {
#include <locale.h>
#endif // LL_GTK
+extern "C" {
+# include "fontconfig/fontconfig.h"
+}
+
#if LL_LINUX || LL_SOLARIS
// not necessarily available on random SDL platforms, so #if LL_LINUX
// for execv(), waitpid(), fork()
@@ -2027,7 +2032,8 @@ void LLWindowSDL::gatherInput()
// the locale to protect it, as exotic/non-C locales
// causes our code lots of general critical weirdness
// and crashness. (SL-35450)
- std::string saved_locale = setlocale(LC_ALL, NULL);
+ static std::string saved_locale;
+ saved_locale = ll_safe_string(setlocale(LC_ALL, NULL));
// Pump until we've nothing left to do or passed 1/15th of a
// second pumping for this frame.
@@ -2748,8 +2754,8 @@ void spawn_web_browser(const char* escaped_url)
# endif // LL_X11
std::string cmd;
- cmd = gDirUtilp->getAppRODataDir().c_str();
- cmd += gDirUtilp->getDirDelimiter().c_str();
+ cmd = gDirUtilp->getAppRODataDir();
+ cmd += gDirUtilp->getDirDelimiter();
cmd += "launch_url.sh";
char* const argv[] = {(char*)cmd.c_str(), (char*)escaped_url, NULL};
@@ -2826,4 +2832,90 @@ void LLWindowSDL::bringToFront()
#endif // LL_X11
}
+//static
+std::string LLWindowSDL::getFontListSans()
+{
+ // Use libfontconfig to find us a nice ordered list of fallback fonts
+ // specific to this system.
+ std::string final_fallback("/usr/share/fonts/truetype/kochi/kochi-gothic.ttf");
+ // Our 'ideal' font properties which define the sorting results.
+ // slant=0 means Roman, index=0 means the first face in a font file
+ // (the one we actually use), weight=80 means medium weight,
+ // spacing=0 means proportional spacing.
+ std::string sort_order("slant=0:index=0:weight=80:spacing=0");
+ // elide_unicode_coverage removes fonts from the list whose unicode
+ // range is covered by fonts earlier in the list. This usually
+ // removes ~90% of the fonts as redundant (which is great because
+ // the font list can be huge), but might unnecessarily reduce the
+ // renderable range if for some reason our FreeType actually fails
+ // to use some of the fonts we want it to.
+ const bool elide_unicode_coverage = true;
+ std::string rtn;
+ FcFontSet *fs = NULL;
+ FcPattern *sortpat = NULL;
+ int font_count = 0;
+
+ llinfos << "Getting system font list from FontConfig..." << llendl;
+
+ // If the user has a system-wide language preference, then favor
+ // fonts from that language group. This doesn't affect the types
+ // of languages that can be displayed, but ensures that their
+ // preferred language is rendered from a single consistent font where
+ // possible.
+ FL_Locale *locale = NULL;
+ FL_Success success = FL_FindLocale(&locale, FL_MESSAGES);
+ if (success != 0)
+ {
+ if (success >= 2 && locale->lang) // confident!
+ {
+ llinfos << "Preferring fonts of language: "
+ << locale->lang
+ << llendl;
+ sort_order = "lang=" + std::string(locale->lang) + ":"
+ + sort_order;
+ }
+ FL_FreeLocale(&locale);
+ }
+
+ if (!FcInit())
+ {
+ llwarns << "FontConfig failed to initialize." << llendl;
+ return final_fallback;
+ }
+
+ sortpat = FcNameParse((FcChar8*) sort_order.c_str());
+ if (sortpat)
+ {
+ // Sort the list of system fonts from most-to-least-desirable.
+ fs = FcFontSort(NULL, sortpat, elide_unicode_coverage,
+ NULL, NULL);
+ FcPatternDestroy(sortpat);
+ }
+
+ if (fs)
+ {
+ // Get the full pathnames to the fonts, where available,
+ // which is what we really want.
+ int i;
+ for (i=0; i<fs->nfont; ++i)
+ {
+ FcChar8 *filename;
+ if (FcResultMatch == FcPatternGetString(fs->fonts[i],
+ FC_FILE, 0,
+ &filename)
+ && filename)
+ {
+ rtn += std::string((const char*)filename)+";";
+ ++font_count;
+ }
+ }
+ FcFontSetDestroy (fs);
+ }
+
+ lldebugs << "Using font list: " << rtn << llendl;
+ llinfos << "Using " << font_count << " system font(s)." << llendl;
+
+ return rtn + final_fallback;
+}
+
#endif // LL_SDL