]> git.lyx.org Git - features.git/commitdiff
Try to compute row height like it should be done
authorJean-Marc Lasgouttes <lasgouttes@lyx.org>
Thu, 3 Jan 2019 15:03:48 +0000 (16:03 +0100)
committerJean-Marc Lasgouttes <lasgouttes@lyx.org>
Thu, 18 Jun 2020 12:39:56 +0000 (14:39 +0200)
Currently, our computation of row height is not completely standard:
* we ignore completely the QFontMetrics::leading() parameter

* we add arbitrarily 2 hardcoded pixels to the height.

This patch reverses these two choices, which leads to
* slightly larger spacing for MinionPro (which has a big leading).

* an additional spacing of 20% font height that depends on dpi and zoom.

Visual inspection with LibreOffice seems to imply that it disregards
the font leading but uses a interline which is 20% larger than the
font height.

src/Row.cpp
src/TextMetrics.cpp
src/frontends/FontMetrics.h
src/frontends/qt4/GuiFontMetrics.cpp
src/frontends/qt4/GuiFontMetrics.h

index 697e526094b7f399801f4d62d24f7b39f5fc503a..1a12e9d695137a7a9d2c691a9193090b07e8c3c9 100644 (file)
@@ -376,8 +376,11 @@ void Row::finalizeLast()
 
        if (elt.type == STRING) {
                dim_.wid -= elt.dim.wid;
-               elt.dim.wid = theFontMetrics(elt.font).width(elt.str);
+               FontMetrics const & fm = theFontMetrics(elt.font);
+               elt.dim.wid = fm.width(elt.str);
                dim_.wid += elt.dim.wid;
+               dim_.asc = fm.maxAscent() + fm.leading();
+               dim_.des = fm.maxDescent();
        }
 }
 
index 29c81da8bd65c09bf5608abb6532d6973a280e14..094b80d9c55123fa2bf30ab74c68ad4721319c6b 100644 (file)
@@ -48,6 +48,7 @@
 #include "support/convert.h"
 #include "support/debug.h"
 #include "support/lassert.h"
+#include "support/lyxlib.h"
 
 #include <stdlib.h>
 #include <cmath>
@@ -61,6 +62,10 @@ using frontend::FontMetrics;
 
 namespace {
 
+// the somewhat arbitrary leading added between rows. This is 20% of
+// the characters height, inluding the possible leading of the font.
+// 20% is a standard value used by LaTeX and word processors.
+double const extra_leading = 0.2;
 
 int numberOfLabelHfills(Paragraph const & par, Row const & row)
 {
@@ -1088,27 +1093,19 @@ void TextMetrics::setRowHeight(Row & row) const
        // Initial value for ascent (useful if row is empty).
        Font const font = displayFont(row.pit(), row.pos());
        FontMetrics const & fm = theFontMetrics(font);
-       int maxasc = int(fm.maxAscent() * spacing_val);
-       int maxdes = int(fm.maxDescent() * spacing_val);
+       int maxasc = fm.maxAscent() + fm.leading();
+       int maxdes = fm.maxDescent();
 
        // Find the ascent/descent of the row contents
        for (Row::Element const & e : row) {
-               if (e.inset) {
-                       maxasc = max(maxasc, e.dim.ascent());
-                       maxdes = max(maxdes, e.dim.descent());
-               } else {
-                       FontMetrics const & fm2 = theFontMetrics(e.font);
-                       maxasc = max(maxasc, int(fm2.maxAscent() * spacing_val));
-                       maxdes = max(maxdes, int(fm2.maxDescent() * spacing_val));
-               }
+               maxasc = max(maxasc, e.dim.ascent());
+               maxdes = max(maxdes, e.dim.descent());
        }
 
-       // This is nicer with box insets
-       ++maxasc;
-       ++maxdes;
-
-       row.dimension().asc = maxasc;
-       row.dimension().des = maxdes;
+       // Add some leading (split between before and after)
+       int const leading = support::iround(extra_leading * (maxasc + maxdes));
+       row.dimension().asc = int((maxasc + leading - leading / 2) * spacing_val);
+       row.dimension().des = int((maxdes + leading / 2) * spacing_val);
 }
 
 
@@ -2009,7 +2006,8 @@ void TextMetrics::completionPosAndDim(Cursor const & cur, int & x, int & y,
 
 int defaultRowHeight()
 {
-       return int(theFontMetrics(sane_font).maxHeight() *  1.2);
+       FontMetrics const & fm = theFontMetrics(sane_font);
+       return support::iround(fm.maxHeight() * (1 + extra_leading) + fm.leading());
 }
 
 } // namespace lyx
index 4472aa70083855c96018e9dd8d34fc7b97c01184..a35a26b481dfa4ded2072ade65a0e41c927f5b78 100644 (file)
@@ -60,6 +60,8 @@ public:
        virtual int maxAscent() const = 0;
        /// return the maximum descent of the font
        virtual int maxDescent() const = 0;
+       /// return the default leading of the font (often 0)
+       virtual int leading() const = 0;
        /// return default dimension of the font.
        /// \warning \c width is set to zero.
        virtual Dimension const defaultDimension() const = 0;
index 3911fd1b477fb9321e282355f0469137759efa5f..b57f514aa6bb7858b5e5b9918c7608ca6b1cc9e7 100644 (file)
@@ -111,6 +111,12 @@ int GuiFontMetrics::maxDescent() const
 }
 
 
+int GuiFontMetrics::leading() const
+{
+       return metrics_.leading();
+}
+
+
 int GuiFontMetrics::em() const
 {
        return QFontInfo(font_).pixelSize();
index 8a2ebe2525fb0c98bc55e8bd726abc3cd7f8fe67..6d50d35425198ea3d9cf1c073eff22f31b755b9b 100644 (file)
@@ -36,6 +36,7 @@ public:
 
        virtual int maxAscent() const;
        virtual int maxDescent() const;
+       virtual int leading() const;
        virtual Dimension const defaultDimension() const;
        virtual int em() const;
        virtual int xHeight() const;