Work around broken math symbol display (bug 7954)

This extends the already existing math symbol fallback mechanism in two ways:
1) When considering the availability of the math font, also take broken
   code points into account. These are currently 0x0009 and 0x00ad, depending
   on the platform.
2) If the fallback symbol in the standard "Symbol" font is not given, or if
   the "Symbol" font is not available, or the fallback symbol is one of the
   broken ones, try to use a generic unicode symbol as second fallback instead.
   If this is available, we rely on Qt to find a font which has it. Only if
   this is not available, display the symbol as ERT.
This ensures that we do never get a symbol which is not displayed: Either
it can be displayed, with or without fallback, or it will be shown as ERT.
This commit is contained in:
Georg Baum 2014-03-08 11:13:39 +01:00
parent 188dd74618
commit be0cd47559
3 changed files with 54 additions and 2 deletions

View File

@ -12,6 +12,8 @@
#ifndef FONTLOADER_H
#define FONTLOADER_H
#include "support/strfwd.h"
namespace lyx {
class FontInfo;
@ -36,6 +38,9 @@ public:
/// Is the given font available ?
bool available(FontInfo const & f);
/// Can the given symbol be displayed in general?
bool canBeDisplayed(char_type c);
/// Get the Font metrics for this FontInfo
FontMetrics const & metrics(FontInfo const & f);
};

View File

@ -368,6 +368,21 @@ bool FontLoader::available(FontInfo const & f)
}
bool FontLoader::canBeDisplayed(char_type c)
{
// bug 8493
if (c == 0x0009)
// FIXME check whether this is still needed for Qt5
return false;
#if QT_VERSION < 0x050000 && defined(QT_MAC_USE_COCOA) && (QT_MAC_USE_COCOA > 0)
// bug 7954, see also comment in GuiPainter::text()
if (c == 0x00ad)
return false;
#endif
return true;
}
FontMetrics const & FontLoader::metrics(FontInfo const & f)
{
return fontinfo(f).metrics;

View File

@ -110,6 +110,32 @@ bool isMathFontAvailable(docstring & name)
}
bool canBeDisplayed(char_type c)
{
if (!use_gui)
return true;
return theFontLoader().canBeDisplayed(c);
}
bool isUnicodeSymbolAvailable(docstring const & name, char_type & c)
{
docstring cmd(from_ascii("\\") + name);
bool is_combining;
bool termination;
c = Encodings::fromLaTeXCommand(cmd, Encodings::MATH_CMD,
is_combining, termination);
if (c == 0 && name == "varOmega") {
// fallback for bug 7954, unicodesymbols does not list
// \\varOmega because of requirements, but this might change
cmd = from_ascii("\\mathit{\\Omega}");
c = Encodings::fromLaTeXCommand(cmd, Encodings::MATH_CMD,
is_combining, termination);
}
return c != 0 && !is_combining;
}
void initSymbols()
{
FileName const filename = libFileSearch(string(), "symbols");
@ -201,20 +227,26 @@ void initSymbols()
// symbol font is not available sometimes
docstring symbol_font = from_ascii("lyxsymbol");
char_type unicodesymbol = 0;
if (tmp.extra == "func" || tmp.extra == "funclim" || tmp.extra == "special") {
LYXERR(Debug::MATHED, "symbol abuse for " << to_utf8(tmp.name));
tmp.draw = tmp.name;
} else if (isMathFontAvailable(tmp.inset)) {
} else if (isMathFontAvailable(tmp.inset) && canBeDisplayed(charid)) {
LYXERR(Debug::MATHED, "symbol available for " << to_utf8(tmp.name));
tmp.draw.push_back(char_type(charid));
} else if (fallbackid && isMathFontAvailable(symbol_font)) {
} else if (fallbackid && isMathFontAvailable(symbol_font) &&
canBeDisplayed(fallbackid)) {
if (tmp.inset == "cmex")
tmp.inset = from_ascii("lyxsymbol");
else
tmp.inset = from_ascii("lyxboldsymbol");
LYXERR(Debug::MATHED, "symbol fallback for " << to_utf8(tmp.name));
tmp.draw.push_back(char_type(fallbackid));
} else if (isUnicodeSymbolAvailable(tmp.name, unicodesymbol)) {
LYXERR(Debug::MATHED, "unicode fallback for " << to_utf8(tmp.name));
tmp.inset = from_ascii("mathnormal");
tmp.draw.push_back(unicodesymbol);
} else {
LYXERR(Debug::MATHED, "faking " << to_utf8(tmp.name));
tmp.draw = tmp.name;