commit e2d834e8d07a73c5e4fa49ca3e7aff651e2c0b8a
Author: Enrico Forestieri <for...@lyx.org>
Date:   Mon Aug 4 18:52:20 2014 +0200

    Fix bug #9146 (Graphics conversion problem).
    
    If LyX does not know about a given file format, it may easily
    happen that the format is recognized as "latex" and this causes
    bug #9146. This patch limits the check for a latex format to
    non-binary files. The strategy for deciding that a file has
    binary content is the same as that adopted by the "less" program.
    This is a stripped down backport of the more complex fix in master.

diff --git a/src/Format.cpp b/src/Format.cpp
index 93383ac..71437de 100644
--- a/src/Format.cpp
+++ b/src/Format.cpp
@@ -238,12 +238,17 @@ string guessFormatFromContents(FileName const & fn)
        int const max_count = 50;
        int count = 0;
 
+       // Maximum number of binary chars allowed for latex detection
+       int const max_bin = 5;
+
        string str;
        string format;
        bool firstLine = true;
        bool backslash = false;
+       bool maybelatex = false;
+       int binchars = 0;
        int dollars = 0;
-       while ((count++ < max_count) && format.empty()) {
+       while ((count++ < max_count) && format.empty() && binchars <= max_bin) {
                if (ifs.eof())
                        break;
 
@@ -359,16 +364,26 @@ string guessFormatFromContents(FileName const & fn)
                         contains(str, "$$") ||
                         contains(str, "\\[") ||
                         contains(str, "\\]"))
-                       format = "latex";
+                       maybelatex = true;
                else {
                        if (contains(str, '\\'))
                                backslash = true;
                        dollars += count_char(str, '$');
+                       if (backslash && dollars > 1)
+                               // inline equation
+                               maybelatex = true;
                }
+
+               // Note that this is formally not correct, since count_bin_chars
+               // expects utf8, and str can be anything: plain text in any
+               // encoding, or really binary data. In practice it works, since
+               // QString::fromUtf8() drops invalid utf8 sequences, and while
+               // the exact number may not be correct, we still get a high
+               // number for truly binary files.
+               binchars += count_bin_chars(str);
        }
 
-       if (format.empty() && backslash && dollars > 1)
-               // inline equation
+       if (format.empty() && binchars <= max_bin && maybelatex)
                format = "latex";
 
        if (format.empty()) {
diff --git a/src/support/lstrings.cpp b/src/support/lstrings.cpp
index d4b1ccf..103976a 100644
--- a/src/support/lstrings.cpp
+++ b/src/support/lstrings.cpp
@@ -917,6 +917,31 @@ int count_char(docstring const & str, 
docstring::value_type chr)
 }
 
 
+int count_bin_chars(string const & str)
+{
+       QString const qstr = toqstr(str).simplified();
+       int count = 0;
+       QString::const_iterator cit = qstr.begin();
+       QString::const_iterator end = qstr.end();
+       for (; cit != end; ++cit)  {
+               switch (cit->category()) {
+               case QChar::Separator_Line:
+               case QChar::Separator_Paragraph:
+               case QChar::Other_Control:
+               case QChar::Other_Format:
+               case QChar::Other_Surrogate:
+               case QChar::Other_PrivateUse:
+               case QChar::Other_NotAssigned:
+                       ++count;
+                       break;
+               default:
+                       break;
+               }
+       }
+       return count;
+}
+
+
 docstring const trim(docstring const & a, char const * p)
 {
        LASSERT(p, return a);
diff --git a/src/support/lstrings.h b/src/support/lstrings.h
index 576a5b9..20a73c4 100644
--- a/src/support/lstrings.h
+++ b/src/support/lstrings.h
@@ -196,6 +196,14 @@ int count_char(std::string const & str, char chr);
 /// Count all occurences of char \a chr inside \a str
 int count_char(docstring const & str, docstring::value_type chr);
 
+/** Count all occurences of binary chars inside \a str.
+    It is assumed that \a str is utf-8 encoded and that a binary char
+    belongs to the unicode class names Zl, Zp, Cc, Cf, Cs, Co, or Cn
+    (excluding white space characters such as '\t', '\n', '\v', '\f', '\r').
+    See http://www.unicode.org/Public/6.2.0/ucd/UnicodeData.txt
+*/
+int count_bin_chars(std::string const & str);
+
 /** Trims characters off the end and beginning of a string.
     \code
     trim("ccabccc", "c") == "ab".
diff --git a/status.21x b/status.21x
index 012fb1d..4bd5f69 100644
--- a/status.21x
+++ b/status.21x
@@ -95,6 +95,8 @@ What's new
 
 - Fix reverse search in insets (figures, tables, branches, etc.) (bug 9151).
 
+- Fix on-screen display of images whose type is not known to LyX (bug 9146).
+
 
 * INTERNALS
 

Reply via email to