Warning, file /plasma/plasma-workspace/kcms/fonts/fonts.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002     SPDX-FileCopyrightText: 1997 Mark Donohoe
0003     SPDX-FileCopyrightText: 1999 Lars Knoll
0004     SPDX-FileCopyrightText: 2000 Rik Hemsley
0005     SPDX-FileCopyrightText: 2015 Antonis Tsiapaliokas <antonis.tsiapaliokas@kde.org>
0006     SPDX-FileCopyrightText: 2017 Marco Martin <mart@kde.org>
0007     SPDX-FileCopyrightText: 2019 Benjamin Port <benjamin.port@enioka.com>
0008 
0009     Ported to kcontrol2:
0010     SPDX-FileCopyrightText: Geert Jansen
0011 
0012     SPDX-License-Identifier: LGPL-2.0-or-later
0013 */
0014 
0015 #include "fonts.h"
0016 
0017 #include <QApplication>
0018 #include <QDBusConnection>
0019 #include <QDBusMessage>
0020 #include <QFontDatabase>
0021 #include <QQmlEngine>
0022 #include <QQuickItem>
0023 #include <QQuickView>
0024 #include <QWindow>
0025 
0026 #include <KAcceleratorManager>
0027 #include <KConfig>
0028 #include <KConfigGroup>
0029 #include <KFontChooserDialog>
0030 #include <KLocalizedString>
0031 #include <KPluginFactory>
0032 #include <KWindowSystem>
0033 
0034 #include "../kcms-common_p.h"
0035 #include "krdb.h"
0036 #include "kxftconfig.h"
0037 #include "previewimageprovider.h"
0038 
0039 #include "fontsdata.h"
0040 
0041 /**** DLL Interface ****/
0042 K_PLUGIN_FACTORY_WITH_JSON(KFontsFactory, "kcm_fonts.json", registerPlugin<KFonts>(); registerPlugin<FontsData>();)
0043 
0044 /**** KFonts ****/
0045 
0046 KFonts::KFonts(QObject *parent, const KPluginMetaData &metaData, const QVariantList &args)
0047     : KQuickAddons::ManagedConfigModule(parent, metaData, args)
0048     , m_data(new FontsData(this))
0049     , m_subPixelOptionsModel(new QStandardItemModel(this))
0050     , m_hintingOptionsModel(new QStandardItemModel(this))
0051 {
0052     qmlRegisterAnonymousType<QStandardItemModel>("QStandardItemModel", 1);
0053     qmlRegisterAnonymousType<FontsSettings>("FontsSettings", 1);
0054     qmlRegisterAnonymousType<FontsAASettings>("FontsAASettings", 1);
0055 
0056     setButtons(Apply | Default | Help);
0057 
0058     for (KXftConfig::SubPixel::Type t :
0059          {KXftConfig::SubPixel::None, KXftConfig::SubPixel::Rgb, KXftConfig::SubPixel::Bgr, KXftConfig::SubPixel::Vrgb, KXftConfig::SubPixel::Vbgr}) {
0060         auto item = new QStandardItem(KXftConfig::description(t));
0061         m_subPixelOptionsModel->appendRow(item);
0062     }
0063 
0064     for (KXftConfig::Hint::Style s : {KXftConfig::Hint::None, KXftConfig::Hint::Slight, KXftConfig::Hint::Medium, KXftConfig::Hint::Full}) {
0065         auto item = new QStandardItem(KXftConfig::description(s));
0066         m_hintingOptionsModel->appendRow(item);
0067     }
0068     connect(fontsAASettings(), &FontsAASettings::hintingChanged, this, &KFonts::hintingCurrentIndexChanged);
0069     connect(fontsAASettings(), &FontsAASettings::subPixelChanged, this, &KFonts::subPixelCurrentIndexChanged);
0070 }
0071 
0072 KFonts::~KFonts()
0073 {
0074 }
0075 
0076 FontsSettings *KFonts::fontsSettings() const
0077 {
0078     return m_data->fontsSettings();
0079 }
0080 
0081 FontsAASettings *KFonts::fontsAASettings() const
0082 {
0083     return m_data->fontsAASettings();
0084 }
0085 
0086 QAbstractItemModel *KFonts::subPixelOptionsModel() const
0087 {
0088     return m_subPixelOptionsModel;
0089 }
0090 
0091 QAbstractItemModel *KFonts::hintingOptionsModel() const
0092 {
0093     return m_hintingOptionsModel;
0094 }
0095 
0096 void KFonts::load()
0097 {
0098     // first load all the settings
0099     ManagedConfigModule::load();
0100 
0101     // Load preview
0102     // NOTE: This needs to be done AFTER AA settings is loaded
0103     // otherwise AA settings will be reset in process of loading
0104     // previews
0105     engine()->addImageProvider("preview", new PreviewImageProvider(fontsSettings()->font()));
0106 
0107     // KCM expect save state to be false at this point (can be true because if a font setting loaded
0108     // from the config isn't available on the system, font substitution may take place)
0109     setNeedsSave(false);
0110 }
0111 
0112 void KFonts::save()
0113 {
0114     auto dpiItem = fontsAASettings()->findItem("forceFontDPI");
0115     auto dpiWaylandItem = fontsAASettings()->findItem("forceFontDPIWayland");
0116     auto antiAliasingItem = fontsAASettings()->findItem("antiAliasing");
0117     Q_ASSERT(dpiItem && dpiWaylandItem && antiAliasingItem);
0118     if (dpiItem->isSaveNeeded() || dpiWaylandItem->isSaveNeeded() || antiAliasingItem->isSaveNeeded()) {
0119         Q_EMIT aliasingChangeApplied();
0120     }
0121 
0122     auto forceFontDPIChanged = dpiItem->isSaveNeeded();
0123 
0124     ManagedConfigModule::save();
0125 
0126 #if HAVE_X11
0127     // if the setting is reset in the module, remove the dpi value,
0128     // otherwise don't explicitly remove it and leave any possible system-wide value
0129     if (fontsAASettings()->forceFontDPI() == 0 && forceFontDPIChanged && !KWindowSystem::isPlatformWayland()) {
0130         QProcess proc;
0131         proc.setProcessChannelMode(QProcess::ForwardedChannels);
0132         proc.start("xrdb",
0133                    QStringList() << "-quiet"
0134                                  << "-remove"
0135                                  << "-nocpp");
0136         if (proc.waitForStarted()) {
0137             proc.write(QByteArray("Xft.dpi\n"));
0138             proc.closeWriteChannel();
0139             proc.waitForFinished();
0140         }
0141     }
0142     QApplication::processEvents();
0143 #endif
0144 
0145     // Notify the world about the font changes
0146     if (qEnvironmentVariableIsSet("KDE_FULL_SESSION")) {
0147         QDBusMessage message = QDBusMessage::createSignal("/KDEPlatformTheme", "org.kde.KDEPlatformTheme", "refreshFonts");
0148         QDBusConnection::sessionBus().send(message);
0149     }
0150 
0151     runRdb(KRdbExportXftSettings | KRdbExportGtkTheme);
0152 }
0153 
0154 void KFonts::adjustFont(const QFont &font, const QString &category)
0155 {
0156     QFont selFont = font;
0157     int ret = KFontChooserDialog::getFont(selFont, KFontChooser::NoDisplayFlags);
0158 
0159     if (ret == QDialog::Accepted) {
0160         if (category == QLatin1String("font")) {
0161             fontsSettings()->setFont(selFont);
0162         } else if (category == QLatin1String("menuFont")) {
0163             fontsSettings()->setMenuFont(selFont);
0164         } else if (category == QLatin1String("toolBarFont")) {
0165             fontsSettings()->setToolBarFont(selFont);
0166         } else if (category == QLatin1String("activeFont")) {
0167             fontsSettings()->setActiveFont(selFont);
0168         } else if (category == QLatin1String("smallestReadableFont")) {
0169             fontsSettings()->setSmallestReadableFont(selFont);
0170         } else if (category == QLatin1String("fixed")) {
0171             fontsSettings()->setFixed(selFont);
0172         }
0173     }
0174     Q_EMIT fontsHaveChanged();
0175 }
0176 
0177 void KFonts::adjustAllFonts()
0178 {
0179     QFont font = fontsSettings()->font();
0180     KFontChooser::FontDiffFlags fontDiffFlags;
0181     int ret = KFontChooserDialog::getFontDiff(font, fontDiffFlags, KFontChooser::NoDisplayFlags);
0182 
0183     if (ret == QDialog::Accepted && fontDiffFlags) {
0184         fontsSettings()->setFont(applyFontDiff(fontsSettings()->font(), font, fontDiffFlags));
0185         fontsSettings()->setMenuFont(applyFontDiff(fontsSettings()->menuFont(), font, fontDiffFlags));
0186         fontsSettings()->setToolBarFont(applyFontDiff(fontsSettings()->toolBarFont(), font, fontDiffFlags));
0187         fontsSettings()->setActiveFont(applyFontDiff(fontsSettings()->activeFont(), font, fontDiffFlags));
0188 
0189         QFont smallestFont = font;
0190         // Make the small font 2 points smaller than the general font, but only
0191         // if the general font is 9pt or higher or else the small font would be
0192         // borderline unreadable. Assume that if the user is making the font
0193         // tiny, they want a tiny font everywhere.
0194         const int generalFontPointSize = font.pointSize();
0195         if (generalFontPointSize >= 9) {
0196             smallestFont.setPointSize(generalFontPointSize - 2);
0197         }
0198         fontsSettings()->setSmallestReadableFont(applyFontDiff(fontsSettings()->smallestReadableFont(), smallestFont, fontDiffFlags));
0199 
0200         const QFont adjustedFont = applyFontDiff(fontsSettings()->fixed(), font, fontDiffFlags);
0201         if (QFontInfo(adjustedFont).fixedPitch()) {
0202             fontsSettings()->setFixed(adjustedFont);
0203         }
0204     }
0205 }
0206 
0207 QFont KFonts::applyFontDiff(const QFont &fnt, const QFont &newFont, int fontDiffFlags)
0208 {
0209     QFont font(fnt);
0210 
0211     if (fontDiffFlags & KFontChooser::FontDiffSize) {
0212         font.setPointSizeF(newFont.pointSizeF());
0213     }
0214     if ((fontDiffFlags & KFontChooser::FontDiffFamily)) {
0215         font.setFamily(newFont.family());
0216     }
0217     if (fontDiffFlags & KFontChooser::FontDiffStyle) {
0218         font.setWeight(newFont.weight());
0219         font.setStyle(newFont.style());
0220         font.setUnderline(newFont.underline());
0221         font.setStyleName(newFont.styleName());
0222     }
0223 
0224     return font;
0225 }
0226 
0227 int KFonts::subPixelCurrentIndex() const
0228 {
0229     return fontsAASettings()->subPixel() - KXftConfig::SubPixel::None;
0230 }
0231 
0232 void KFonts::setSubPixelCurrentIndex(int idx)
0233 {
0234     fontsAASettings()->setSubPixel(static_cast<KXftConfig::SubPixel::Type>(KXftConfig::SubPixel::None + idx));
0235 }
0236 
0237 int KFonts::hintingCurrentIndex() const
0238 {
0239     return fontsAASettings()->hinting() - KXftConfig::Hint::None;
0240 }
0241 
0242 void KFonts::setHintingCurrentIndex(int idx)
0243 {
0244     fontsAASettings()->setHinting(static_cast<KXftConfig::Hint::Style>(KXftConfig::Hint::None + idx));
0245 }
0246 
0247 #include "fonts.moc"