Commit fd59b50e authored by Gustavo Carneiro's avatar Gustavo Carneiro Committed by Kurt Hindenburg
Browse files

Move font methods to a new TerminalFont class.

parent 9433d17a
......@@ -183,6 +183,7 @@ set(konsoleprivate_SRCS ${windowadaptors_SRCS}
terminalDisplay/TerminalPainter.cpp
terminalDisplay/TerminalScrollBar.cpp
terminalDisplay/TerminalColor.cpp
terminalDisplay/TerminalFonts.cpp
widgets/TerminalDisplayAccessible.cpp
widgets/TerminalHeaderBar.cpp
......
......@@ -10,6 +10,7 @@
#include "terminalDisplay/TerminalDisplay.h"
#include "terminalDisplay/TerminalColor.h"
#include "terminalDisplay/TerminalFonts.h"
#include <QRect>
#include <QEvent>
......@@ -255,7 +256,7 @@ void FilterChain::paint(TerminalDisplay* td, QPainter& painter)
for (const auto &spot : spots) {
QRegion region;
if (spot->type() == HotSpot::Link || spot->type() == HotSpot::EMailAddress || spot->type() == HotSpot::EscapedUrl) {
QPair<QRegion, QRect> spotRegion = spot->region(td->fontWidth(), td->fontHeight(), td->columns(), td->contentRect());
QPair<QRegion, QRect> spotRegion = spot->region(td->terminalFont()->fontWidth(), td->terminalFont()->fontHeight(), td->columns(), td->contentRect());
region = spotRegion.first;
QRect r = spotRegion.second;
......@@ -318,10 +319,10 @@ void FilterChain::paint(TerminalDisplay* td, QPainter& painter)
// because the check below for the position of the cursor
// finds it on the border of the target area
QRect r;
r.setCoords(startColumn * td->fontWidth() + td->contentRect().left(),
line * td->fontHeight() + td->contentRect().top(),
endColumn * td->fontWidth() + td->contentRect().left() - 1,
(line + 1)* td->fontHeight() + td->contentRect().top() - 1);
r.setCoords(startColumn * td->terminalFont()->fontWidth() + td->contentRect().left(),
line * td->terminalFont()->fontHeight() + td->contentRect().top(),
endColumn * td->terminalFont()->fontWidth() + td->contentRect().left() - 1,
(line + 1)* td->terminalFont()->fontHeight() + td->contentRect().top() - 1);
// Underline link hotspots
// TODO: Fix accessing the urlHint here.
......
......@@ -11,6 +11,7 @@
#include <QDebug>
#include "terminalDisplay/TerminalDisplay.h"
#include "terminalDisplay/TerminalFonts.h"
#include "FileFilterHotspot.h"
using namespace Konsole;
......@@ -123,7 +124,7 @@ void HotSpot::mouseEnterEvent(TerminalDisplay *td, QMouseEvent *ev)
td->setCursor(Qt::PointingHandCursor);
}
auto r = region(td->fontWidth(), td->fontHeight(), td->columns(), td->contentRect()).first;
auto r = region(td->terminalFont()->fontWidth(), td->terminalFont()->fontHeight(), td->columns(), td->contentRect()).first;
td->update(r);
}
......@@ -135,7 +136,7 @@ void HotSpot::mouseLeaveEvent(TerminalDisplay *td, QMouseEvent *ev)
return;
}
auto r = region(td->fontWidth(), td->fontHeight(), td->columns(), td->contentRect()).first;
auto r = region(td->terminalFont()->fontWidth(), td->terminalFont()->fontHeight(), td->columns(), td->contentRect()).first;
td->update(r);
td->resetCursor();
......
......@@ -11,6 +11,7 @@
#include "profile/ProfileManager.h"
#include "konsoledebug.h"
#include "terminalDisplay/TerminalColor.h"
#include "terminalDisplay/TerminalFonts.h"
// Qt
#include <QApplication>
......@@ -1656,17 +1657,17 @@ void SessionController::clearHistoryAndReset()
void SessionController::increaseFontSize()
{
view()->increaseFontSize();
view()->terminalFont()->increaseFontSize();
}
void SessionController::decreaseFontSize()
{
view()->decreaseFontSize();
view()->terminalFont()->decreaseFontSize();
}
void SessionController::resetFontSize()
{
view()->resetFontSize();
view()->terminalFont()->resetFontSize();
}
void SessionController::monitorActivity(bool monitor)
......
......@@ -36,6 +36,7 @@
#include "SessionController.h"
#include "terminalDisplay/TerminalDisplay.h"
#include "terminalDisplay/TerminalFonts.h"
using namespace Konsole;
......@@ -298,7 +299,7 @@ void SessionManager::sessionProfileCommandReceived(const QString &text)
QHash<TerminalDisplay *, QFont> zoomFontSizes;
const QList<TerminalDisplay *> viewsList = session->views();
for (TerminalDisplay *view : viewsList) {
const QFont &viewCurFont = view->getVTFont();
const QFont &viewCurFont = view->terminalFont()->getVTFont();
if (viewCurFont != _sessionProfiles[session]->font()) {
zoomFontSizes.insert(view, viewCurFont);
}
......@@ -329,7 +330,7 @@ void SessionManager::sessionProfileCommandReceived(const QString &text)
QHashIterator<TerminalDisplay *, QFont> it(zoomFontSizes);
while (it.hasNext()) {
it.next();
it.key()->setVTFont(it.value());
it.key()->terminalFont()->setVTFont(it.value());
}
}
}
......
This diff is collapsed.
......@@ -39,6 +39,7 @@ namespace Konsole {
class TerminalPainter;
class TerminalScrollBar;
class TerminalColor;
class TerminalFont;
class KonsolePrintManager;
......@@ -130,9 +131,6 @@ public:
/** Specifies whether or not text can blink. */
void setBlinkingTextEnabled(bool blink);
void setLineSpacing(uint);
uint lineSpacing() const;
void setSessionController(SessionController *controller);
SessionController *sessionController();
......@@ -188,23 +186,6 @@ public:
return _usedColumns;
}
/**
* Returns the height of the characters in the font used to draw the text in the display.
*/
int fontHeight() const
{
return _fontHeight;
}
/**
* Returns the width of the characters in the display.
* This assumes the use of a fixed-width font.
*/
int fontWidth() const
{
return _fontWidth;
}
void setSize(int columns, int lines);
void propagateSize();
......@@ -240,30 +221,10 @@ public:
*/
int bellMode() const;
/** Returns the font used to draw characters in the display */
QFont getVTFont()
{
return font();
}
TerminalHeaderBar *headerBar() const
{
return _headerBar;
}
/**
* Sets the font used to draw the display. Has no effect if @p font
* is larger than the size of the display itself.
*/
void setVTFont(const QFont &f);
/** Increases the font size */
void increaseFontSize();
/** Decreases the font size */
void decreaseFontSize();
/** Reset the font size */
void resetFontSize();
void resetCursor();
......@@ -334,6 +295,11 @@ public:
return _terminalColor;
}
TerminalFont *terminalFont() const
{
return _terminalFont;
}
bool cursorBlinking() const
{
return _cursorBlinking;
......@@ -349,31 +315,11 @@ public:
return _cursorShape;
}
bool boldIntense() const
{
return _boldIntense;
}
bool useFontLineCharacters() const
{
return _useFontLineCharacters;
}
bool bidiEnabled() const
{
return _bidiEnabled;
}
int fontAscent() const
{
return _fontAscent;
}
bool antialiasText() const
{
return _antialiasText;
}
ColorSchemeWallpaper::Ptr wallpaper() const
{
return _wallpaper;
......@@ -522,7 +468,6 @@ Q_SIGNALS:
* @param eventType The type of event. 0 for a mouse press / release or 1 for mouse motion
*/
void mouseSignal(int button, int column, int line, int eventType);
void changedFontMetricSignal(int height, int width);
void changedContentSizeSignal(int height, int width);
/**
......@@ -550,7 +495,7 @@ Q_SIGNALS:
void peekPrimaryRequested(bool doPeek);
void drawContents(Character *image, QPainter &paint, const QRect &rect, bool printerFriendly, int imageSize, bool bidiEnabled, bool &fixedFont,
void drawContents(Character *image, QPainter &paint, const QRect &rect, bool printerFriendly, int imageSize, bool bidiEnabled,
QVector<LineProperty> lineProperties);
void drawCurrentResultRect(QPainter &painter, QRect searchResultRect);
......@@ -582,7 +527,6 @@ protected:
void wheelEvent(QWheelEvent *ev) override;
bool focusNextPrevChild(bool next) override;
void fontChange(const QFont &);
void extendSelection(const QPoint &position);
// drag and drop
......@@ -673,12 +617,6 @@ private:
QVBoxLayout *_verticalLayout;
bool _fixedFont; // has fixed pitch
int _fontHeight; // height
int _fontWidth; // width
int _fontAscent; // ascend
bool _boldIntense; // Whether intense colors should be rendered with bold font
int _lines; // the number of lines that can be displayed in the widget
int _columns; // the number of columns that can be displayed in the widget
......@@ -754,8 +692,6 @@ private:
//terminal output - informing them what has happened and how to resume output
KMessageWidget *_outputSuspendedMessageWidget;
uint _lineSpacing;
QSize _size;
ColorScheme const* _colorScheme;
......@@ -770,9 +706,6 @@ private:
InputMethodData _inputMethodData;
bool _antialiasText; // do we anti-alias or not
bool _useFontLineCharacters;
//the delay in milliseconds between redrawing blinking text
static const int TEXT_BLINK_DELAY = 500;
......@@ -814,6 +747,7 @@ private:
TerminalPainter *_terminalPainter;
TerminalScrollBar *_scrollBar;
TerminalColor *_terminalColor;
TerminalFont *_terminalFont;
KonsolePrintManager *_printManager;
};
......
/*
SPDX-FileCopyrightText: 2020-2020 Gustavo Carneiro <gcarneiroa@hotmail.com>
SPDX-FileCopyrightText: 2007-2008 Robert Knight <robertknight@gmail.com>
SPDX-FileCopyrightText: 1997, 1998 Lars Doelle <lars.doelle@on-line.de>
SPDX-License-Identifier: GPL-2.0-or-later
*/
// Own
#include "TerminalFonts.h"
// Konsole
#include "konsoledebug.h"
#include "terminalDisplay/TerminalDisplay.h"
#include "session/SessionManager.h"
#include "session/SessionController.h"
#include "session/Session.h"
// Qt
#include <QFont>
#include <QFontMetrics>
#define REPCHAR "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
"abcdefgjijklmnopqrstuvwxyz" \
"0123456789./+@"
namespace Konsole
{
TerminalFont::TerminalFont(QWidget *parent)
: QWidget(parent)
, m_fixedFont(true)
, m_lineSpacing(0)
, m_fontHeight(1)
, m_fontWidth(1)
, m_fontAscent(1)
, m_boldIntense(false)
, m_antialiasText(true)
, m_useFontLineCharacters(false)
, m_profile(nullptr)
{
}
void TerminalFont::applyProfile(const Profile::Ptr &profile)
{
m_profile = profile;
m_antialiasText = profile->antiAliasFonts();
m_boldIntense = profile->boldIntense();
m_useFontLineCharacters = profile->useFontLineCharacters();
m_lineSpacing = uint(profile->lineSpacing());
setVTFont(profile->font());
}
void TerminalFont::setVTFont(const QFont &f)
{
QFont newFont(f);
int strategy = 0;
// hint that text should be drawn with- or without anti-aliasing.
// depending on the user's font configuration, this may not be respected
strategy |= m_antialiasText ? QFont::PreferAntialias : QFont::NoAntialias;
// Konsole cannot handle non-integer font metrics
strategy |= QFont::ForceIntegerMetrics;
// In case the provided font doesn't have some specific characters it should
// fall back to a Monospace fonts.
newFont.setStyleHint(QFont::TypeWriter, QFont::StyleStrategy(strategy));
// Try to check that a good font has been loaded.
// For some fonts, ForceIntegerMetrics causes height() == 0 which
// will cause Konsole to crash later.
QFontMetrics fontMetrics2(newFont);
if (fontMetrics2.height() < 1) {
qCDebug(KonsoleDebug)<<"The font "<<newFont.toString()<<" has an invalid height()";
// Ask for a generic font so at least it is usable.
// Font listed in profile's dialog will not be updated.
newFont = QFont(QStringLiteral("Monospace"));
// Set style strategy without ForceIntegerMetrics for the font
strategy &= ~QFont::ForceIntegerMetrics;
newFont.setStyleHint(QFont::TypeWriter, QFont::StyleStrategy(strategy));
qCDebug(KonsoleDebug)<<"Font changed to "<<newFont.toString();
}
// experimental optimization. Konsole assumes that the terminal is using a
// mono-spaced font, in which case kerning information should have an effect.
// Disabling kerning saves some computation when rendering text.
newFont.setKerning(false);
// "Draw intense colors in bold font" feature needs to use different font weights. StyleName
// property, when set, doesn't allow weight changes. Since all properties (weight, stretch,
// italic, etc) are stored in QFont independently, in almost all cases styleName is not needed.
newFont.setStyleName(QString());
if (newFont == qobject_cast<QWidget*>(parent())->font()) {
// Do not process the same font again
return;
}
QFontInfo fontInfo(newFont);
// QFontInfo::fixedPitch() appears to not match QFont::fixedPitch() - do not test it.
// related? https://bugreports.qt.io/browse/QTBUG-34082
if (fontInfo.family() != newFont.family()
|| !qFuzzyCompare(fontInfo.pointSizeF(), newFont.pointSizeF())
|| fontInfo.styleHint() != newFont.styleHint()
|| fontInfo.weight() != newFont.weight()
|| fontInfo.style() != newFont.style()
|| fontInfo.underline() != newFont.underline()
|| fontInfo.strikeOut() != newFont.strikeOut()
|| fontInfo.rawMode() != newFont.rawMode()) {
const QString nonMatching = QString::asprintf("%s,%g,%d,%d,%d,%d,%d,%d,%d,%d",
qPrintable(fontInfo.family()),
fontInfo.pointSizeF(),
-1, // pixelSize is not used
static_cast<int>(fontInfo.styleHint()),
fontInfo.weight(),
static_cast<int>(fontInfo.style()),
static_cast<int>(fontInfo.underline()),
static_cast<int>(fontInfo.strikeOut()),
// Intentional newFont use - fixedPitch is bugged, see comment above
static_cast<int>(newFont.fixedPitch()),
static_cast<int>(fontInfo.rawMode()));
qCDebug(KonsoleDebug) << "The font to use in the terminal can not be matched exactly on your system.";
qCDebug(KonsoleDebug) << " Selected: " << newFont.toString();
qCDebug(KonsoleDebug) << " System : " << nonMatching;
}
qobject_cast<QWidget*>(parent())->setFont(newFont);
fontChange(newFont);
}
QFont TerminalFont::getVTFont() const
{
return qobject_cast<QWidget*>(parent())->font();
}
void TerminalFont::increaseFontSize()
{
QFont font = qobject_cast<QWidget*>(parent())->font();
font.setPointSizeF(font.pointSizeF() + 1);
setVTFont(font);
}
void TerminalFont::decreaseFontSize()
{
const qreal MinimumFontSize = 6;
QFont font = qobject_cast<QWidget*>(parent())->font();
font.setPointSizeF(qMax(font.pointSizeF() - 1, MinimumFontSize));
setVTFont(font);
}
void TerminalFont::resetFontSize()
{
const qreal MinimumFontSize = 6;
TerminalDisplay *display = qobject_cast<TerminalDisplay*>(parent());
QFont font = display->font();
Profile::Ptr currentProfile = SessionManager::instance()->sessionProfile(display->sessionController()->session());
const qreal defaultFontSize = currentProfile->font().pointSizeF();
font.setPointSizeF(qMax(defaultFontSize, MinimumFontSize));
setVTFont(font);
}
void TerminalFont::setLineSpacing(uint i)
{
m_lineSpacing = i;
fontChange(qobject_cast<QWidget*>(parent())->font());
}
uint TerminalFont::lineSpacing() const
{
return m_lineSpacing;
}
bool TerminalFont::fixedFont() const
{
return m_fixedFont;
}
void TerminalFont::setFixedFont(const bool fixedFont)
{
m_fixedFont = fixedFont;
}
int TerminalFont::fontHeight() const
{
return m_fontHeight;
}
int TerminalFont::fontWidth() const
{
return m_fontWidth;
}
int TerminalFont::fontAscent() const
{
return m_fontAscent;
}
bool TerminalFont::boldIntense() const
{
return m_boldIntense;
}
bool TerminalFont::antialiasText() const
{
return m_antialiasText;
}
bool TerminalFont::useFontLineCharacters() const
{
return m_useFontLineCharacters;
}
void TerminalFont::fontChange(const QFont &)
{
QFontMetrics fm(qobject_cast<QWidget*>(parent())->font());
m_fontHeight = fm.height() + m_lineSpacing;
Q_ASSERT(m_fontHeight > 0);
/* TODO: When changing the three deprecated width() below
* consider the info in
* https://phabricator.kde.org/D23144 comments
* horizontalAdvance() was added in Qt 5.11 (which should be the
* minimum for 20.04 or 20.08 KDE Applications release)
*/
// waba TerminalDisplay 1.123:
// "Base character width on widest ASCII character. This prevents too wide
// characters in the presence of double wide (e.g. Japanese) characters."
// Get the width from representative normal width characters
m_fontWidth = qRound((static_cast<double>(fm.horizontalAdvance(QStringLiteral(REPCHAR))) / static_cast<double>(qstrlen(REPCHAR))));
m_fixedFont = true;
const int fw = fm.horizontalAdvance(QLatin1Char(REPCHAR[0]));
for (unsigned int i = 1; i < qstrlen(REPCHAR); i++) {
if (fw != fm.horizontalAdvance(QLatin1Char(REPCHAR[i]))) {
m_fixedFont = false;
break;
}
}
if (m_fontWidth < 1) {
m_fontWidth = 1;
}
m_fontAscent = fm.ascent();
qobject_cast<TerminalDisplay*>(parent())->propagateSize();
update();
}
}
/*
SPDX-FileCopyrightText: 2020-2020 Gustavo Carneiro <gcarneiroa@hotmail.com>
SPDX-FileCopyrightText: 2007-2008 Robert Knight <robertknight@gmail.com>
SPDX-FileCopyrightText: 1997, 1998 Lars Doelle <lars.doelle@on-line.de>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef TERMINALFONTS_H
#define TERMINALFONTS_H
#include <QWidget>
#include "profile/Profile.h"
class QFont;
namespace Konsole
{
class TerminalFont : public QWidget
{
Q_OBJECT
public:
explicit TerminalFont(QWidget *parent = nullptr);
~TerminalFont() = default;
void applyProfile(const Profile::Ptr &profile);
void setVTFont(const QFont &f);
QFont getVTFont() const;
void increaseFontSize();
void decreaseFontSize();
void resetFontSize();
void setLineSpacing(uint);
uint lineSpacing() const;
bool fixedFont() const;
void setFixedFont(const bool);
int fontHeight() const;
int fontWidth() const;
int fontAscent() const;
bool boldIntense() const;