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.
This commit is contained in:
Jean-Marc Lasgouttes 2015-04-14 15:22:11 +02:00
parent 893ae612e4
commit cf6128caf6
5 changed files with 51 additions and 27 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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());
}

View File

@ -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,