2003-09-02 10:29:05 +00:00
|
|
|
/**
|
|
|
|
* \file xftFontLoader.C
|
|
|
|
* This file is part of LyX, the document processor.
|
|
|
|
* Licence details can be found in the file COPYING.
|
|
|
|
*
|
|
|
|
* \author Huang Ying
|
|
|
|
*
|
2003-09-02 17:02:32 +00:00
|
|
|
* Full author contact details are available in file CREDITS.
|
2003-09-02 10:29:05 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
2004-11-16 23:18:46 +00:00
|
|
|
// Too hard to make concept checks work with this file
|
|
|
|
#ifdef _GLIBCPP_CONCEPT_CHECKS
|
|
|
|
#undef _GLIBCPP_CONCEPT_CHECKS
|
|
|
|
#endif
|
|
|
|
|
2003-09-02 10:29:05 +00:00
|
|
|
#include "xftFontLoader.h"
|
|
|
|
#include "FontInfo.h"
|
|
|
|
#include "gettext.h"
|
|
|
|
#include "debug.h"
|
|
|
|
#include "lyxrc.h" // lyxrc.font_*
|
|
|
|
#include "BufferView.h"
|
2004-09-26 13:18:29 +00:00
|
|
|
#include "GtkmmX.h"
|
|
|
|
|
2003-09-02 10:29:05 +00:00
|
|
|
#include "frontends/LyXView.h"
|
2004-09-26 13:18:29 +00:00
|
|
|
#include "frontends/lyx_gui.h"
|
|
|
|
|
2005-01-27 21:05:44 +00:00
|
|
|
#include "support/convert.h"
|
2005-01-05 10:54:31 +00:00
|
|
|
#include "support/lstrings.h"
|
2003-09-02 10:29:05 +00:00
|
|
|
#include "support/systemcall.h"
|
|
|
|
#include "support/filetools.h"
|
2004-09-26 13:18:29 +00:00
|
|
|
|
|
|
|
#include <cmath> // fabs()
|
2003-09-02 10:29:05 +00:00
|
|
|
#include <vector>
|
2004-09-26 13:18:29 +00:00
|
|
|
|
2003-09-02 10:29:05 +00:00
|
|
|
using std::endl;
|
2003-10-06 15:43:21 +00:00
|
|
|
using std::string;
|
2003-09-02 10:29:05 +00:00
|
|
|
|
|
|
|
// The global fontLoader
|
|
|
|
xftFontLoader fontLoader;
|
|
|
|
|
|
|
|
|
|
|
|
// Initialize font loader
|
|
|
|
xftFontLoader::xftFontLoader()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Destroy font loader
|
|
|
|
xftFontLoader::~xftFontLoader()
|
|
|
|
{
|
|
|
|
unload();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Update fonts after zoom, dpi, font names, or norm change
|
|
|
|
// For now, we just ditch all fonts we have. Later, we should
|
|
|
|
// reuse the ones that are already loaded.
|
|
|
|
void xftFontLoader::update()
|
|
|
|
{
|
|
|
|
unload();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Unload all fonts
|
|
|
|
void xftFontLoader::unload()
|
|
|
|
{
|
|
|
|
// Unload all fonts
|
|
|
|
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) {
|
|
|
|
if (fonts_[i1][i2][i3][i4]){
|
|
|
|
XftFontClose(getDisplay(), fonts_[i1][i2][i3][i4]);
|
|
|
|
fonts_[i1][i2][i3][i4] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
string xftFontLoader::familyString(LyXFont::FONT_FAMILY family)
|
|
|
|
{
|
|
|
|
string ffamily;
|
|
|
|
switch (family) {
|
|
|
|
case LyXFont::ROMAN_FAMILY:
|
|
|
|
ffamily = lyxrc.roman_font_name;
|
|
|
|
break;
|
|
|
|
case LyXFont::SANS_FAMILY:
|
|
|
|
ffamily = lyxrc.sans_font_name;
|
|
|
|
break;
|
|
|
|
case LyXFont::TYPEWRITER_FAMILY:
|
|
|
|
ffamily = lyxrc.typewriter_font_name;
|
|
|
|
break;
|
|
|
|
case LyXFont::CMR_FAMILY:
|
|
|
|
ffamily = "cmr10";
|
|
|
|
break;
|
|
|
|
case LyXFont::CMSY_FAMILY:
|
|
|
|
ffamily = "cmsy10";
|
|
|
|
break;
|
|
|
|
case LyXFont::CMM_FAMILY:
|
|
|
|
ffamily = "cmmi10";
|
|
|
|
break;
|
|
|
|
case LyXFont::CMEX_FAMILY:
|
|
|
|
ffamily = "cmex10";
|
|
|
|
break;
|
|
|
|
case LyXFont::MSA_FAMILY:
|
|
|
|
ffamily = "msam10";
|
|
|
|
break;
|
|
|
|
case LyXFont::MSB_FAMILY:
|
|
|
|
ffamily = "msbm10";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ffamily = "Sans";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return ffamily;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Get font pattern
|
|
|
|
/* Takes care of finding which font that can match the given request. Tries
|
|
|
|
different alternatives. */
|
|
|
|
XftPattern * xftFontLoader::getFontPattern(LyXFont::FONT_FAMILY family,
|
|
|
|
LyXFont::FONT_SERIES series,
|
|
|
|
LyXFont::FONT_SHAPE shape,
|
|
|
|
LyXFont::FONT_SIZE size)
|
|
|
|
{
|
|
|
|
// Normal font. Let's search for an existing name that matches.
|
|
|
|
string ffamily;
|
|
|
|
int fweight;
|
|
|
|
int fslant;
|
2005-01-27 21:05:44 +00:00
|
|
|
double fsize = convert<double>(lyxrc.font_sizes[size]) * lyxrc.zoom / 100.0;
|
2003-09-02 10:29:05 +00:00
|
|
|
XftPattern *fpat = XftPatternCreate();
|
|
|
|
|
|
|
|
ffamily = familyString(family);
|
|
|
|
switch (series) {
|
|
|
|
case LyXFont::MEDIUM_SERIES:
|
|
|
|
fweight = XFT_WEIGHT_MEDIUM;
|
|
|
|
break;
|
|
|
|
case LyXFont::BOLD_SERIES:
|
|
|
|
fweight = XFT_WEIGHT_BOLD;
|
|
|
|
break;
|
2003-09-09 18:27:24 +00:00
|
|
|
default:
|
2003-09-02 10:29:05 +00:00
|
|
|
fweight = XFT_WEIGHT_MEDIUM;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (shape) {
|
|
|
|
case LyXFont::UP_SHAPE:
|
|
|
|
case LyXFont::SMALLCAPS_SHAPE:
|
|
|
|
fslant = XFT_SLANT_ROMAN;
|
|
|
|
break;
|
|
|
|
case LyXFont::ITALIC_SHAPE:
|
|
|
|
fslant = XFT_SLANT_ITALIC;
|
|
|
|
break;
|
|
|
|
case LyXFont::SLANTED_SHAPE:
|
|
|
|
fslant = XFT_SLANT_OBLIQUE;
|
|
|
|
break;
|
2003-09-09 18:27:24 +00:00
|
|
|
default:
|
2003-09-02 10:29:05 +00:00
|
|
|
fslant = XFT_SLANT_ROMAN;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
XftPatternAddString(fpat, XFT_FAMILY, ffamily.c_str());
|
|
|
|
XftPatternAddInteger(fpat, XFT_WEIGHT, fweight);
|
|
|
|
XftPatternAddInteger(fpat, XFT_SLANT, fslant);
|
|
|
|
XftPatternAddDouble(fpat, XFT_SIZE, fsize);
|
|
|
|
return fpat;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Do load font
|
|
|
|
XftFont * xftFontLoader::doLoad(LyXFont::FONT_FAMILY family,
|
|
|
|
LyXFont::FONT_SERIES series,
|
|
|
|
LyXFont::FONT_SHAPE shape,
|
|
|
|
LyXFont::FONT_SIZE size)
|
|
|
|
{
|
2004-09-26 13:18:29 +00:00
|
|
|
XftPattern * fpat = getFontPattern(family, series, shape, size);
|
2003-09-02 10:29:05 +00:00
|
|
|
XftResult result;
|
2004-09-26 13:18:29 +00:00
|
|
|
XftPattern * fpat2 = XftFontMatch(getDisplay(), getScreen(),
|
|
|
|
fpat, &result);
|
2003-09-02 10:29:05 +00:00
|
|
|
XftFont * font = XftFontOpenPattern(getDisplay(), fpat2);
|
|
|
|
fonts_[family][series][shape][size] = font;
|
|
|
|
return font;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool xftFontLoader::available(LyXFont const & f)
|
|
|
|
{
|
|
|
|
if (!lyx_gui::use_gui)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
static std::vector<bool> cache_set(LyXFont::NUM_FAMILIES, false);
|
|
|
|
static std::vector<bool> cache(LyXFont::NUM_FAMILIES, false);
|
|
|
|
|
|
|
|
LyXFont::FONT_FAMILY family = f.family();
|
|
|
|
if (cache_set[family])
|
|
|
|
return cache[family];
|
|
|
|
cache_set[family] = true;
|
|
|
|
|
|
|
|
string const ffamily = familyString(family);
|
|
|
|
if (isSpecial(f)) {
|
|
|
|
cache_set[family] = true;
|
2004-09-26 13:18:29 +00:00
|
|
|
XftPattern * fpat = XftPatternCreate();
|
2003-09-02 10:29:05 +00:00
|
|
|
XftPatternAddString(fpat, XFT_FAMILY, ffamily.c_str());
|
|
|
|
XftResult result;
|
2004-09-26 13:18:29 +00:00
|
|
|
XftPattern * fpat2 = XftFontMatch(getDisplay(), getScreen(),
|
|
|
|
fpat, &result);
|
2003-09-02 10:29:05 +00:00
|
|
|
XftPatternDestroy(fpat);
|
|
|
|
char * familyM;
|
|
|
|
XftPatternGetString(fpat2, XFT_FAMILY, 0, &familyM);
|
|
|
|
if (ffamily == familyM) {
|
|
|
|
cache[family] = true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
// We don't need to set cache[family] to false, as it
|
|
|
|
// is initialized to false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
// We don't care about non-symbol fonts
|
|
|
|
return false;
|
|
|
|
}
|