From cf6128caf664378f15d9c93b6d35621e19f4eecb Mon Sep 17 00:00:00 2001 From: Jean-Marc Lasgouttes Date: Tue, 14 Apr 2015 15:22:11 +0200 Subject: [PATCH] Use QFontMetrics information for underlines (and friends) width and position The width of the line is now dependent on the font size. This new computation is applied to: underline, strikeout, double underline. --- src/frontends/FontMetrics.h | 8 +++++ src/frontends/qt4/GuiFontMetrics.cpp | 20 ++++++++++++- src/frontends/qt4/GuiFontMetrics.h | 3 ++ src/frontends/qt4/GuiPainter.cpp | 45 +++++++++++++--------------- src/frontends/qt4/GuiPainter.h | 2 +- 5 files changed, 51 insertions(+), 27 deletions(-) diff --git a/src/frontends/FontMetrics.h b/src/frontends/FontMetrics.h index 1c1a658f8a..e8493d1316 100644 --- a/src/frontends/FontMetrics.h +++ b/src/frontends/FontMetrics.h @@ -65,6 +65,14 @@ public: virtual Dimension const defaultDimension() const = 0; /// return the em size virtual int em() const = 0; + /// return the width of a line for underlining + virtual int lineWidth() const = 0; + /// return the distance from the base line to where an underline + /// should be drawn. + virtual int underlinePos() const = 0; + /// return the distance from the base line to where the strike out line + /// should be drawn. + virtual int strikeoutPos() 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 e41ef3cf3c..2214623d3b 100644 --- a/src/frontends/qt4/GuiFontMetrics.cpp +++ b/src/frontends/qt4/GuiFontMetrics.cpp @@ -78,10 +78,28 @@ int GuiFontMetrics::em() const } +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; diff --git a/src/frontends/qt4/GuiFontMetrics.h b/src/frontends/qt4/GuiFontMetrics.h index a382253281..75507b0c99 100644 --- a/src/frontends/qt4/GuiFontMetrics.h +++ b/src/frontends/qt4/GuiFontMetrics.h @@ -36,6 +36,9 @@ public: virtual int maxDescent() const; virtual Dimension const defaultDimension() const; virtual int em() const; + virtual int lineWidth() const; + virtual int underlinePos() const; + virtual int strikeoutPos() const; virtual int width(char_type c) const; virtual int ascent(char_type c) const; virtual int descent(char_type c) const; diff --git a/src/frontends/qt4/GuiPainter.cpp b/src/frontends/qt4/GuiPainter.cpp index 8e0229ed1d..2ecd3acd66 100644 --- a/src/frontends/qt4/GuiPainter.cpp +++ b/src/frontends/qt4/GuiPainter.cpp @@ -570,42 +570,37 @@ int GuiPainter::preeditText(int x, int y, char_type c, } -void GuiPainter::doubleUnderline(FontInfo const & f, int x, int y, int width) +void GuiPainter::underline(FontInfo const & f, int x, int y, int width, + line_style ls) { FontMetrics const & fm = theFontMetrics(f); + int const pos = fm.underlinePos(); - int const below = max(fm.maxDescent() / 2, 2); - - line(x, y + below, x + width, y + below, f.realColor()); - line(x, y + below - 2, x + width, y + below - 2, f.realColor()); -} - - -void GuiPainter::underline(FontInfo const & f, int x, int y, int width) -{ - FontMetrics const & fm = theFontMetrics(f); - - int const below = max(fm.maxDescent() / 2, 2); - int const height = max((fm.maxDescent() / 4) - 1, 1); - - if (height < 2) - line(x, y + below, x + width, y + below, f.realColor()); - else - fillRectangle(x, y + below, width, below + height, f.realColor()); + line(x, y + pos, x + width, y + pos, + f.realColor(), ls, fm.lineWidth()); } void GuiPainter::strikeoutLine(FontInfo const & f, int x, int y, int width) { FontMetrics const & fm = theFontMetrics(f); + int const pos = fm.strikeoutPos(); - int const middle = max((fm.maxHeight() / 4), 1); - int const height = middle/3; + line(x, y - pos, x + width, y - pos, + f.realColor(), line_solid, fm.lineWidth()); +} - if (height < 2) - line(x, y - middle, x + width, y - middle, f.realColor()); - else - fillRectangle(x, y - middle, width, height, f.realColor()); + +void GuiPainter::doubleUnderline(FontInfo const & f, int x, int y, int width) +{ + FontMetrics const & fm = theFontMetrics(f); + int const pos1 = fm.underlinePos() + fm.lineWidth(); + int const pos2 = fm.underlinePos() - fm.lineWidth() + 1; + + line(x, y + pos1, x + width, y + pos1, + f.realColor(), line_solid, fm.lineWidth()); + line(x, y + pos2, x + width, y + pos2, + f.realColor(), line_solid, fm.lineWidth()); } diff --git a/src/frontends/qt4/GuiPainter.h b/src/frontends/qt4/GuiPainter.h index 5538d14fe4..b1f4fb8ecd 100644 --- a/src/frontends/qt4/GuiPainter.h +++ b/src/frontends/qt4/GuiPainter.h @@ -147,7 +147,7 @@ public: private: /// check the font, and if set, draw an underline void underline(FontInfo const & f, - int x, int y, int width); + int x, int y, int width, line_style ls = line_solid); /// check the font, and if set, draw an dashed underline void dashedUnderline(FontInfo const & f,