]> git.lyx.org Git - features.git/commitdiff
(almost) Fix Qt4 support breakspace
authorJean-Marc Lasgouttes <lasgouttes@lyx.org>
Thu, 10 Nov 2022 16:24:56 +0000 (17:24 +0100)
committerJean-Marc Lasgouttes <lasgouttes@lyx.org>
Thu, 10 Nov 2022 16:27:45 +0000 (17:27 +0100)
When is it detected that our zero-width characters are not really
zero-width, avoid to use them altogether. Currently, this is known to
happen in Qt4 with monospace fonts.

This allow to remove the special Qt4 code in breaskString_helper.

Related to bug #10117.

src/frontends/qt/GuiFontMetrics.cpp
src/frontends/qt/GuiFontMetrics.h

index d2ebf0e18d816bcb8098ef98ccab9dbdb21bc86f..cc3a32929bc5299132fb83d80b5eec7f6f233606 100644 (file)
@@ -146,6 +146,11 @@ GuiFontMetrics::GuiFontMetrics(QFont const & font)
                        slope_ = defaultSlope;
                LYXERR(Debug::FONT, "Italic slope: " << slope_);
        }
+       // If those characters have a non-zero width, we need to avoid them.
+       // This happens with Qt4 with monospace fonts
+       needs_naked_ = width(QString() + QChar(0x2060) + QChar(0x202d) + QChar(0x202e)) > 0;
+       // if (needs_naked_)
+       //      LYXERR0("Font " << font.family() << " needs naked text layouts!");
 }
 
 
@@ -349,6 +354,7 @@ struct TextLayoutHelper
        /// \c s is the original string
        /// \c isrtl is true if the string is right-to-left
        /// \c naked is true to disable the insertion of zero width annotations
+       /// FIXME: remove \c naked argument when Qt4 support goes away.
        TextLayoutHelper(docstring const & s, bool isrtl, bool naked = false);
 
        /// translate QString index to docstring index
@@ -481,7 +487,7 @@ GuiFontMetrics::getTextLayout(docstring const & s, bool const rtl,
        if (auto ptl = qtextlayout_cache_[key])
                return ptl;
        PROFILE_CACHE_MISS(getTextLayout);
-       TextLayoutHelper tlh(s, rtl);
+       TextLayoutHelper tlh(s, rtl, needs_naked_);
        auto const ptl = getTextLayout_helper(tlh, wordspacing, font_);
        qtextlayout_cache_.insert(key, ptl);
        return ptl;
@@ -491,7 +497,7 @@ GuiFontMetrics::getTextLayout(docstring const & s, bool const rtl,
 int GuiFontMetrics::pos2x(docstring const & s, int pos, bool const rtl,
                           double const wordspacing) const
 {
-       TextLayoutHelper tlh(s, rtl);
+       TextLayoutHelper tlh(s, rtl, needs_naked_);
        auto ptl = getTextLayout(tlh, wordspacing);
        // pos can be negative, see #10506.
        int const qpos = tlh.pos2qpos(max(pos, 0));
@@ -502,7 +508,7 @@ int GuiFontMetrics::pos2x(docstring const & s, int pos, bool const rtl,
 int GuiFontMetrics::x2pos(docstring const & s, int & x, bool const rtl,
                           double const wordspacing) const
 {
-       TextLayoutHelper tlh(s, rtl);
+       TextLayoutHelper tlh(s, rtl, needs_naked_);
        auto ptl = getTextLayout(tlh, wordspacing);
        QTextLine const & tline = ptl->lineForTextPosition(0);
        int qpos = tline.xToCursor(x);
@@ -540,7 +546,7 @@ FontMetrics::Breaks
 GuiFontMetrics::breakString_helper(docstring const & s, int first_wid, int wid,
                                    bool rtl, bool force) const
 {
-       TextLayoutHelper const tlh(s, rtl);
+       TextLayoutHelper const tlh(s, rtl, needs_naked_);
 
        QTextLayout tl;
 #ifdef BIDI_USE_FLAG
@@ -582,7 +588,6 @@ GuiFontMetrics::breakString_helper(docstring const & s, int first_wid, int wid,
                QTextLine const & line = tl.lineAt(i);
                int const line_epos = line.textStart() + line.textLength();
                int const epos = tlh.qpos2pos(line_epos);
-#if QT_VERSION >= 0x050000
                // This does not take trailing spaces into account, except for the last line.
                int const wid = iround(line.naturalTextWidth());
                // If the line is not the last one, trailing space is always omitted.
@@ -591,24 +596,8 @@ GuiFontMetrics::breakString_helper(docstring const & s, int first_wid, int wid,
                if (i + 1 == tl.lineCount() && !s.empty() && isSpace(s.back())
                    && line.textStart() <= tlh.pos2qpos(s.size() - 1))
                        nspc_wid = iround(line.cursorToX(tlh.pos2qpos(s.size() - 1)));
-#else
-               // With some monospace fonts, the value of horizontalAdvance()
-               // can be wrong with Qt4. One hypothesis is that the invisible
-               // characters that we use are given a non-null width.
-               // FIXME: this is slower than it could be but we'll get rid of Qt4 anyway
-               docstring ss = s.substr(pos, epos - pos);
-               int const wid = width(ss);
-               if (!ss.empty() && isSpace(ss.back()))
-                       ss.pop_back();
-               int const nspc_wid = i + 1 < tl.lineCount() ? width(ss) : wid;
-#endif
                breaks.emplace_back(epos - pos, wid, nspc_wid);
                pos = epos;
-#if 0
-               // FIXME: should it be kept in some form?
-               if ((force && line.textLength() == brkStrOffset) || line_wid > x)
-                       return {-1, line_wid};
-#endif
        }
 
        return breaks;
index 5c32ea9de89237cc9e6822ff50b1cb4ed84c86b9..0187c5c85ff762488ea312685211aec6baa5f59d 100644 (file)
@@ -119,6 +119,10 @@ private:
        /// Slope of italic font
        double slope_;
 
+       /// If true, avoid extra annotation in string for QTextLayout
+       // FIXME: remove wen Qt4 suport goes away
+       bool needs_naked_ = false;
+
        /// Cache of char widths
        mutable QHash<char_type, int> width_cache_;
        /// Cache of string widths