]> git.lyx.org Git - features.git/commitdiff
Work around broken math symbol display (bug 7954)
authorGeorg Baum <baum@lyx.org>
Sat, 8 Mar 2014 10:13:39 +0000 (11:13 +0100)
committerGeorg Baum <baum@lyx.org>
Sat, 8 Mar 2014 10:13:39 +0000 (11:13 +0100)
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
src/frontends/qt4/GuiFontLoader.cpp
src/mathed/MathFactory.cpp

index 20fe5b886ec2fffeaa8b8cc3b15f00e963e268e7..ac1854a345073e730665b4ddf5c62a7b2fdfe3de 100644 (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);
 };
index b2448bebeec226a9cfd744ba63bc06de38939640..8081cd6dca7618573038f885a7949cb3cd6c8f6f 100644 (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;
index 151771df38f7b30ab8a388ea7631e317f5b31bb8..961e70e9f459250191b717d16e5d228d006c76b1 100644 (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;