From be0cd47559c33740d67aa2b2d80531ba09c920b3 Mon Sep 17 00:00:00 2001 From: Georg Baum Date: Sat, 8 Mar 2014 11:13:39 +0100 Subject: [PATCH] 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. --- src/frontends/FontLoader.h | 5 ++++ src/frontends/qt4/GuiFontLoader.cpp | 15 ++++++++++++ src/mathed/MathFactory.cpp | 36 +++++++++++++++++++++++++++-- 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/src/frontends/FontLoader.h b/src/frontends/FontLoader.h index 20fe5b886e..ac1854a345 100644 --- a/src/frontends/FontLoader.h +++ b/src/frontends/FontLoader.h @@ -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); }; diff --git a/src/frontends/qt4/GuiFontLoader.cpp b/src/frontends/qt4/GuiFontLoader.cpp index b2448bebee..8081cd6dca 100644 --- a/src/frontends/qt4/GuiFontLoader.cpp +++ b/src/frontends/qt4/GuiFontLoader.cpp @@ -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; diff --git a/src/mathed/MathFactory.cpp b/src/mathed/MathFactory.cpp index 151771df38..961e70e9f4 100644 --- a/src/mathed/MathFactory.cpp +++ b/src/mathed/MathFactory.cpp @@ -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; -- 2.39.2