]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/qt4/GuiFontMetrics.cpp
Use QFontMetrics information for underlines (and friends) width and position
[lyx.git] / src / frontends / qt4 / GuiFontMetrics.cpp
index f3a4c0fab79999a6ea63371e4fb65e0ce1fbd5fc..2214623d3b7b9b4befc7c3aff5125f21e8957217 100644 (file)
@@ -72,10 +72,34 @@ int GuiFontMetrics::maxDescent() const
 }
 
 
+int GuiFontMetrics::em() const
+{
+       return QFontInfo(font_).pixelSize();
+}
+
+
+int GuiFontMetrics::lineWidth() const
+{
+       return metrics_.lineWidth();
+}
+
+
+int GuiFontMetrics::underlinePos() const
+{
+       return metrics_.underlinePos();
+}
+
+
+int GuiFontMetrics::strikeoutPos() const
+{
+       return metrics_.strikeOutPos();
+}
+
+
 int GuiFontMetrics::lbearing(char_type c) const
 {
        if (!is_utf16(c))
-               // FIXME: QFontMetrics::leftBearingdoes not support the
+               // FIXME: QFontMetrics::leftBearing does not support the
                //        full unicode range. Once it does, we could use:
                //return metrics_.leftBearing(toqstr(docstring(1, c)));
                return 0;
@@ -144,10 +168,11 @@ int GuiFontMetrics::signedWidth(docstring const & s) const
 }
 
 namespace {
-void setTextLayout(QTextLayout & tl, docstring const & s, QFont const & font,
-                            bool const rtl)
+void setTextLayout(QTextLayout & tl, docstring const & s, QFont font,
+                   bool const rtl, double const wordspacing)
 {
        tl.setText(toqstr(s));
+       font.setWordSpacing(wordspacing);
        tl.setFont(font);
        // Note that both setFlags and the enums are undocumented
        tl.setFlags(rtl ? Qt::TextForceRightToLeft : Qt::TextForceLeftToRight);
@@ -158,18 +183,22 @@ void setTextLayout(QTextLayout & tl, docstring const & s, QFont const & font,
 }
 
 
-int GuiFontMetrics::pos2x(docstring const & s, int const pos, bool const rtl) const
+int GuiFontMetrics::pos2x(docstring const & s, int const pos, bool const rtl,
+                          double const wordspacing) const
 {
        QTextLayout tl;
-       setTextLayout(tl, s, font_, rtl);
+       QFont copy = font_;
+       copy.setWordSpacing(wordspacing);
+       setTextLayout(tl, s, font_, rtl, wordspacing);
        return static_cast<int>(tl.lineForTextPosition(pos).cursorToX(pos));
 }
 
 
-int GuiFontMetrics::x2pos(docstring const & s, int & x, bool const rtl) const
+int GuiFontMetrics::x2pos(docstring const & s, int & x, bool const rtl,
+                          double const wordspacing) const
 {
        QTextLayout tl;
-       setTextLayout(tl, s, font_, rtl);
+       setTextLayout(tl, s, font_, rtl, wordspacing);
        int pos = tl.lineForTextPosition(0).xToCursor(x);
        // correct x value to the actual cursor position.
        x = static_cast<int>(tl.lineForTextPosition(0).cursorToX(pos));
@@ -177,6 +206,31 @@ int GuiFontMetrics::x2pos(docstring const & s, int & x, bool const rtl) const
 }
 
 
+bool GuiFontMetrics::breakAt(docstring & s, int & x, bool const rtl, bool const force) const
+{
+       if (s.empty())
+               return false;
+       QTextLayout tl;
+       tl.setText(toqstr(s));
+       tl.setFont(font_);
+       // Note that both setFlags and the enums are undocumented
+       tl.setFlags(rtl ? Qt::TextForceRightToLeft : Qt::TextForceLeftToRight);
+       QTextOption to;
+       to.setWrapMode(force ? QTextOption::WrapAnywhere : QTextOption::WordWrap);
+       tl.setTextOption(to);
+       tl.beginLayout();
+       QTextLine line = tl.createLine();
+       line.setLineWidth(x);
+       tl.createLine();
+       tl.endLayout();
+       if (int(line.naturalTextWidth()) > x)
+               return false;
+       x = int(line.naturalTextWidth());
+       s = s.substr(0, line.textLength());
+       return true;
+}
+
+
 void GuiFontMetrics::rectText(docstring const & str,
        int & w, int & ascent, int & descent) const
 {