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