Warning, file /plasma/plasma-workspace/kcms/fonts/fontsaasettings.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: 2020 Benjamin Port <benjamin.port@enioka.com>
0003     SPDX-FileCopyrightText: 2022 Harald Sitter <sitter@kde.org>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "fontsaasettings.h"
0009 
0010 #include <KWindowSystem>
0011 #include <QDebug>
0012 
0013 namespace
0014 {
0015 bool defaultExclude()
0016 {
0017     return false;
0018 }
0019 
0020 int defaultExcludeFrom()
0021 {
0022     return 8;
0023 }
0024 
0025 int defaultExcludeTo()
0026 {
0027     return 15;
0028 }
0029 
0030 bool defaultAntiAliasing()
0031 {
0032     return true;
0033 }
0034 
0035 KXftConfig::SubPixel::Type defaultSubPixel()
0036 {
0037     return KXftConfig::SubPixel::Rgb;
0038 }
0039 
0040 KXftConfig::Hint::Style defaultHinting()
0041 {
0042     return KXftConfig::Hint::Slight;
0043 }
0044 }
0045 
0046 class FontAASettingsStore : public QObject
0047 {
0048     Q_OBJECT
0049     Q_PROPERTY(bool exclude READ exclude WRITE setExclude)
0050     Q_PROPERTY(int excludeFrom READ excludeFrom WRITE setExcludeFrom)
0051     Q_PROPERTY(int excludeTo READ excludeTo WRITE setExcludeTo)
0052     Q_PROPERTY(bool antiAliasing READ antiAliasing WRITE setAntiAliasing)
0053     Q_PROPERTY(KXftConfig::SubPixel::Type subPixel READ subPixel WRITE setSubPixel)
0054     Q_PROPERTY(KXftConfig::Hint::Style hinting READ hinting WRITE setHinting)
0055 public:
0056     FontAASettingsStore(FontsAASettings *parent = nullptr)
0057         : QObject(parent)
0058     {
0059         load();
0060     }
0061 
0062     bool exclude() const
0063     {
0064         return m_exclude;
0065     }
0066 
0067     void setExclude(bool exclude)
0068     {
0069         if (m_exclude != exclude) {
0070             m_exclude = exclude;
0071         }
0072     }
0073 
0074     int excludeFrom() const
0075     {
0076         return m_excludeFrom;
0077     }
0078 
0079     void setExcludeFrom(int excludeFrom)
0080     {
0081         if (m_excludeFrom != excludeFrom) {
0082             m_excludeFrom = excludeFrom;
0083         }
0084     }
0085 
0086     int excludeTo() const
0087     {
0088         return m_excludeTo;
0089     }
0090 
0091     void setExcludeTo(int excludeTo)
0092     {
0093         if (m_excludeTo != excludeTo) {
0094             m_excludeTo = excludeTo;
0095         }
0096     }
0097 
0098     bool isImmutable() const
0099     {
0100         return m_isImmutable;
0101     }
0102 
0103     bool antiAliasing() const
0104     {
0105         return m_antiAliasing;
0106     }
0107 
0108     void setAntiAliasing(bool antiAliasing)
0109     {
0110         if (antiAliasing != m_antiAliasing) {
0111             m_antiAliasingChanged = true;
0112             m_antiAliasing = antiAliasing;
0113         }
0114     }
0115 
0116     KXftConfig::SubPixel::Type subPixel() const
0117     {
0118         return m_subPixel;
0119     }
0120 
0121     void setSubPixel(KXftConfig::SubPixel::Type subPixel)
0122     {
0123         if (m_subPixel != subPixel) {
0124             m_subPixelChanged = true;
0125             m_subPixel = subPixel;
0126         }
0127     }
0128 
0129     KXftConfig::Hint::Style hinting() const
0130     {
0131         return m_hinting;
0132     }
0133 
0134     void setHinting(KXftConfig::Hint::Style hinting)
0135     {
0136         if (m_hinting != hinting) {
0137             m_hintingChanged = true;
0138             m_hinting = hinting;
0139         }
0140     }
0141 
0142     void save()
0143     {
0144         KXftConfig xft;
0145         KXftConfig::AntiAliasing::State aaState = KXftConfig::AntiAliasing::NotSet;
0146         if (m_antiAliasingChanged || xft.antiAliasingHasLocalConfig()) {
0147             aaState = m_antiAliasing ? KXftConfig::AntiAliasing::Enabled : KXftConfig::AntiAliasing::Disabled;
0148         }
0149         xft.setAntiAliasing(aaState);
0150 
0151         if (m_exclude) {
0152             xft.setExcludeRange(m_excludeFrom, m_excludeTo);
0153         } else {
0154             xft.setExcludeRange(0, 0);
0155         }
0156 
0157         if (m_subPixelChanged || xft.subPixelTypeHasLocalConfig()) {
0158             xft.setSubPixelType(m_subPixel);
0159         } else {
0160             xft.setSubPixelType(KXftConfig::SubPixel::NotSet);
0161         }
0162 
0163         if (m_hintingChanged || xft.hintStyleHasLocalConfig()) {
0164             xft.setHintStyle(m_hinting);
0165         } else {
0166             xft.setHintStyle(KXftConfig::Hint::NotSet);
0167         }
0168 
0169         // Write to KConfig to sync with krdb
0170         KSharedConfig::Ptr config = KSharedConfig::openConfig("kdeglobals");
0171         KConfigGroup grp(config, "General");
0172 
0173         grp.writeEntry("XftSubPixel", KXftConfig::toStr(m_subPixel));
0174 
0175         if (aaState == KXftConfig::AntiAliasing::NotSet) {
0176             grp.revertToDefault("XftAntialias");
0177         } else {
0178             grp.writeEntry("XftAntialias", aaState == KXftConfig::AntiAliasing::Enabled);
0179         }
0180 
0181         QString hs(KXftConfig::toStr(m_hinting));
0182         if (hs != grp.readEntry("XftHintStyle")) {
0183             if (KXftConfig::Hint::NotSet == m_hinting) {
0184                 grp.revertToDefault("XftHintStyle");
0185             } else {
0186                 grp.writeEntry("XftHintStyle", hs);
0187             }
0188         }
0189 
0190         xft.apply();
0191 
0192         m_subPixelChanged = false;
0193         m_hintingChanged = false;
0194         m_antiAliasingChanged = false;
0195     }
0196 
0197     void load()
0198     {
0199         double from, to;
0200         KXftConfig xft;
0201 
0202         if (xft.getExcludeRange(from, to)) {
0203             setExclude(true);
0204             setExcludeFrom(from);
0205             setExcludeTo(to);
0206         } else {
0207             setExclude(defaultExclude());
0208             setExcludeFrom(defaultExcludeFrom());
0209             setExcludeTo(defaultExcludeTo());
0210         }
0211 
0212         // sub pixel
0213         KXftConfig::SubPixel::Type spType = KXftConfig::SubPixel::NotSet;
0214         xft.getSubPixelType(spType);
0215         // if it is not set, we have no subpixel hinting
0216         if (spType == KXftConfig::SubPixel::NotSet) {
0217             spType = KXftConfig::SubPixel::None;
0218         }
0219         setSubPixel(spType);
0220 
0221         // hinting
0222         KXftConfig::Hint::Style hStyle = KXftConfig::Hint::NotSet;
0223         xft.getHintStyle(hStyle);
0224         // if it is not set, we have no hinting
0225         if (hStyle == KXftConfig::Hint::NotSet) {
0226             hStyle = KXftConfig::Hint::None;
0227         }
0228         setHinting(hStyle);
0229 
0230         KSharedConfig::Ptr config = KSharedConfig::openConfig("kdeglobals");
0231         KConfigGroup cg(config, "General");
0232         m_isImmutable = cg.isEntryImmutable("XftAntialias");
0233 
0234         const auto aaState = xft.getAntiAliasing();
0235         setAntiAliasing(aaState != KXftConfig::AntiAliasing::Disabled);
0236 
0237         m_subPixelChanged = false;
0238         m_hintingChanged = false;
0239         m_antiAliasingChanged = false;
0240     }
0241 
0242 private:
0243     bool m_isImmutable;
0244     bool m_antiAliasing;
0245     bool m_antiAliasingChanged;
0246     KXftConfig::SubPixel::Type m_subPixel;
0247     bool m_subPixelChanged;
0248     KXftConfig::Hint::Style m_hinting;
0249     bool m_hintingChanged;
0250     bool m_exclude;
0251     int m_excludeFrom;
0252     int m_excludeTo;
0253 };
0254 
0255 FontsAASettings::FontsAASettings(QObject *parent)
0256     : FontsAASettingsBase(parent)
0257     , m_fontAASettingsStore(new FontAASettingsStore(this))
0258 {
0259     addItemInternal("exclude", defaultExclude(), &FontsAASettings::excludeChanged);
0260     addItemInternal("excludeFrom", defaultExcludeFrom(), &FontsAASettings::excludeFromChanged);
0261     addItemInternal("excludeTo", defaultExcludeTo(), &FontsAASettings::excludeToChanged);
0262     addItemInternal("antiAliasing", defaultAntiAliasing(), &FontsAASettings::antiAliasingChanged);
0263     addItemInternal("subPixel", defaultSubPixel(), &FontsAASettings::subPixelChanged);
0264     addItemInternal("hinting", defaultHinting(), &FontsAASettings::hintingChanged);
0265 
0266     connect(this, &FontsAASettings::forceFontDPIWaylandChanged, this, &FontsAASettings::dpiChanged);
0267     connect(this, &FontsAASettings::forceFontDPIChanged, this, &FontsAASettings::dpiChanged);
0268 }
0269 
0270 void FontsAASettings::addItemInternal(const QByteArray &propertyName, const QVariant &defaultValue, NotifySignalType notifySignal)
0271 {
0272     auto item = new KPropertySkeletonItem(m_fontAASettingsStore, propertyName, defaultValue);
0273     addItem(item, propertyName);
0274     item->setNotifyFunction([this, notifySignal] {
0275         Q_EMIT(this->*notifySignal)();
0276     });
0277 }
0278 
0279 bool FontsAASettings::exclude() const
0280 {
0281     return findItem("exclude")->property().toBool();
0282 }
0283 
0284 void FontsAASettings::setExclude(bool exclude)
0285 {
0286     findItem("exclude")->setProperty(exclude);
0287 }
0288 
0289 int FontsAASettings::excludeFrom() const
0290 {
0291     return findItem("excludeFrom")->property().toInt();
0292 }
0293 
0294 void FontsAASettings::setExcludeFrom(int excludeFrom)
0295 {
0296     findItem("excludeFrom")->setProperty(excludeFrom);
0297 }
0298 
0299 int FontsAASettings::excludeTo() const
0300 {
0301     return findItem("excludeTo")->property().toInt();
0302 }
0303 
0304 void FontsAASettings::setExcludeTo(int excludeTo)
0305 {
0306     findItem("excludeTo")->setProperty(excludeTo);
0307 }
0308 
0309 bool FontsAASettings::antiAliasing() const
0310 {
0311     return findItem("antiAliasing")->property().toBool();
0312 }
0313 
0314 void FontsAASettings::setAntiAliasing(bool enabled)
0315 {
0316     if (antiAliasing() == enabled) {
0317         return;
0318     }
0319 
0320     findItem("antiAliasing")->setProperty(enabled);
0321     if (!enabled) {
0322         setSubPixel(KXftConfig::SubPixel::None);
0323     } else if (subPixel() == KXftConfig::SubPixel::None) {
0324         setSubPixel(defaultSubPixel());
0325     }
0326 }
0327 
0328 int FontsAASettings::dpi() const
0329 {
0330     return KWindowSystem::isPlatformWayland() ? forceFontDPIWayland() : forceFontDPI();
0331 }
0332 
0333 void FontsAASettings::setDpi(int newDPI)
0334 {
0335     if (dpi() == newDPI) {
0336         return;
0337     }
0338 
0339     if (KWindowSystem::isPlatformWayland()) {
0340         setForceFontDPIWayland(newDPI);
0341     } else {
0342         setForceFontDPI(newDPI);
0343     }
0344     Q_EMIT dpiChanged();
0345 }
0346 
0347 KXftConfig::SubPixel::Type FontsAASettings::subPixel() const
0348 {
0349     return findItem("subPixel")->property().value<KXftConfig::SubPixel::Type>();
0350 }
0351 
0352 void FontsAASettings::setSubPixel(KXftConfig::SubPixel::Type type)
0353 {
0354     if (subPixel() == type) {
0355         return;
0356     }
0357 
0358     findItem("subPixel")->setProperty(type);
0359 }
0360 
0361 KXftConfig::Hint::Style FontsAASettings::hinting() const
0362 {
0363     return findItem("hinting")->property().value<KXftConfig::Hint::Style>();
0364 }
0365 
0366 bool FontsAASettings::isAaImmutable() const
0367 {
0368     return m_fontAASettingsStore->isImmutable();
0369 }
0370 
0371 bool FontsAASettings::excludeStateProxy() const
0372 {
0373     return false;
0374 }
0375 
0376 void FontsAASettings::setHinting(KXftConfig::Hint::Style hinting)
0377 {
0378     findItem("hinting")->setProperty(hinting);
0379 }
0380 
0381 bool FontsAASettings::usrSave()
0382 {
0383     m_fontAASettingsStore->save();
0384     return FontsAASettingsBase::usrSave();
0385 }
0386 
0387 #include "fontsaasettings.moc"