diff --git a/kcms/fonts/fonts.h b/kcms/fonts/fonts.h --- a/kcms/fonts/fonts.h +++ b/kcms/fonts/fonts.h @@ -46,8 +46,25 @@ Q_PROPERTY(bool exclude READ exclude WRITE setExclude NOTIFY excludeChanged) Q_PROPERTY(int excludeTo READ excludeTo WRITE setExcludeTo NOTIFY excludeToChanged) Q_PROPERTY(int excludeFrom READ excludeFrom WRITE setExcludeFrom NOTIFY excludeFromChanged) - Q_PROPERTY(int antiAliasing READ antiAliasing WRITE setAntiAliasing NOTIFY aliasingChanged) + Q_PROPERTY(bool antiAliasing READ antiAliasing WRITE setAntiAliasing NOTIFY aliasingChanged) Q_PROPERTY(int dpi READ dpi WRITE setDpi NOTIFY dpiChanged) + + struct State + { + bool exclude; + int excludeFrom; + int excludeTo; + int antiAliasing; + bool antiAliasingHasLocalConfig; + bool subPixelHasLocalConfig; + bool hintingHasLocalConfig; + int dpi; + int subPixel; + int hinting; + + bool operator==(const State& other) const; + bool operator!=(const State& other) const; + }; public: enum AASetting { AAEnabled, AASystem, AADisabled }; @@ -70,16 +87,22 @@ void setExcludeFrom(const int &excludeTo); int excludeFrom() const; - void setAntiAliasing(const int& antiAliasing); - int antiAliasing() const; + void setAntiAliasing(bool antiAliasing); + bool antiAliasing() const; + + bool antiAliasingNeedsSave() const; + bool subPixelNeedsSave() const; + bool hintingNeedsSave() const; void setDpi(const int &dpi); int dpi() const; int subPixelCurrentIndex(); void setSubPixelCurrentIndex(int idx); + void setSubPixel(int idx); int hintingCurrentIndex(); void setHintingCurrentIndex(int idx); + void setHinting(int idx); bool needsSave() const; @@ -97,21 +120,10 @@ #if defined(HAVE_FONTCONFIG) && HAVE_X11 private: - int m_excludeTo; - int m_excludeToOriginal; - int m_excludeFrom; - int m_excludeFromOriginal; - int m_antiAliasing; - int m_antiAliasingOriginal; - int m_dpi; - int m_dpiOriginal; - int m_subPixelCurrentIndex = 0; - int m_subPixelCurrentIndexOriginal; - int m_hintingCurrentIndex = 0; - int m_hintingCurrentIndexOriginal; + State m_state; + State m_originalState; QStandardItemModel *m_subPixelOptionsModel; QStandardItemModel *m_hintingOptionsModel; - bool m_exclude = false; #endif }; diff --git a/kcms/fonts/fonts.cpp b/kcms/fonts/fonts.cpp --- a/kcms/fonts/fonts.cpp +++ b/kcms/fonts/fonts.cpp @@ -112,12 +112,14 @@ , m_subPixelOptionsModel(new QStandardItemModel(this)) , m_hintingOptionsModel(new QStandardItemModel(this)) { - for (int t = KXftConfig::SubPixel::NotSet; t <= KXftConfig::SubPixel::Vbgr; ++t) { + m_state.subPixel = KXftConfig::SubPixel::None; + for (int t = KXftConfig::SubPixel::None; t <= KXftConfig::SubPixel::Vbgr; ++t) { QStandardItem *item = new QStandardItem(KXftConfig::description((KXftConfig::SubPixel::Type)t)); m_subPixelOptionsModel->appendRow(item); } - for (int s = KXftConfig::Hint::NotSet; s <= KXftConfig::Hint::Full; ++s) { + m_state.hinting = KXftConfig::Hint::None; + for (int s = KXftConfig::Hint::None; s <= KXftConfig::Hint::Full; ++s) { QStandardItem * item = new QStandardItem(KXftConfig::description((KXftConfig::Hint::Style)s)); m_hintingOptionsModel->appendRow(item); } @@ -129,39 +131,38 @@ KXftConfig xft; if (xft.getExcludeRange(from, to)) { - m_excludeFrom = from; - m_excludeTo = to; + m_state.excludeFrom = from; + m_state.excludeTo = to; setExclude(true); } else { - m_excludeFrom = 8; - m_excludeTo = 15; + m_state.excludeFrom = 8; + m_state.excludeTo = 15; setExclude(false); } - m_excludeFromOriginal = m_excludeFrom; - m_excludeToOriginal = m_excludeTo; + m_originalState.exclude = m_state.exclude; + m_originalState.excludeFrom = m_state.excludeFrom; + m_originalState.excludeTo = m_state.excludeTo; excludeToChanged(); excludeFromChanged(); KXftConfig::SubPixel::Type spType; - xft.getSubPixelType(spType); + if (!xft.getSubPixelType(spType) || KXftConfig::SubPixel::NotSet == spType) { + spType = KXftConfig::SubPixel::Rgb; + } - setSubPixelCurrentIndex(spType); - m_subPixelCurrentIndexOriginal = spType; + setSubPixel(spType); + m_originalState.subPixel = spType; + m_state.subPixelHasLocalConfig = xft.subPixelTypeHasLocalConfig(); KXftConfig::Hint::Style hStyle; if (!xft.getHintStyle(hStyle) || KXftConfig::Hint::NotSet == hStyle) { - KConfig kglobals("kdeglobals", KConfig::NoGlobals); - - hStyle = KXftConfig::Hint::NotSet; - xft.setHintStyle(hStyle); - KConfigGroup(&kglobals, "General").writeEntry("XftHintStyle", KXftConfig::toStr(hStyle)); - kglobals.sync(); - runRdb(KRdbExportXftSettings | KRdbExportGtkTheme); + hStyle = KXftConfig::Hint::Slight; } - setHintingCurrentIndex(hStyle); - m_hintingCurrentIndexOriginal = hStyle; + setHinting(hStyle); + m_originalState.hinting = hStyle; + m_state.hintingHasLocalConfig = xft.hintStyleHasLocalConfig(); KConfig _cfgfonts("kcmfonts"); KConfigGroup cfgfonts(&_cfgfonts, "General"); @@ -174,24 +175,28 @@ } if (dpicfg <= 0) { - m_dpiOriginal = 0; + m_originalState.dpi = 0; } else { - m_dpiOriginal = dpicfg; + m_originalState.dpi = dpicfg; }; setDpi(dpicfg); KSharedConfig::Ptr config = KSharedConfig::openConfig("kdeglobals"); KConfigGroup cg(config, "General"); if (cfgfonts.readEntry("dontChangeAASettings", true)) { - setAntiAliasing(1); //AASystem + setAntiAliasing(true); //AASystem + m_state.antiAliasingHasLocalConfig = false; } else if (cg.readEntry("XftAntialias", true)) { - setAntiAliasing(0); //AAEnabled + setAntiAliasing(true); //AAEnabled + m_state.antiAliasingHasLocalConfig = xft.antiAliasingHasLocalConfig(); } else { - setAntiAliasing(2); //AADisabled + setAntiAliasing(false); //AADisabled + m_state.antiAliasingHasLocalConfig = xft.antiAliasingHasLocalConfig(); } - m_antiAliasingOriginal = m_antiAliasing; + m_originalState.antiAliasing = m_state.antiAliasing; + m_originalState.antiAliasingHasLocalConfig = m_state.antiAliasingHasLocalConfig; } bool FontAASettings::save(KXftConfig::AntiAliasing::State aaState) @@ -201,27 +206,35 @@ KConfigGroup grp(&kglobals, "General"); xft.setAntiAliasing(aaState); - if (m_exclude) { - xft.setExcludeRange(m_excludeFrom, m_excludeTo); + if (m_state.exclude) { + xft.setExcludeRange(m_state.excludeFrom, m_state.excludeTo); } else { xft.setExcludeRange(0, 0); } - KXftConfig::SubPixel::Type spType = (KXftConfig::SubPixel::Type)m_subPixelCurrentIndex; + KXftConfig::SubPixel::Type spType = (KXftConfig::SubPixel::Type)m_state.subPixel; - xft.setSubPixelType(spType); + if (subPixelNeedsSave()) { + xft.setSubPixelType(spType); + } else { + xft.setSubPixelType(KXftConfig::SubPixel::NotSet); + } grp.writeEntry("XftSubPixel", KXftConfig::toStr(spType)); if (aaState == KXftConfig::AntiAliasing::NotSet) { grp.revertToDefault("XftAntialias"); } else { grp.writeEntry("XftAntialias", aaState == KXftConfig::AntiAliasing::Enabled); } bool mod = false; - KXftConfig::Hint::Style hStyle = (KXftConfig::Hint::Style)m_hintingCurrentIndex; - - xft.setHintStyle(hStyle); + KXftConfig::Hint::Style hStyle = (KXftConfig::Hint::Style)m_state.hinting; + if (hintingNeedsSave()) { + xft.setHintStyle(hStyle); + } else { + xft.setHintStyle(KXftConfig::Hint::NotSet); + } + QString hs(KXftConfig::toStr(hStyle)); if (hs != grp.readEntry("XftHintStyle")) { @@ -244,17 +257,17 @@ KConfigGroup cfgfonts(&_cfgfonts, "General"); if (KWindowSystem::isPlatformWayland()) { - cfgfonts.writeEntry("forceFontDPIWayland", m_dpi); + cfgfonts.writeEntry("forceFontDPIWayland", m_state.dpi); } else { - cfgfonts.writeEntry("forceFontDPI", m_dpi); + cfgfonts.writeEntry("forceFontDPI", m_state.dpi); } cfgfonts.sync(); #if HAVE_X11 // if the setting is reset in the module, remove the dpi value, // otherwise don't explicitly remove it and leave any possible system-wide value - if (m_dpi == 0 && m_dpiOriginal != 0 && !KWindowSystem::isPlatformWayland()) { + if (m_state.dpi == 0 && m_originalState.dpi != 0 && !KWindowSystem::isPlatformWayland()) { QProcess proc; proc.setProcessChannelMode(QProcess::ForwardedChannels); proc.start("xrdb", QStringList() << "-quiet" << "-remove" << "-nocpp"); @@ -271,162 +284,185 @@ // Don't overwrite global settings unless explicitly asked for - e.g. the system // fontconfig setup may be much more complex than this module can provide. // TODO: With AASystem the changes already made by this module should be reverted somehow. -#if defined(HAVE_FONTCONFIG) && HAVE_X11 - if (mod || (m_antiAliasing != m_antiAliasingOriginal) || m_dpi != m_dpiOriginal) { +#if defined(HAVE_FONTCONFIG) && defined (HAVE_X11) + if (mod || (m_state.antiAliasing != m_originalState.antiAliasing) || m_state.dpi != m_originalState.dpi) { KMessageBox::information(nullptr, i18n( "

Some changes such as anti-aliasing or DPI will only affect newly started applications.

" ), i18n("Font Settings Changed"), "FontSettingsChanged"); - m_antiAliasingOriginal = m_antiAliasing; - m_dpiOriginal = m_dpi; + m_originalState.antiAliasing = m_state.antiAliasing; + m_originalState.dpi = m_state.dpi; } #else #if HAVE_X11 - if (m_dpi != m_dpiOriginal) { + if (m_state.dpi != m_originalState.dpi) { KMessageBox::information(0, i18n( "

Some changes such as DPI will only affect newly started applications.

" ), i18n("Font Settings Changed"), "FontSettingsChanged"); - m_dpiOriginal = m_dpi; + m_originalState.dpi = m_state.dpi; } #endif #endif - m_excludeToOriginal = m_excludeTo; - m_excludeFromOriginal = m_excludeFrom; + m_originalState.excludeTo = m_state.excludeTo; + m_originalState.excludeFrom = m_state.excludeFrom; - m_subPixelCurrentIndexOriginal = m_subPixelCurrentIndex; - m_hintingCurrentIndexOriginal = m_hintingCurrentIndex; + m_originalState.subPixel = m_state.subPixel; + m_originalState.hinting = m_state.hinting; return mod; } void FontAASettings::defaults() { setExcludeTo(15); setExcludeFrom(8); - setAntiAliasing(1); - m_antiAliasingOriginal = m_antiAliasing; + setAntiAliasing(true); + m_originalState.antiAliasing = m_state.antiAliasing; + m_state.antiAliasingHasLocalConfig = false; setDpi(0); - setSubPixelCurrentIndex(KXftConfig::SubPixel::NotSet); - setHintingCurrentIndex(KXftConfig::Hint::NotSet); + setSubPixel(KXftConfig::SubPixel::Rgb); + m_state.subPixelHasLocalConfig = false; + setHinting(KXftConfig::Hint::Slight); + m_state.hintingHasLocalConfig = false; } #endif void FontAASettings::setExclude(bool exclude) { - if (exclude == m_exclude) { + if (exclude == m_state.exclude) { return; } - m_exclude = exclude; + m_state.exclude = exclude; emit excludeChanged(); } bool FontAASettings::exclude() const { - return m_exclude; + return m_state.exclude; } void FontAASettings::setExcludeTo(const int &excludeTo) { - if (m_excludeTo == excludeTo) { + if (m_state.excludeTo == excludeTo) { return; } - m_excludeTo = excludeTo; + m_state.excludeTo = excludeTo; emit excludeToChanged(); } int FontAASettings::excludeTo() const { - return m_excludeTo; + return m_state.excludeTo; } void FontAASettings::setExcludeFrom(const int &excludeTo) { - if (m_excludeFrom == excludeTo) { + if (m_state.excludeFrom == excludeTo) { return; } - m_excludeFrom = excludeTo; + m_state.excludeFrom = excludeTo; emit excludeToChanged(); } int FontAASettings::excludeFrom() const { - return m_excludeFrom; + return m_state.excludeFrom; } -void FontAASettings::setAntiAliasing(const int &antiAliasing) +void FontAASettings::setAntiAliasing(bool antiAliasing) { - if (m_antiAliasing == antiAliasing) { + if (m_state.antiAliasing == antiAliasing) { return; } - m_antiAliasing = antiAliasing; + m_state.antiAliasing = antiAliasing; emit aliasingChanged(); } -int FontAASettings::antiAliasing() const +bool FontAASettings::antiAliasing() const { - return m_antiAliasing; + return m_state.antiAliasing; +} + +bool FontAASettings::antiAliasingNeedsSave() const +{ + return m_state.antiAliasingHasLocalConfig || (m_state.antiAliasing != m_originalState.antiAliasing); +} + +bool FontAASettings::subPixelNeedsSave() const +{ + return m_state.subPixelHasLocalConfig || (m_state.subPixel != m_originalState.subPixel); +} + +bool FontAASettings::hintingNeedsSave() const +{ + return m_state.hintingHasLocalConfig || (m_state.hinting != m_originalState.hinting); } void FontAASettings::setDpi(const int &dpi) { - if (m_dpi == dpi) { + if (m_state.dpi == dpi) { return; } - m_dpi = dpi; + m_state.dpi = dpi; emit dpiChanged(); } int FontAASettings::dpi() const { - return m_dpi; + return m_state.dpi; } -void FontAASettings::setSubPixelCurrentIndex(int idx) +void FontAASettings::setSubPixel(int idx) { - if (m_subPixelCurrentIndex == idx) { + if (m_state.subPixel == idx) { return; } - m_subPixelCurrentIndex = idx; + m_state.subPixel = idx; emit subPixelCurrentIndexChanged(); } +void FontAASettings::setSubPixelCurrentIndex(int idx) +{ + setSubPixel(KXftConfig::SubPixel::None + idx); +} + int FontAASettings::subPixelCurrentIndex() { - return m_subPixelCurrentIndex; + return m_state.subPixel - KXftConfig::SubPixel::None; } -void FontAASettings::setHintingCurrentIndex(int idx) +void FontAASettings::setHinting(int idx) { - if (m_hintingCurrentIndex == idx) { + if (m_state.hinting == idx) { return; } - m_hintingCurrentIndex = idx; + m_state.hinting = idx; emit hintingCurrentIndexChanged(); } +void FontAASettings::setHintingCurrentIndex(int idx) +{ + setHinting(KXftConfig::Hint::None + idx); +} + int FontAASettings::hintingCurrentIndex() { - return m_hintingCurrentIndex; + return m_state.hinting - KXftConfig::Hint::None; } bool FontAASettings::needsSave() const { - return m_excludeTo != m_excludeToOriginal - || m_excludeFrom != m_excludeFromOriginal - || m_antiAliasing != m_antiAliasingOriginal - || m_dpi != m_dpiOriginal - || m_subPixelCurrentIndex != m_subPixelCurrentIndexOriginal - || m_hintingCurrentIndex != m_hintingCurrentIndexOriginal; + return m_state != m_originalState; } @@ -450,6 +486,8 @@ connect(m_fontAASettings, &FontAASettings::subPixelCurrentIndexChanged, this, updateState); connect(m_fontAASettings, &FontAASettings::hintingCurrentIndexChanged, this, updateState); + connect(m_fontAASettings, &FontAASettings::excludeChanged, this, updateState); + connect(m_fontAASettings, &FontAASettings::excludeFromChanged, this, updateState); connect(m_fontAASettings, &FontAASettings::excludeToChanged, this, updateState); connect(m_fontAASettings, &FontAASettings::antiAliasingChanged, this, updateState); connect(m_fontAASettings, &FontAASettings::aliasingChanged, this, updateState); @@ -539,7 +577,10 @@ KConfig _cfgfonts("kcmfonts"); KConfigGroup cfgfonts(&_cfgfonts, "General"); - FontAASettings::AASetting aaSetting = (FontAASettings::AASetting)m_fontAASettings->antiAliasing(); + FontAASettings::AASetting aaSetting = FontAASettings::AASystem; + if (m_fontAASettings->antiAliasingNeedsSave()) { + aaSetting = m_fontAASettings->antiAliasing() ? FontAASettings::AAEnabled : FontAASettings::AADisabled; + } cfgfonts.writeEntry("dontChangeAASettings", aaSetting == FontAASettings::AASystem); if (aaSetting == FontAASettings::AAEnabled) { @@ -707,5 +748,29 @@ return font; } +bool FontAASettings::State::operator==(const State& other) const +{ + if ( + exclude != other.exclude + || antiAliasing != other.antiAliasing + || dpi != other.dpi + || subPixel != other.subPixel + || hinting != other.hinting + ) { + return false; + } + + if (exclude && (excludeFrom != other.excludeFrom || excludeTo != other.excludeTo)) { + return false; + } + + return true; +} + +bool FontAASettings::State::operator!=(const State& other) const +{ + return !(*this == other); +} + #include "fonts.moc" diff --git a/kcms/fonts/kxftconfig.h b/kcms/fonts/kxftconfig.h --- a/kcms/fonts/kxftconfig.h +++ b/kcms/fonts/kxftconfig.h @@ -26,6 +26,7 @@ #include #include +#include class KXftConfig { @@ -155,6 +156,9 @@ void setHintStyle(Hint::Style style); void setAntiAliasing(AntiAliasing::State state); AntiAliasing::State getAntiAliasing() const; + bool antiAliasingHasLocalConfig() const; + bool subPixelTypeHasLocalConfig() const; + bool hintStyleHasLocalConfig() const; bool changed() { return m_madeChanges; @@ -167,22 +171,29 @@ private: + bool parseConfigFile(const QString& filename); void readContents(); void applySubPixelType(); void applyHintStyle(); void applyAntiAliasing(); void setHinting(bool set); void applyHinting(); void applyExcludeRange(bool pixel); + QString getConfigFile(); private: + + QStringList m_globalFiles; SubPixel m_subPixel; Exclude m_excludeRange, m_excludePixelRange; Hint m_hint; Hinting m_hinting; AntiAliasing m_antiAliasing; + bool m_antiAliasingHasLocalConfig; + bool m_subPixelHasLocalConfig; + bool m_hintHasLocalConfig; QDomDocument m_doc; QString m_file; bool m_madeChanges; diff --git a/kcms/fonts/kxftconfig.cpp b/kcms/fonts/kxftconfig.cpp --- a/kcms/fonts/kxftconfig.cpp +++ b/kcms/fonts/kxftconfig.cpp @@ -107,49 +107,6 @@ return QFileInfo(item).lastModified(); } -// -// Obtain location of config file to use. -QString getConfigFile() -{ - FcStrList *list = FcConfigGetConfigFiles(FcConfigGetCurrent()); - QStringList files; - FcChar8 *file; - QString home(dirSyntax(QDir::homePath())); - - while ((file = FcStrListNext(list))) { - QString f((const char *)file); - - if (fExists(f) && 0 == f.indexOf(home)) { - files.append(f); - } - } - FcStrListDone(list); - - // - // Go through list of files, looking for the preferred one... - if (!files.isEmpty()) { - QStringList::const_iterator it(files.begin()), - end(files.end()); - - for (; it != end; ++it) - if (-1 != (*it).indexOf(QRegExp("/\\.?fonts\\.conf$"))) { - return *it; - } - return files.front(); // Just return the 1st one... - } else { // Hmmm... no known files? - if (FcGetVersion() >= 21000) { - QString targetPath(KGlobal::dirs()->localxdgconfdir() + "fontconfig"); - QDir target(targetPath); - if (!target.exists()) { - target.mkpath(targetPath); - } - return targetPath + "/fonts.conf"; - } else { - return home + "/.fonts.conf"; - } - } -} - static QString getEntry(QDomElement element, const char *type, unsigned int numAttributes, ...) { if (numAttributes == element.attributes().length()) { @@ -228,6 +185,55 @@ { } +// +// Obtain location of config file to use. +QString KXftConfig::getConfigFile() +{ + FcStrList *list = FcConfigGetConfigFiles(FcConfigGetCurrent()); + QStringList localFiles; + FcChar8 *file; + QString home(dirSyntax(QDir::homePath())); + + + m_globalFiles.clear(); + + while ((file = FcStrListNext(list))) { + + QString f((const char *)file); + + if (fExists(f) && 0 == f.indexOf(home)) { + localFiles.append(f); + } else { + m_globalFiles.append(f); + } + } + FcStrListDone(list); + + // + // Go through list of localFiles, looking for the preferred one... + if (localFiles.count()) { + QStringList::const_iterator it(localFiles.begin()), + end(localFiles.end()); + + for (; it != end; ++it) + if (-1 != (*it).indexOf(QRegExp("/\\.?fonts\\.conf$"))) { + return *it; + } + return localFiles.front(); // Just return the 1st one... + } else { // Hmmm... no known localFiles? + if (FcGetVersion() >= 21000) { + QString targetPath(KGlobal::dirs()->localxdgconfdir() + "fontconfig"); + QDir target(targetPath); + if (!target.exists()) { + target.mkpath(targetPath); + } + return targetPath + "/fonts.conf"; + } else { + return home + "/.fonts.conf"; + } + } +} + bool KXftConfig::reset() { bool ok = false; @@ -239,45 +245,66 @@ m_excludePixelRange.reset(); m_subPixel.reset(); m_antiAliasing.reset(); - - QFile f(m_file); - - if (f.open(QIODevice::ReadOnly)) { - m_time = getTimeStamp(m_file); - ok = true; - m_doc.clear(); - - if (m_doc.setContent(&f)) { - readContents(); - } - f.close(); + m_antiAliasingHasLocalConfig = false; + m_subPixelHasLocalConfig = false; + m_hintHasLocalConfig = false; + + QStringList::const_iterator it(m_globalFiles.begin()), + end(m_globalFiles.end()); + for (; it != end; ++it) { + ok |= parseConfigFile(*it); + } + + AntiAliasing globalAntialiasing; + globalAntialiasing.state = m_antiAliasing.state; + SubPixel globalSubPixel; + globalSubPixel.type = m_subPixel.type; + Hint globalHint; + globalHint.style = m_hint.style; + Exclude globalExcludeRange; + globalExcludeRange.from = m_excludeRange.from; + globalExcludeRange.to = m_excludePixelRange.to; + Exclude globalExcludePixelRange; + globalExcludePixelRange.from = m_excludePixelRange.from; + globalExcludePixelRange.to = m_excludePixelRange.to; + Hinting globalHinting; + globalHinting.set = m_hinting.set; + + m_antiAliasing.reset(); + m_subPixel.reset(); + m_hint.reset(); + m_hinting.reset(); + m_excludeRange.reset(); + m_excludePixelRange.reset(); + + ok |= parseConfigFile(m_file); + + if (m_antiAliasing.node.isNull()) { + m_antiAliasing = globalAntialiasing; } else { - ok = !fExists(m_file) && dWritable(getDir(m_file)); + m_antiAliasingHasLocalConfig = true; } - - if (m_doc.documentElement().isNull()) { - m_doc.appendChild(m_doc.createElement("fontconfig")); + + if (m_subPixel.node.isNull()) { + m_subPixel = globalSubPixel; + } else { + m_subPixelHasLocalConfig = true; } - - if (ok) { - // - // Check exclude range values - i.e. size and pixel size... - // If "size" range is set, ensure "pixelsize" matches... - if (!equal(0, m_excludeRange.from) || !equal(0, m_excludeRange.to)) { - double pFrom = (double)point2Pixel(m_excludeRange.from), - pTo = (double)point2Pixel(m_excludeRange.to); - - if (!equal(pFrom, m_excludePixelRange.from) || !equal(pTo, m_excludePixelRange.to)) { - m_excludePixelRange.from = pFrom; - m_excludePixelRange.to = pTo; - m_madeChanges = true; - } - } else if (!equal(0, m_excludePixelRange.from) || !equal(0, m_excludePixelRange.to)) { - // "pixelsize" set, but not "size" !!! - m_excludeRange.from = (int)pixel2Point(m_excludePixelRange.from); - m_excludeRange.to = (int)pixel2Point(m_excludePixelRange.to); - m_madeChanges = true; - } + + if (m_hint.node.isNull()) { + m_hint = globalHint; + } else { + m_hintHasLocalConfig = true; + } + + if (m_hinting.node.isNull()) { + m_hinting = globalHinting; + } + if (m_excludeRange.node.isNull()) { + m_excludeRange = globalExcludeRange; + } + if (m_excludePixelRange.node.isNull()) { + m_excludePixelRange = globalExcludePixelRange; } return ok; @@ -367,6 +394,11 @@ return ok; } +bool KXftConfig::subPixelTypeHasLocalConfig() const +{ + return m_subPixelHasLocalConfig; +} + bool KXftConfig::getSubPixelType(SubPixel::Type &type) { type = m_subPixel.type; @@ -381,6 +413,11 @@ } } +bool KXftConfig::hintStyleHasLocalConfig() const +{ + return m_hintHasLocalConfig; +} + bool KXftConfig::getHintStyle(Hint::Style &style) { if (Hint::NotSet != m_hint.style && !m_hint.toBeRemoved) { @@ -508,48 +545,122 @@ } } +bool KXftConfig::parseConfigFile(const QString& filename) +{ + bool ok = false; + + QFile f(filename); + + if (f.open(QIODevice::ReadOnly)) { + m_time = getTimeStamp(filename); + ok = true; + m_doc.clear(); + + if (m_doc.setContent(&f)) { + readContents(); + } + f.close(); + } else { + ok = !fExists(filename) && dWritable(getDir(filename)); + } + + if (m_doc.documentElement().isNull()) { + m_doc.appendChild(m_doc.createElement("fontconfig")); + } + + if (ok) { + // + // Check exclude range values - i.e. size and pixel size... + // If "size" range is set, ensure "pixelsize" matches... + if (!equal(0, m_excludeRange.from) || !equal(0, m_excludeRange.to)) { + double pFrom = (double)point2Pixel(m_excludeRange.from), + pTo = (double)point2Pixel(m_excludeRange.to); + + if (!equal(pFrom, m_excludePixelRange.from) || !equal(pTo, m_excludePixelRange.to)) { + m_excludePixelRange.from = pFrom; + m_excludePixelRange.to = pTo; + m_madeChanges = true; + } + } else if (!equal(0, m_excludePixelRange.from) || !equal(0, m_excludePixelRange.to)) { + // "pixelsize" set, but not "size" !!! + m_excludeRange.from = (int)pixel2Point(m_excludePixelRange.from); + m_excludeRange.to = (int)pixel2Point(m_excludePixelRange.to); + m_madeChanges = true; + } + } + + return ok; +} + void KXftConfig::readContents() { QDomNode n = m_doc.documentElement().firstChild(); while (!n.isNull()) { QDomElement e = n.toElement(); - + if (!e.isNull()) { if ("match" == e.tagName()) { QString str; + + int childNodesCount = e.childNodes().count(); + QDomNode en = e.firstChild(); + while (!en.isNull()) { + if (en.isComment()) { + childNodesCount--; + } + en = en.nextSibling(); + } - switch (e.childNodes().count()) { + switch (childNodesCount) { case 1: - if ("font" == e.attribute("target")) { - QDomElement ene = e.firstChild().toElement(); - - if (!ene.isNull() && "edit" == ene.tagName()) { - if (!(str = getEntry(ene, "const", 2, "name", "rgba", "mode", - "assign")).isNull()) { - m_subPixel.node = n; - m_subPixel.type = strToType(str.toLatin1()); - } else if (!(str = getEntry(ene, "const", 2, "name", "hintstyle", "mode", - "assign")).isNull()) { - m_hint.node = n; - m_hint.style = strToStyle(str.toLatin1()); - } else if (!(str = getEntry(ene, "bool", 2, "name", "hinting", "mode", - "assign")).isNull()) { - m_hinting.node = n; - m_hinting.set = str.toLower() != "false"; - } else if (!(str = getEntry(ene, "bool", 2, "name", "antialias", "mode", - "assign")).isNull()) { - m_antiAliasing.node = n; - m_antiAliasing.state = str.toLower() != "false" ? - AntiAliasing::Enabled : AntiAliasing::Disabled; + if ("font" == e.attribute("target") || "pattern" == e.attribute("target")) { + QDomNode en = e.firstChild(); + while (!en.isNull()) { + QDomElement ene = en.toElement(); + + while (ene.isComment()) { + ene = ene.nextSiblingElement(); + } + + if (!ene.isNull() && "edit" == ene.tagName()) { + if (!(str = getEntry(ene, "const", 2, "name", "rgba", "mode", + "assign")).isNull() + || (m_subPixel.type == SubPixel::NotSet && !(str = getEntry(ene, "const", 2, "name", "rgba", "mode", + "append")).isNull())) { + m_subPixel.node = n; + m_subPixel.type = strToType(str.toLatin1()); + } else if (!(str = getEntry(ene, "const", 2, "name", "hintstyle", "mode", + "assign")).isNull() + || (m_hint.style == Hint::NotSet && !(str = getEntry(ene, "const", 2, "name", "hintstyle", "mode", + "append")).isNull())) { + m_hint.node = n; + m_hint.style = strToStyle(str.toLatin1()); + } else if (!(str = getEntry(ene, "bool", 2, "name", "hinting", "mode", + "assign")).isNull()) { + m_hinting.node = n; + m_hinting.set = str.toLower() != "false"; + } else if (!(str = getEntry(ene, "bool", 2, "name", "antialias", "mode", + "assign")).isNull() + || (m_antiAliasing.state == AntiAliasing::NotSet && !(str = getEntry(ene, "bool", 2, "name", "antialias", "mode", + "append")).isNull())) { + m_antiAliasing.node = n; + m_antiAliasing.state = str.toLower() != "false" ? + AntiAliasing::Enabled : AntiAliasing::Disabled; + } } + + en = en.nextSibling(); } } break; case 3: // CPD: Is target "font" or "pattern" ???? if ("font" == e.attribute("target")) { bool foundFalse = false; QDomNode en = e.firstChild(); + while (en.isComment()) { + en = en.nextSibling(); + } QString family; double from = -1.0, to = -1.0, @@ -765,6 +876,11 @@ } } +bool KXftConfig::antiAliasingHasLocalConfig() const +{ + return m_antiAliasingHasLocalConfig; +} + KXftConfig::AntiAliasing::State KXftConfig::getAntiAliasing() const { return m_antiAliasing.state; diff --git a/kcms/fonts/package/contents/ui/main.qml b/kcms/fonts/package/contents/ui/main.qml --- a/kcms/fonts/package/contents/ui/main.qml +++ b/kcms/fonts/package/contents/ui/main.qml @@ -31,7 +31,7 @@ Kirigami.FormLayout { id: formLayout - readonly property int maxImplicitWidth: Math.max(adjustAllFontsButton.implicitWidth, Math.max(antiAliasingComboBox.implicitWidth, Math.max(excludeField.implicitWidth, Math.max(subPixelCombo.implicitWidth, hintingCombo.implicitWidth)))) + readonly property int maxImplicitWidth: Math.max(adjustAllFontsButton.implicitWidth, excludeField.implicitWidth, subPixelCombo.implicitWidth, hintingCombo.implicitWidth) QtControls.Button { id: adjustAllFontsButton @@ -78,34 +78,28 @@ Kirigami.FormData.isSection: true } - QtControls.ComboBox { - id: antiAliasingComboBox - Layout.preferredWidth: formLayout.maxImplicitWidth - Kirigami.FormData.label: i18nc("Used as a noun, and precedes a combobox full of options", "Anti-aliasing:") - - model: [i18n("Enabled"), i18n("Vendor default"), i18n("Disabled")] - - currentIndex: kcm.fontAASettings.antiAliasing - onCurrentIndexChanged: kcm.fontAASettings.antiAliasing = antiAliasingComboBox.currentIndex + QtControls.CheckBox { + id: antiAliasingCheckBox + checked: kcm.fontAASettings.antiAliasing + onCheckedChanged: kcm.fontAASettings.antiAliasing = checked + Kirigami.FormData.label: i18n("Anti-Aliasing:") + text: i18n("Enable") + Layout.fillWidth: true } QtControls.CheckBox { id: excludeCheckBox checked: kcm.fontAASettings.exclude onCheckedChanged: kcm.fontAASettings.exclude = checked; text: i18n("Exclude range from anti-aliasing") Layout.fillWidth: true - enabled: antiAliasingComboBox.currentIndex == 0 + enabled: antiAliasingCheckBox.checked } RowLayout { id: excludeField - enabled: antiAliasingComboBox.currentIndex == 0 - - Item { - width: units.largeSpacing - } - + Layout.preferredWidth: formLayout.maxImplicitWidth + enabled: antiAliasingCheckBox.checked QtControls.SpinBox { id: excludeFromSpinBox stepSize: 1 @@ -143,7 +137,7 @@ onCurrentIndexChanged: kcm.fontAASettings.subPixelCurrentIndex = currentIndex; model: kcm.fontAASettings.subPixelOptionsModel textRole: "display" - enabled: antiAliasingComboBox.currentIndex == 0 + enabled: antiAliasingCheckBox.checked popup.height: popup.implicitHeight delegate: QtControls.ItemDelegate { id: subPixelDelegate @@ -180,7 +174,7 @@ onCurrentTextChanged: kcm.fontAASettings.hintingCurrentIndex = currentIndex; model: kcm.fontAASettings.hintingOptionsModel textRole: "display" - enabled: antiAliasingComboBox.currentIndex == 0 + enabled: antiAliasingCheckBox.checked popup.height: popup.implicitHeight delegate: QtControls.ItemDelegate { id: hintingDelegate diff --git a/kcms/fonts/previewimageprovider.cpp b/kcms/fonts/previewimageprovider.cpp --- a/kcms/fonts/previewimageprovider.cpp +++ b/kcms/fonts/previewimageprovider.cpp @@ -81,19 +81,22 @@ const auto sections = idpart.split(QLatin1Char('_')); if (sections.size() >= 2) { - subPixelIndex = sections[0].toInt(); - hintingIndex = sections[1].toInt(); + subPixelIndex = sections[0].toInt() + KXftConfig::SubPixel::None; + hintingIndex = sections[1].toInt() + KXftConfig::Hint::None; + } else { + return QImage(); } KXftConfig xft; - + KXftConfig::AntiAliasing::State oldAntialiasing = xft.getAntiAliasing(); - double oldStart,oldEnd; + double oldStart = 0; + double oldEnd = 0; xft.getExcludeRange(oldStart, oldEnd); - KXftConfig::SubPixel::Type oldSubPixelType; + KXftConfig::SubPixel::Type oldSubPixelType = KXftConfig::SubPixel::NotSet; xft.getSubPixelType(oldSubPixelType); - KXftConfig::Hint::Style oldHintStyle; + KXftConfig::Hint::Style oldHintStyle = KXftConfig::Hint::NotSet; xft.getHintStyle(oldHintStyle); diff --git a/kcms/krdb/krdb.cpp b/kcms/krdb/krdb.cpp --- a/kcms/krdb/krdb.cpp +++ b/kcms/krdb/krdb.cpp @@ -499,37 +499,28 @@ if (exportXftSettings) { - if (generalCfgGroup.hasKey("XftAntialias")) + contents += QLatin1String("Xft.antialias: "); + if(generalCfgGroup.readEntry("XftAntialias", true)) + contents += QLatin1String("1\n"); + else + contents += QLatin1String("0\n"); + + QString hintStyle = generalCfgGroup.readEntry("XftHintStyle", "hintslight"); + contents += QLatin1String("Xft.hinting: "); + if(hintStyle.isEmpty()) + contents += QLatin1String("-1\n"); + else { - contents += QLatin1String("Xft.antialias: "); - if(generalCfgGroup.readEntry("XftAntialias", true)) + if(hintStyle!=QLatin1String("hintnone")) contents += QLatin1String("1\n"); else contents += QLatin1String("0\n"); + contents += "Xft.hintstyle: " + hintStyle + '\n'; } - if (generalCfgGroup.hasKey("XftHintStyle")) - { - QString hintStyle = generalCfgGroup.readEntry("XftHintStyle", "hintmedium"); - contents += QLatin1String("Xft.hinting: "); - if(hintStyle.isEmpty()) - contents += QLatin1String("-1\n"); - else - { - if(hintStyle!=QLatin1String("hintnone")) - contents += QLatin1String("1\n"); - else - contents += QLatin1String("0\n"); - contents += "Xft.hintstyle: " + hintStyle + '\n'; - } - } - - if (generalCfgGroup.hasKey("XftSubPixel")) - { - QString subPixel = generalCfgGroup.readEntry("XftSubPixel"); - if(!subPixel.isEmpty()) - contents += "Xft.rgba: " + subPixel + '\n'; - } + QString subPixel = generalCfgGroup.readEntry("XftSubPixel", "rgb"); + if(!subPixel.isEmpty()) + contents += "Xft.rgba: " + subPixel + '\n'; KConfig _cfgfonts( QStringLiteral("kcmfonts") ); KConfigGroup cfgfonts(&_cfgfonts, "General");