commit b4ff3fb2878da14c3ae702b506b91210f4481888
Author: Richard Kimberly Heck <[email protected]>
Date:   Tue Nov 22 21:04:29 2022 -0500

    Backport fix for #11491. From Enrico.
---
 src/BufferView.cpp                   |   16 +++++
 src/BufferView.h                     |    5 ++
 src/frontends/FontMetrics.h          |    2 +
 src/frontends/qt4/GuiFontMetrics.cpp |   25 +++++++
 src/frontends/qt4/GuiFontMetrics.h   |    4 +
 src/mathed/InsetMathDecoration.cpp   |   37 +++++++---
 src/mathed/MathSupport.cpp           |  121 +++++++++++++++++++++++++--------
 src/mathed/MathSupport.h             |    2 +
 8 files changed, 171 insertions(+), 41 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index 182bfdf..d5c850b 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -82,6 +82,7 @@
 #include "support/gettext.h"
 #include "support/lassert.h"
 #include "support/lstrings.h"
+#include "support/lyxlib.h"
 #include "support/Package.h"
 #include "support/types.h"
 
@@ -389,6 +390,21 @@ int BufferView::inPixels(Length const & len) const
 }
 
 
+int BufferView::zoomedPixels(int pix) const
+{
+       // FIXME: the dpi setting should really depend on the BufferView
+       // (think different monitors).
+
+       // Zoom factor specified by user in percent
+       double const zoom = lyxrc.currentZoom / 100.0; // [percent]
+
+       // DPI setting for monitor: pixels/inch
+       double const dpizoom = lyxrc.dpi / 100.0; // [per 100dpi]
+
+       return support::iround(pix * zoom * dpizoom);
+}
+
+
 bool BufferView::isTopScreen() const
 {
        return 0 == d->scrollbarParameters_.min;
diff --git a/src/BufferView.h b/src/BufferView.h
index 886d3c8..8326e36 100644
--- a/src/BufferView.h
+++ b/src/BufferView.h
@@ -114,6 +114,11 @@ public:
         */
        int inPixels(Length const & len) const;
 
+       /** Return the number of pixels equivalent to \c pix pixels at
+        * 100dpi and 100% zoom.
+        */
+       int zoomedPixels(int pix) const;
+
        /// \return true if the BufferView is at the top of the document.
        bool isTopScreen() const;
 
diff --git a/src/frontends/FontMetrics.h b/src/frontends/FontMetrics.h
index c02606c..fbe18df 100644
--- a/src/frontends/FontMetrics.h
+++ b/src/frontends/FontMetrics.h
@@ -73,6 +73,8 @@ public:
        /// return the distance from the base line to where the strike out line
        /// should be drawn.
        virtual int strikeoutPos() const = 0;
+       /// return slope for italic font
+       virtual double italicSlope() const = 0;
 
        /// return the width of the char in the font
        virtual int width(char_type c) const = 0;
diff --git a/src/frontends/qt4/GuiFontMetrics.cpp 
b/src/frontends/qt4/GuiFontMetrics.cpp
index 3df1bc9..2e20a08 100644
--- a/src/frontends/qt4/GuiFontMetrics.cpp
+++ b/src/frontends/qt4/GuiFontMetrics.cpp
@@ -20,11 +20,15 @@
 #include "support/convert.h"
 #include "support/lassert.h"
 #include "support/lyxlib.h"
+#include "support/debug.h"
 
 #define DISABLE_PMPROF
 #include "support/pmprof.h"
 
 #include <QByteArray>
+#include <QRawFont>
+#include <QtEndian>
+#include <QtMath>
 
 using namespace std;
 using namespace lyx::support;
@@ -113,6 +117,21 @@ GuiFontMetrics::GuiFontMetrics(QFont const & font)
          breakat_cache_(cache_metrics_breakat_size),
          qtextlayout_cache_(cache_metrics_qtextlayout_size)
 {
+       // Determine italic slope
+       double const defaultSlope = tan(qDegreesToRadians(19.0));
+       QRawFont raw = QRawFont::fromFont(font);
+       QByteArray post(raw.fontTable("post"));
+       if (post.length() == 0) {
+               slope_ = defaultSlope;
+               LYXERR(Debug::FONT, "Screen font doesn't have 'post' table.");
+       } else {
+               // post table description:
+               // 
https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6post.html
+               int32_t italicAngle = qFromBigEndian(*reinterpret_cast<int32_t 
*>(post.data() + 4));
+               double angle = italicAngle / 65536.0; // Fixed-point 16.16 to 
floating-point
+               slope_ = -tan(qDegreesToRadians(angle));
+               LYXERR(Debug::FONT, "Italic slope: " << slope_);
+       }
 }
 
 
@@ -154,6 +173,12 @@ int GuiFontMetrics::strikeoutPos() const
 }
 
 
+double GuiFontMetrics::italicSlope() const
+{
+       return slope_;
+}
+
+
 namespace {
 int const outOfLimitMetric = -10000;
 }
diff --git a/src/frontends/qt4/GuiFontMetrics.h 
b/src/frontends/qt4/GuiFontMetrics.h
index 6cea40f..f4ba40b 100644
--- a/src/frontends/qt4/GuiFontMetrics.h
+++ b/src/frontends/qt4/GuiFontMetrics.h
@@ -41,6 +41,7 @@ public:
        virtual int lineWidth() const;
        virtual int underlinePos() const;
        virtual int strikeoutPos() const;
+       virtual double italicSlope() const;
        virtual int width(char_type c) const;
        virtual int ascent(char_type c) const;
        virtual int descent(char_type c) const;
@@ -83,6 +84,9 @@ private:
        /// Metrics on the font
        QFontMetrics metrics_;
 
+       /// Slope of italic font
+       double slope_;
+
        /// Cache of char widths
        mutable QHash<char_type, int> width_cache_;
        /// Cache of string widths
diff --git a/src/mathed/InsetMathDecoration.cpp 
b/src/mathed/InsetMathDecoration.cpp
index 1262370..fd918ca 100644
--- a/src/mathed/InsetMathDecoration.cpp
+++ b/src/mathed/InsetMathDecoration.cpp
@@ -13,12 +13,14 @@
 
 #include "InsetMathDecoration.h"
 
+#include "InsetMathChar.h"
 #include "MathData.h"
 #include "MathParser.h"
 #include "MathSupport.h"
 #include "MathStream.h"
 #include "MetricsInfo.h"
 
+#include "BufferView.h"
 #include "LaTeXFeatures.h"
 
 #include "support/debug.h"
@@ -115,15 +117,19 @@ void InsetMathDecoration::metrics(MetricsInfo & mi, 
Dimension & dim) const
 
        cell(0).metrics(mi, dim);
 
-       dh_  = 6; //mathed_char_height(LM_TC_VAR, mi, 'I', ascent_, descent_);
-       dw_  = 6; //mathed_char_width(LM_TC_VAR, mi, 'x');
+       int const l1 = mi.base.bv->zoomedPixels(1);
+       int const l2 = 6 * l1;
+       int const l3 = 6 * l1;
+
+       dh_  = l2; //mathed_char_height(LM_TC_VAR, mi, 'I', ascent_, descent_);
+       dw_  = l3; //mathed_char_width(LM_TC_VAR, mi, 'x');
 
        if (upper()) {
-               dy_ = -dim.asc - dh_;
-               dim.asc += dh_ + 1;
+               dy_ = -dim.asc - dh_ - l1;
+               dim.asc += dh_ + l1;
        } else {
-               dy_ = dim.des + 1;
-               dim.des += dh_ + 2;
+               dy_ = dim.des + l1;
+               dim.des += dh_ + l2;
        }
 }
 
@@ -134,11 +140,20 @@ void InsetMathDecoration::draw(PainterInfo & pi, int x, 
int y) const
 
        cell(0).draw(pi, x, y);
        Dimension const & dim0 = cell(0).dimension(*pi.base.bv);
-       if (wide())
-               mathed_draw_deco(pi, x + 1, y + dy_, dim0.wid, dh_, key_->name);
-       else
-               mathed_draw_deco(pi, x + 1 + (dim0.wid - dw_) / 2,
-                       y + dy_, dw_, dh_, key_->name);
+       if (wide()) {
+               mathed_draw_deco(pi, x, y + dy_, dim0.wid, dh_, key_->name);
+               return;
+       }
+       // Lacking the necessary font parameters, in order to properly align
+       // the decoration we have to resort to heuristics for choosing a
+       // suitable value for shift
+       char_type c = (cell(0).empty() || !cell(0)[0]->asCharInset())
+               ? 0 : cell(0)[0]->asCharInset()->getChar();
+       double slope = (c == 0) ? 0.0 : mathed_char_slope(pi.base, c);
+       int kerning = (c == 0) ? 0 : mathed_char_kerning(pi.base.font, c);
+       int shift = (kerning == 0) ? int(dim0.asc * slope) : kerning;
+       mathed_draw_deco(pi, x + (dim0.wid - dw_) / 2 + shift,
+                        y + dy_, dw_, dh_, key_->name);
 }
 
 
diff --git a/src/mathed/MathSupport.cpp b/src/mathed/MathSupport.cpp
index b98dc54..f76a5d7 100644
--- a/src/mathed/MathSupport.cpp
+++ b/src/mathed/MathSupport.cpp
@@ -21,6 +21,7 @@
 #include "MathParser.h"
 #include "MathStream.h"
 
+#include "Encoding.h"
 #include "LaTeXFeatures.h"
 #include "MetricsInfo.h"
 
@@ -32,6 +33,7 @@
 #include "support/docstream.h"
 #include "support/lassert.h"
 #include "support/lyxlib.h"
+#include "support/textutils.h"
 
 #include <map>
 #include <algorithm>
@@ -99,8 +101,8 @@ double const parenthHigh[] = {
 
 double const parenth[] = {
        2, 13,
-       0.9930, 0.0071, 0.7324, 0.0578, 0.5141, 0.1126,
-       0.3380, 0.1714, 0.2183, 0.2333, 0.0634, 0.3621,
+       0.9930, 0.0081, 0.7254, 0.0588, 0.5070, 0.1136,
+       0.3310, 0.1724, 0.2113, 0.2353, 0.0563, 0.3631,
        0.0141, 0.5000, 0.0563, 0.6369, 0.2113, 0.7647,
        0.3310, 0.8276, 0.5070, 0.8864, 0.7254, 0.9412,
        0.9930, 0.9919,
@@ -108,6 +110,13 @@ double const parenth[] = {
 };
 
 
+double const breve[] = {
+       2, 5,
+       0.1, 0.4,  0.2, 0.7,  0.5, 0.8,  0.8, 0.7,  0.9, 0.4,
+       0
+};
+
+
 double const brace[] = {
        2, 21,
        0.9492, 0.0020, 0.9379, 0.0020, 0.7458, 0.0243,
@@ -277,13 +286,13 @@ double const corner[] = {
 
 double const angle[] = {
        2, 3,
-       1, 0,  0.05, 0.5,  1, 1,
+       0.9, 0.05,  0.05, 0.5,  0.9, 0.95,
        0
 };
 
 
 double const slash[] = {
-       1, 0.95, 0.05, 0.05, 0.95,
+       1, 0.8, 0.1, 0.1, 0.8,
        0
 };
 
@@ -298,31 +307,31 @@ double const dot[] = {
 //     1, 0.5, 0.2, 0.5, 0.2,
 //     1, 0.4, 0.4, 0.6, 0.4,
 //     1, 0.5, 0.5, 0.5, 0.5,
-       5, 0.4, 0.4, 0.6, 0.4,
+       5, 0.4, 0.5, 0.6, 0.5,
        0
 };
 
 
 double const ddot[] = {
-       5, 0.0, 0.4, 0.3, 0.4,
-       5, 0.6, 0.4, 1.0, 0.4,
+       5, 0.1, 0.5, 0.3, 0.5,
+       5, 0.6, 0.5, 0.8, 0.5,
        0
 };
 
 
 double const dddot[] = {
-       1, 0.1,  0.5, 0.2,  0.5,
-       1, 0.45, 0.5, 0.55, 0.5,
-       1, 0.8,  0.5, 0.9,  0.5,
+       5, -0.2, 0.5, 0.0, 0.5,
+       5,  0.3, 0.5, 0.5, 0.5,
+       5,  0.8, 0.5, 1.0, 0.5,
        0
 };
 
 
 double const ddddot[] = {
-       1, 0.1,  0.5, 0.2,  0.5,
-       1, 0.45, 0.5, 0.55, 0.5,
-       1, 0.8,  0.5, 0.9,  0.5,
-       1, 1.15, 0.5, 1.25, 0.5,
+       5, -0.4, 0.5, -0.2, 0.5,
+       5,  0.1, 0.5,  0.3, 0.5,
+       5,  0.6, 0.5,  0.8, 0.5,
+       5,  1.1, 0.5,  1.3, 0.5,
        0
 };
 
@@ -344,8 +353,10 @@ double const dline3[] = {
 
 
 double const ring[] = {
-       2, 5,
-       0.5, 0.8,  0.8, 0.5,  0.5, 0.2,  0.2, 0.5,  0.5, 0.8,
+       2, 9,
+       0.5, 0.8,  0.7, 0.7,  0.8, 0.5,
+       0.7, 0.3,  0.5, 0.2,  0.3, 0.3,
+       0.2, 0.5,  0.3, 0.7,  0.5, 0.8,
        0
 };
 
@@ -364,8 +375,12 @@ double const  Vert[] = {
 
 
 double const tilde[] = {
-       2, 4,
-       0.00, 0.8,  0.25, 0.2,  0.75, 0.8,  1.00, 0.2,
+       2, 13,
+       -0.05,0.70,  0.00, 0.55,  0.05, 0.40,
+       0.15, 0.30,  0.30, 0.30,  0.40, 0.40,
+       0.45, 0.55,  0.50, 0.70,  0.60, 0.80,
+       0.75, 0.80,  0.85, 0.70,  0.90, 0.55,
+       0.95, 0.40,
        0
 };
 
@@ -463,7 +478,7 @@ named_deco_struct deco_table[] = {
        {"bar",            hline,      0 },
        {"dot",            dot,        0 },
        {"check",          angle,      1 },
-       {"breve",          parenth,    1 },
+       {"breve",          breve,      0 },
        {"vec",            arrow,      3 },
        {"mathring",       ring,       0 },
 
@@ -570,6 +585,15 @@ int mathed_char_kerning(FontInfo const & font, char_type c)
 }
 
 
+double mathed_char_slope(MetricsBase const & mb, char_type c)
+{
+       bool slanted = isAlphaASCII(c) || Encodings::isMathAlpha(c);
+       if (slanted && mb.fontname == "mathnormal")
+               return theFontMetrics(mb.font).italicSlope();
+       return 0.0;
+}
+
+
 void mathed_string_dim(FontInfo const & font,
                       docstring const & s,
                       Dimension & dim)
@@ -596,9 +620,11 @@ int mathed_string_width(FontInfo const & font, docstring 
const & s)
 void mathed_draw_deco(PainterInfo & pi, int x, int y, int w, int h,
        docstring const & name)
 {
+       int const lw = pi.base.solidLineThickness();
+
        if (name == ".") {
                pi.pain.line(x + w/2, y, x + w/2, y + h,
-                         Color_cursor, Painter::line_onoffdash);
+                         Color_cursor, Painter::line_onoffdash, lw);
                return;
        }
 
@@ -640,16 +666,50 @@ void mathed_draw_deco(PainterInfo & pi, int x, int y, int 
w, int h,
                        pi.pain.line(
                                int(x + xx + 0.5), int(y + yy + 0.5),
                                int(x + x2 + 0.5), int(y + y2 + 0.5),
-                               pi.base.font.color());
+                               pi.base.font.color(), Painter::line_solid, lw);
                        if (code == 5) {  // thicker, but rounded
-                               pi.pain.line(
-                                       int(x + xx + 0.5+1), int(y + yy + 
0.5-1),
-                                       int(x + x2 + 0.5-1), int(y + y2 + 
0.5-1),
-                               pi.base.font.color());
-                               pi.pain.line(
-                                       int(x + xx + 0.5+1), int(y + yy + 
0.5+1),
-                                       int(x + x2 + 0.5-1), int(y + y2 + 
0.5+1),
-                               pi.base.font.color());
+                               double const xa = x + xx + 0.5;
+                               double const xb = x + x2 + 0.5;
+                               double const ya = y + yy + 0.5;
+                               double const yb = y + y2 + 0.5;
+                               pi.pain.line(int(xa + 1), int(ya - 1),
+                                            int(xb - 1), int(yb - 1),
+                                            pi.base.font.color(),
+                                            Painter::line_solid, lw);
+                               pi.pain.line(int(xa + 1), int(ya + 1),
+                                            int(xb - 1), int(yb + 1),
+                                            pi.base.font.color(),
+                                            Painter::line_solid, lw);
+                               if (xa + 2 <= xb - 2) {
+                                       pi.pain.line(int(xa + 2), int(ya - 2),
+                                                    int(xb - 2), int(yb - 2),
+                                                    pi.base.font.color(),
+                                                    Painter::line_solid, lw);
+                                       pi.pain.line(int(xa + 2), int(ya + 2),
+                                                    int(xb - 2), int(yb + 2),
+                                                    pi.base.font.color(),
+                                                    Painter::line_solid, lw);
+                               }
+                               if (xa + 3 <= xb - 3) {
+                                       pi.pain.line(int(xa + 3), int(ya - 3),
+                                                    int(xb - 3), int(yb - 3),
+                                                    pi.base.font.color(),
+                                                    Painter::line_solid, lw);
+                                       pi.pain.line(int(xa + 3), int(ya + 3),
+                                                    int(xb - 3), int(yb + 3),
+                                                    pi.base.font.color(),
+                                                    Painter::line_solid, lw);
+                               }
+                               if (xa + 4 <= xb - 4) {
+                                       pi.pain.line(int(xa + 4), int(ya - 4),
+                                                    int(xb - 4), int(yb - 4),
+                                                    pi.base.font.color(),
+                                                    Painter::line_solid, lw);
+                                       pi.pain.line(int(xa + 4), int(ya + 4),
+                                                    int(xb - 4), int(yb + 4),
+                                                    pi.base.font.color(),
+                                                    Painter::line_solid, lw);
+                               }
                        }
                } else {
                        int xp[32];
@@ -667,7 +727,8 @@ void mathed_draw_deco(PainterInfo & pi, int x, int y, int 
w, int h,
                                yp[j] = int(y + yy + 0.5);
                                //  lyxerr << "P[" << j ' ' << xx << ' ' << yy 
<< ' ' << x << ' ' << y << ']';
                        }
-                       pi.pain.lines(xp, yp, n, pi.base.font.color());
+                       pi.pain.lines(xp, yp, n, pi.base.font.color(),
+                               Painter::fill_none, Painter::line_solid, lw);
                }
        }
 }
diff --git a/src/mathed/MathSupport.h b/src/mathed/MathSupport.h
index 7c40baa..4675bcc 100644
--- a/src/mathed/MathSupport.h
+++ b/src/mathed/MathSupport.h
@@ -46,6 +46,8 @@ int mathed_char_width(FontInfo const &, char_type c);
 
 int mathed_char_kerning(FontInfo const &, char_type c);
 
+double mathed_char_slope(MetricsBase const & mb, char_type c);
+
 void mathed_draw_deco(PainterInfo & pi, int x, int y, int w, int h,
        docstring const & name);
 
-- 
lyx-cvs mailing list
[email protected]
http://lists.lyx.org/mailman/listinfo/lyx-cvs

Reply via email to