#include <qglobal.h>
#include <qfontmetrics.h>
+#include <qfontdatabase.h>
+#include <qstringlist.h>
#include "support/lstrings.h"
#ifdef Q_WS_X11
using std::endl;
-qfont_loader::qfont_loader()
+namespace {
+
+void addFontPath()
{
- for (int i1 = 0; i1 < LyXFont::NUM_FAMILIES; ++i1) {
- for (int i2 = 0; i2 < 2; ++i2) {
- for (int i3 = 0; i3 < 4; ++i3) {
- for (int i4 = 0; i4 < 10; ++i4) {
- fontinfo_[i1][i2][i3][i4] = 0;
- }
- }
- }
+#ifdef Q_WS_X11
+ string const dir = OnlyPath(LibFileSearch("xfonts", "fonts.dir"));
+ if (!dir.empty()) {
+ QWidget w;
+ int n;
+ char ** p = XGetFontPath(w.x11Display(), &n);
+ if (std::find(p, p + n, dir) != p + n)
+ return;
+ lyxerr << "Adding " << dir << " to the font path.\n";
+ string const command = "xset fp+ " + dir;
+ Systemcall s;
+ if (!s.startscript(Systemcall::Wait, command))
+ return;
+ lyxerr << "Unable to add font path.\n";
}
+#endif
}
-qfont_loader::~qfont_loader()
+struct symbol_font {
+ LyXFont::FONT_FAMILY lyx_family;
+ string family;
+ string xlfd;
+};
+
+symbol_font symbol_fonts[] = {
+ { LyXFont::SYMBOL_FAMILY,
+ "symbol",
+ "-*-symbol-*-*-*-*-*-*-*-*-*-*-adobe-fontspecific" },
+
+ { LyXFont::CMR_FAMILY,
+ "cmr10",
+ "-*-cmr10-medium-*-*-*-*-*-*-*-*-*-*-*" },
+
+ { LyXFont::CMSY_FAMILY,
+ "cmsy10",
+ "-*-cmsy10-*-*-*-*-*-*-*-*-*-*-*-*" },
+
+ { LyXFont::CMM_FAMILY,
+ "cmmi10",
+ "-*-cmmi10-medium-*-*-*-*-*-*-*-*-*-*-*" },
+
+ { LyXFont::CMEX_FAMILY,
+ "cmex10",
+ "-*-cmex10-*-*-*-*-*-*-*-*-*-*-*-*" },
+
+ { LyXFont::MSA_FAMILY,
+ "msam10",
+ "-*-msam10-*-*-*-*-*-*-*-*-*-*-*-*" },
+
+ { LyXFont::MSB_FAMILY,
+ "msbm10",
+ "-*-msbm10-*-*-*-*-*-*-*-*-*-*-*-*" },
+
+ { LyXFont::EUFRAK_FAMILY,
+ "eufm10",
+ "-*-eufm10-medium-*-*-*-*-*-*-*-*-*-*-*" },
+
+ { LyXFont::WASY_FAMILY,
+ "wasy10",
+ "-*-wasy10-medium-*-*-*-*-*-*-*-*-*-*-*" }
+};
+
+size_t const nr_symbol_fonts = sizeof(symbol_fonts) / sizeof(symbol_font);
+
+
+string getRawName(string const & family)
{
+ for (size_t i = 0; i < nr_symbol_fonts; ++i) {
+ if (family == symbol_fonts[i].family)
+ return symbol_fonts[i].xlfd;
+ }
+ lyxerr[Debug::FONT] << "BUG: family not found !" << endl;
+ return string();
}
-void qfont_loader::update()
+string const symbolFamily(LyXFont::FONT_FAMILY family)
{
- for (int i1 = 0; i1 < LyXFont::NUM_FAMILIES; ++i1) {
- for (int i2 = 0; i2 < 2; ++i2) {
- for (int i3 = 0; i3 < 4; ++i3) {
- for (int i4 = 0; i4 < 10; ++i4) {
- delete fontinfo_[i1][i2][i3][i4];
- fontinfo_[i1][i2][i3][i4] = 0;
- }
- }
- }
+ for (size_t i = 0; i < nr_symbol_fonts; ++i) {
+ if (family == symbol_fonts[i].lyx_family)
+ return symbol_fonts[i].family;
}
+ return string();
}
-QFont const & qfont_loader::get(LyXFont const & f)
+QFont const getSymbolFont(string const & family)
{
- QFont const & ret(getfontinfo(f)->font);
+ lyxerr[Debug::FONT] << "Looking for font family "
+ << family << " ... ";
+ string upper = family;
+ upper[0] = toupper(family[0]);
+
+ QFont font;
+ font.setFamily(toqstr(family));
+
+ // Note Qt lies about family, so we use rawName.
+ if (contains(fromqstr(font.rawName()), family)) {
+ lyxerr[Debug::FONT] << " got it !" << endl;
+ return font;
+ }
- if (lyxerr.debugging(Debug::FONT)) {
- lyxerr[Debug::FONT] << "Font '" << f.stateText(0)
- << "' matched by\n" << ret.rawName() << endl;
+ font.setFamily(toqstr(upper));
+
+ if (contains(fromqstr(font.rawName()), upper)) {
+ lyxerr[Debug::FONT] << " got it (uppercase version) !" << endl;
+ return font;
}
- lyxerr[Debug::FONT] << "The font has size: "
- << ret.pointSizeFloat() << endl;
+ // A simple setFamily() fails on Qt 2
- return ret;
+ font.setRawName(toqstr(getRawName(family)));
+
+ if (contains(fromqstr(font.rawName()), family)) {
+ lyxerr[Debug::FONT] << " got it (raw version) !" << endl;
+ return font;
+ }
+
+ lyxerr[Debug::FONT] << " FAILED :(" << endl;
+ return font;
}
-namespace {
-string const symbolPattern(LyXFont::FONT_FAMILY family)
+bool isAvailable(LyXFont const & f)
{
- switch (family) {
- case LyXFont::SYMBOL_FAMILY:
- return "-*-symbol-*-*-*-*-*-*-*-*-*-*-adobe-fontspecific";
+ string const tmp = symbolFamily(f.family());
- case LyXFont::CMR_FAMILY:
- return "-*-cmr10-medium-*-*-*-*-*-*-*-*-*-*-*";
+ if (tmp.empty())
+ return false;
- case LyXFont::CMSY_FAMILY:
- return "-*-cmsy10-*-*-*-*-*-*-*-*-*-*-*-*";
+ QString const family(toqstr(tmp));
- case LyXFont::CMM_FAMILY:
- return "-*-cmmi10-medium-*-*-*-*-*-*-*-*-*-*-*";
+ lyxerr[Debug::FONT] << "Family " << tmp
+ << " isAvailable ?" << endl;
- case LyXFont::CMEX_FAMILY:
- return "-*-cmex10-*-*-*-*-*-*-*-*-*-*-*-*";
+ QFontDatabase db;
+ // pass false for match-locale: LaTeX fonts
+ // do not have non-matching locale according
+ // to Qt 2
+ QStringList sl(db.families(false));
- case LyXFont::MSA_FAMILY:
- return "-*-msam10-*-*-*-*-*-*-*-*-*-*-*-*";
+ for (QStringList::Iterator it = sl.begin(); it != sl.end(); ++it) {
- case LyXFont::MSB_FAMILY:
- return "-*-msbm10-*-*-*-*-*-*-*-*-*-*-*-*";
+ // Case-insensitive for Cmmi10 vs. cmmi10
+ if ((*it).contains(family, false)) {
+ lyxerr[Debug::FONT]
+ << "found family "
+ << fromqstr(*it) << endl;
+ return true;
+ }
+ }
- case LyXFont::EUFRAK_FAMILY:
- return "-*-eufm10-medium-*-*-*-*-*-*-*-*-*-*-*";
+ return false;
+}
- case LyXFont::WASY_FAMILY:
- return "-*-wasy10-medium-*-*-*-*-*-*-*-*-*-*-*";
- default:
- return string();
+} // namespace anon
+
+
+qfont_loader::qfont_loader()
+{
+ for (int i1 = 0; i1 < LyXFont::NUM_FAMILIES; ++i1) {
+ for (int i2 = 0; i2 < 2; ++i2) {
+ for (int i3 = 0; i3 < 4; ++i3) {
+ for (int i4 = 0; i4 < 10; ++i4) {
+ fontinfo_[i1][i2][i3][i4] = 0;
+ }
+ }
+ }
}
}
-bool addFontPath()
+
+qfont_loader::~qfont_loader()
{
-#ifdef Q_WS_X11
- string const dir = OnlyPath(LibFileSearch("xfonts", "fonts.dir"));
- if (!dir.empty()) {
- QWidget w;
- int n;
- char ** p = XGetFontPath(w.x11Display(), &n);
- if (std::find(p, p + n, dir) != p + n)
- return false;
- lyxerr << "Adding " << dir << " to the font path.\n";
- string const command = "xset fp+ " + dir;
- Systemcall s;
- if (!s.startscript(Systemcall::Wait, command))
- return true;
- lyxerr << "Unable to add font path.\n";
- }
-#endif
- return false;
}
-bool isAvailable(QFont const & font, LyXFont const & f)
+void qfont_loader::update()
{
- string tmp = symbolPattern(f.family());
- if (tmp.empty())
- return false;
- else {
- bool const found(token(tmp, '-', 2) ==
- token(fromqstr(font.rawName()), '-', 2));
- lyxerr[Debug::FONT] << "Looking for symbol font \n\""
- << tmp << "\" and got \n\"" << fromqstr(font.rawName())
- << "\"\n match: " << found << endl;
- return found;
+ for (int i1 = 0; i1 < LyXFont::NUM_FAMILIES; ++i1) {
+ for (int i2 = 0; i2 < 2; ++i2) {
+ for (int i3 = 0; i3 < 4; ++i3) {
+ for (int i4 = 0; i4 < 10; ++i4) {
+ delete fontinfo_[i1][i2][i3][i4];
+ fontinfo_[i1][i2][i3][i4] = 0;
+ }
+ }
+ }
}
}
-} // namespace anon
+
+QFont const & qfont_loader::get(LyXFont const & f)
+{
+ static bool first_call = true;
+
+ if (first_call) {
+ first_call = false;
+ addFontPath();
+ }
+
+ QFont const & ret(getfontinfo(f)->font);
+
+ return ret;
+}
qfont_loader::font_info::font_info(LyXFont const & f)
: metrics(font)
{
- string pat = symbolPattern(f.family());
+ string const pat = symbolFamily(f.family());
if (!pat.empty()) {
- static bool first_time = true;
- font.setRawName(toqstr(pat));
- if (f.family() != LyXFont::SYMBOL_FAMILY &&
- !isAvailable(font, f) && first_time) {
- first_time = false;
- if (addFontPath()) {
- font.setRawName(toqstr(pat));
- }
- }
+ font = getSymbolFont(pat);
} else {
switch (f.family()) {
case LyXFont::ROMAN_FAMILY:
case LyXFont::BOLD_SERIES:
font.setWeight(QFont::Bold);
break;
+ default:
+ break;
}
switch (f.realShape()) {
case LyXFont::SLANTED_SHAPE:
font.setItalic(true);
break;
+ default:
+ break;
+ }
+
+ if (lyxerr.debugging(Debug::FONT)) {
+ lyxerr[Debug::FONT] << "Font '" << f.stateText(0)
+ << "' matched by\n" << font.rawName() << endl;
}
+ lyxerr[Debug::FONT] << "The font has size: "
+ << font.pointSizeFloat() << endl;
+
// Is this an exact match?
if (font.exactMatch()) {
lyxerr[Debug::FONT] << "This font is an exact match" << endl;
if (!lyxrc.use_gui)
return false;
- bool const is_available(isAvailable(getfontinfo(f)->font, f));
+ bool const is_available(isAvailable(f));
lyxerr[Debug::FONT] << "font_loader::available returning "
<< is_available << endl;
return is_available;