fonts.cpp 18.9 KB
Newer Older
1
2
3
4
/*
    Copyright 1997 Mark Donohoe
    Copyright 1999 Lars Knoll
    Copyright 2000 Rik Hemsley
Marco Martin's avatar
Marco Martin committed
5
6
    Copyright 2015 Antonis Tsiapaliokas <antonis.tsiapaliokas@kde.org>
    Copyright 2017 Marco Martin <mart@kde.org>
Benjamin Port's avatar
Benjamin Port committed
7
    Copyright 2019 Benjamin Port <benjamin.port@enioka.com>
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

    Ported to kcontrol2 by Geert Jansen.

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/
26
27
28
29


#include "fonts.h"

Marco Martin's avatar
Marco Martin committed
30
31
32
33
34
35
#include <QQuickItem>
#include <QWindow>
#include <QQmlEngine>
#include <QQuickView>
#include <QDebug>
#include <QFontDialog>
36
#include <QApplication>
Marco Martin's avatar
Marco Martin committed
37
#include <QFontDatabase>
38
39
40

#include <KAcceleratorManager>
#include <KGlobalSettings>
41
#include <KConfigGroup>
Marco Martin's avatar
Marco Martin committed
42
43
#include <KConfig>
#include <KAboutData>
44
45
#include <KLocalizedString>
#include <KPluginFactory>
Marco Martin's avatar
Marco Martin committed
46
#include <KFontDialog>
47
#include <KWindowSystem>
Marco Martin's avatar
Marco Martin committed
48
#include <KMessageBox>
49
50

#include "../krdb/krdb.h"
Julian Wolff's avatar
Julian Wolff committed
51
#include "previewimageprovider.h"
52

Benjamin Port's avatar
Benjamin Port committed
53
54
#include "fontssettings.h"

55
/**** DLL Interface ****/
Marco Martin's avatar
Marco Martin committed
56
K_PLUGIN_FACTORY_WITH_JSON(KFontsFactory, "kcm_fonts.json", registerPlugin<KFonts>();)
57

Marco Martin's avatar
Marco Martin committed
58
59
60
61
//from KFontRequester
// Determine if the font with given properties is available on the system,
// otherwise find and return the best fitting combination.
static QFont nearestExistingFont(const QFont &font)
62
{
Marco Martin's avatar
Marco Martin committed
63
64
    QFontDatabase dbase;

Yuri Chornoivan's avatar
Yuri Chornoivan committed
65
    // Initialize font data according to given font object.
Marco Martin's avatar
Marco Martin committed
66
67
68
69
70
71
72
73
74
75
76
77
    QString family = font.family();
    QString style = dbase.styleString(font);
    qreal size = font.pointSizeF();

    // Check if the family exists.
    const QStringList families = dbase.families();
    if (!families.contains(family)) {
        // Chose another family.
        family = QFontInfo(font).family(); // the nearest match
        if (!families.contains(family)) {
            family = families.count() ? families.at(0) : QStringLiteral("fixed");
        }
78
79
    }

Marco Martin's avatar
Marco Martin committed
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
    // Check if the family has the requested style.
    // Easiest by piping it through font selection in the database.
    QString retStyle = dbase.styleString(dbase.font(family, style, 10));
    style = retStyle;

    // Check if the family has the requested size.
    // Only for bitmap fonts.
    if (!dbase.isSmoothlyScalable(family, style)) {
        QList<int> sizes = dbase.smoothSizes(family, style);
        if (!sizes.contains(size)) {
            // Find nearest available size.
            int mindiff = 1000;
            int refsize = size;
            Q_FOREACH (int lsize, sizes) {
                int diff = qAbs(refsize - lsize);
                if (mindiff > diff) {
                    mindiff = diff;
                    size = lsize;
                }
            }
100
101
        }
    }
102

Marco Martin's avatar
Marco Martin committed
103
104
105
106
107
108
    // Select the font with confirmed properties.
    QFont result = dbase.font(family, style, int(size));
    if (dbase.isSmoothlyScalable(family, style) && result.pointSize() == floor(size)) {
        result.setPointSizeF(size);
    }
    return result;
109
110
111
}

/**** FontAASettings ****/
112
#if defined(HAVE_FONTCONFIG) && HAVE_X11
Marco Martin's avatar
Marco Martin committed
113
114
FontAASettings::FontAASettings(QObject *parent)
    : QObject(parent)
115
116
    , m_state()
    , m_originalState()
Marco Martin's avatar
Marco Martin committed
117
118
119
    , m_subPixelOptionsModel(new QStandardItemModel(this))
    , m_hintingOptionsModel(new QStandardItemModel(this))
{
120
121
    m_state.subPixel = KXftConfig::SubPixel::None;
    for (int t = KXftConfig::SubPixel::None; t <= KXftConfig::SubPixel::Vbgr; ++t) {
Marco Martin's avatar
Marco Martin committed
122
123
        QStandardItem *item = new QStandardItem(KXftConfig::description((KXftConfig::SubPixel::Type)t));
        m_subPixelOptionsModel->appendRow(item);
124
125
    }

126
127
    m_state.hinting = KXftConfig::Hint::None;
    for (int s = KXftConfig::Hint::None; s <= KXftConfig::Hint::Full; ++s) {
Marco Martin's avatar
Marco Martin committed
128
129
        QStandardItem * item = new QStandardItem(KXftConfig::description((KXftConfig::Hint::Style)s));
        m_hintingOptionsModel->appendRow(item);
130
    }
131
132
}

Marco Martin's avatar
Marco Martin committed
133
void FontAASettings::load()
134
{
135
136
137
138
    double     from, to;
    KXftConfig xft;

    if (xft.getExcludeRange(from, to)) {
139
140
        m_state.excludeFrom = from;
        m_state.excludeTo = to;
Marco Martin's avatar
Marco Martin committed
141
        setExclude(true);
142
    } else {
143
144
        m_state.excludeFrom = 8;
        m_state.excludeTo = 15;
Marco Martin's avatar
Marco Martin committed
145
        setExclude(false);
146
    }
147
148
149
    m_originalState.exclude = m_state.exclude;
    m_originalState.excludeFrom = m_state.excludeFrom;
    m_originalState.excludeTo = m_state.excludeTo;
Marco Martin's avatar
Marco Martin committed
150
151
    excludeToChanged();
    excludeFromChanged();
152

153
    KXftConfig::SubPixel::Type spType;
154
    if (!xft.getSubPixelType(spType) || KXftConfig::SubPixel::NotSet == spType) {
155
        spType = KXftConfig::SubPixel::Rgb;
156
    }
157

158
159
160
    setSubPixel(spType);
    m_originalState.subPixel = spType;
    m_state.subPixelHasLocalConfig = xft.subPixelTypeHasLocalConfig();
161

162
    KXftConfig::Hint::Style hStyle;
163

164
    if (!xft.getHintStyle(hStyle) || KXftConfig::Hint::NotSet == hStyle) {
165
        hStyle = KXftConfig::Hint::Slight;
166
    }
167

168
169
170
    setHinting(hStyle);
    m_originalState.hinting = hStyle;
    m_state.hintingHasLocalConfig = xft.hintStyleHasLocalConfig();
171

Marco Martin's avatar
Marco Martin committed
172
173
    KConfig _cfgfonts("kcmfonts");
    KConfigGroup cfgfonts(&_cfgfonts, "General");
174

Marco Martin's avatar
Marco Martin committed
175
176
177
178
179
180
181
182
    int dpicfg;
    if (KWindowSystem::isPlatformWayland()) {
        dpicfg = cfgfonts.readEntry("forceFontDPIWayland", 0);
    } else {
        dpicfg = cfgfonts.readEntry("forceFontDPI", 0);
    }

    if (dpicfg <= 0) {
183
        m_originalState.dpi = 0;
Marco Martin's avatar
Marco Martin committed
184
    } else {
185
        m_originalState.dpi = dpicfg;
Marco Martin's avatar
Marco Martin committed
186
187
188
189
190
191
192
193
    };

    setDpi(dpicfg);

    KSharedConfig::Ptr config = KSharedConfig::openConfig("kdeglobals");
    KConfigGroup cg(config, "General");

    if (cfgfonts.readEntry("dontChangeAASettings", true)) {
194
195
        setAntiAliasing(true); //AASystem
        m_state.antiAliasingHasLocalConfig = false;
Marco Martin's avatar
Marco Martin committed
196
    } else if (cg.readEntry("XftAntialias", true)) {
197
198
        setAntiAliasing(true); //AAEnabled
        m_state.antiAliasingHasLocalConfig = xft.antiAliasingHasLocalConfig();
Marco Martin's avatar
Marco Martin committed
199
    } else {
200
201
        setAntiAliasing(false); //AADisabled
        m_state.antiAliasingHasLocalConfig = xft.antiAliasingHasLocalConfig();
Marco Martin's avatar
Marco Martin committed
202
    }
203
204
    m_originalState.antiAliasing = m_state.antiAliasing;
    m_originalState.antiAliasingHasLocalConfig = m_state.antiAliasingHasLocalConfig;
205
206
}

207
bool FontAASettings::save(KXftConfig::AntiAliasing::State aaState)
208
{
209
    KXftConfig   xft;
210
211
212

    KSharedConfig::Ptr config = KSharedConfig::openConfig("kdeglobals");
    KConfigGroup grp(config, "General");
213

214
    xft.setAntiAliasing(aaState);
215
216
    if (m_state.exclude) {
        xft.setExcludeRange(m_state.excludeFrom, m_state.excludeTo);
217
218
219
    } else {
        xft.setExcludeRange(0, 0);
    }
220

221
    KXftConfig::SubPixel::Type spType = (KXftConfig::SubPixel::Type)m_state.subPixel;
222

223
224
225
226
227
    if (subPixelNeedsSave()) {
        xft.setSubPixelType(spType);
    } else {
        xft.setSubPixelType(KXftConfig::SubPixel::NotSet);
    }
Marco Martin's avatar
Marco Martin committed
228
229
    grp.writeEntry("XftSubPixel", KXftConfig::toStr(spType));
    if (aaState == KXftConfig::AntiAliasing::NotSet) {
230
231
232
233
        grp.revertToDefault("XftAntialias");
    } else {
        grp.writeEntry("XftAntialias", aaState == KXftConfig::AntiAliasing::Enabled);
    }
234

235
    bool mod = false;
236
    KXftConfig::Hint::Style hStyle = (KXftConfig::Hint::Style)m_state.hinting;
237

238
239
240
241
242
    if (hintingNeedsSave()) {
        xft.setHintStyle(hStyle);
    } else {
        xft.setHintStyle(KXftConfig::Hint::NotSet);
    }
243

244
    QString hs(KXftConfig::toStr(hStyle));
Marco Martin's avatar
Marco Martin committed
245

246
247
248
249
250
251
    if (hs != grp.readEntry("XftHintStyle")) {
        if (KXftConfig::Hint::NotSet == hStyle) {
            grp.revertToDefault("XftHintStyle");
        } else {
            grp.writeEntry("XftHintStyle", hs);
        }
252
    }
253
    mod = true;
254
    config->sync();
255

256
257
258
    if (!mod) {
        mod = xft.changed();
    }
259

260
    xft.apply();
261

Marco Martin's avatar
Marco Martin committed
262
263
264
265
    KConfig _cfgfonts("kcmfonts");
    KConfigGroup cfgfonts(&_cfgfonts, "General");

    if (KWindowSystem::isPlatformWayland()) {
266
        cfgfonts.writeEntry("forceFontDPIWayland", m_state.dpi);
Marco Martin's avatar
Marco Martin committed
267
    } else {
268
        cfgfonts.writeEntry("forceFontDPI", m_state.dpi);
Marco Martin's avatar
Marco Martin committed
269
270
271
272
273
274
275
    }

    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
276
    if (m_state.dpi == 0 && m_originalState.dpi != 0 && !KWindowSystem::isPlatformWayland()) {
Marco Martin's avatar
Marco Martin committed
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
        QProcess proc;
        proc.setProcessChannelMode(QProcess::ForwardedChannels);
        proc.start("xrdb", QStringList() << "-quiet" << "-remove" << "-nocpp");
        if (proc.waitForStarted()) {
            proc.write(QByteArray("Xft.dpi\n"));
            proc.closeWriteChannel();
            proc.waitForFinished();
        }
    }
#endif

    QApplication::processEvents();			// Process font change ourselves

    // 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.
293
294
295
296
#if defined(HAVE_FONTCONFIG) && defined (HAVE_X11)
    if (mod || (m_state.antiAliasing != m_originalState.antiAliasing) || m_state.dpi != m_originalState.dpi) {
        m_originalState.antiAliasing = m_state.antiAliasing;
        m_originalState.dpi = m_state.dpi;
297
        emit aliasingChangeApplied();
Marco Martin's avatar
Marco Martin committed
298
299
300
    }
#else
#if HAVE_X11
301
302
    if (m_state.dpi != m_originalState.dpi) {
        m_originalState.dpi = m_state.dpi;
Marco Martin's avatar
Marco Martin committed
303
304
305
306
    }
#endif
#endif

Fabian Vogt's avatar
Fabian Vogt committed
307
    m_originalState.exclude = m_state.exclude;
308
309
    m_originalState.excludeTo = m_state.excludeTo;
    m_originalState.excludeFrom = m_state.excludeFrom;
310

311
312
    m_originalState.subPixel = m_state.subPixel;
    m_originalState.hinting = m_state.hinting;
Marco Martin's avatar
Marco Martin committed
313

314
    return mod;
315
316
317
318
}

void FontAASettings::defaults()
{
Marco Martin's avatar
Marco Martin committed
319
320
    setExcludeTo(15);
    setExcludeFrom(8);
321
322
323
    setAntiAliasing(true);
    m_originalState.antiAliasing = m_state.antiAliasing;
    m_state.antiAliasingHasLocalConfig = false;
324
    setDpi(0);
325
    setSubPixel(KXftConfig::SubPixel::Rgb);
326
    m_state.subPixelHasLocalConfig = false;
327
    setHinting(KXftConfig::Hint::Slight);
328
    m_state.hintingHasLocalConfig = false;
329
330
}

Marco Martin's avatar
Marco Martin committed
331
332
333
#endif

void FontAASettings::setExclude(bool exclude)
334
{
335
    if (exclude == m_state.exclude) {
Marco Martin's avatar
Marco Martin committed
336
337
        return;
    }
338

339
    m_state.exclude = exclude;
Marco Martin's avatar
Marco Martin committed
340
341
    emit excludeChanged();
}
342

Marco Martin's avatar
Marco Martin committed
343
344
bool FontAASettings::exclude() const
{
345
    return m_state.exclude;
346
347
}

Marco Martin's avatar
Marco Martin committed
348
void FontAASettings::setExcludeTo(const int &excludeTo)
349
{
350
    if (m_state.excludeTo == excludeTo) {
Marco Martin's avatar
Marco Martin committed
351
352
        return;
    }
353

354
    m_state.excludeTo = excludeTo;
Marco Martin's avatar
Marco Martin committed
355
356
    emit excludeToChanged();
}
357

Marco Martin's avatar
Marco Martin committed
358
359
int FontAASettings::excludeTo() const
{
360
    return m_state.excludeTo;
361
362
}

Marco Martin's avatar
Marco Martin committed
363
void FontAASettings::setExcludeFrom(const int &excludeTo)
364
{
365
    if (m_state.excludeFrom == excludeTo) {
Marco Martin's avatar
Marco Martin committed
366
367
        return;
    }
368

369
    m_state.excludeFrom = excludeTo;
Marco Martin's avatar
Marco Martin committed
370
371
    emit excludeToChanged();
}
372

Marco Martin's avatar
Marco Martin committed
373
374
int FontAASettings::excludeFrom() const
{
375
    return m_state.excludeFrom;
376
}
377

378
void FontAASettings::setAntiAliasing(bool antiAliasing)
379
{
380
    if (m_state.antiAliasing == antiAliasing) {
Marco Martin's avatar
Marco Martin committed
381
382
        return;
    }
383

384
    m_state.antiAliasing = antiAliasing;
Marco Martin's avatar
Marco Martin committed
385
386
    emit aliasingChanged();
}
387

388
389
390
391
392
393
394
395
396
397
398
bool FontAASettings::antiAliasing() const
{
    return m_state.antiAliasing;
}

bool FontAASettings::antiAliasingNeedsSave() const
{
    return m_state.antiAliasingHasLocalConfig || (m_state.antiAliasing != m_originalState.antiAliasing);
}

bool FontAASettings::subPixelNeedsSave() const
Marco Martin's avatar
Marco Martin committed
399
{
400
401
402
403
404
405
    return m_state.subPixelHasLocalConfig || (m_state.subPixel != m_originalState.subPixel);
}

bool FontAASettings::hintingNeedsSave() const
{
    return m_state.hintingHasLocalConfig || (m_state.hinting != m_originalState.hinting);
406
407
}

Marco Martin's avatar
Marco Martin committed
408
void FontAASettings::setDpi(const int &dpi)
409
{
410
    if (m_state.dpi == dpi) {
Marco Martin's avatar
Marco Martin committed
411
        return;
412
    }
Marco Martin's avatar
Marco Martin committed
413

414
    m_state.dpi = dpi;
Marco Martin's avatar
Marco Martin committed
415
    emit dpiChanged();
416
417
}

Marco Martin's avatar
Marco Martin committed
418
int FontAASettings::dpi() const
419
{
420
    return m_state.dpi;
421
422
}

423
void FontAASettings::setSubPixel(int idx)
424
{
425
    if (m_state.subPixel == idx) {
Marco Martin's avatar
Marco Martin committed
426
427
428
        return;
    }

429
    m_state.subPixel = idx;
Marco Martin's avatar
Marco Martin committed
430
431
    emit subPixelCurrentIndexChanged();
}
432

433
434
435
436
437
void FontAASettings::setSubPixelCurrentIndex(int idx)
{
    setSubPixel(KXftConfig::SubPixel::None + idx);
}

Marco Martin's avatar
Marco Martin committed
438
439
int FontAASettings::subPixelCurrentIndex()
{
440
    return m_state.subPixel - KXftConfig::SubPixel::None;
Marco Martin's avatar
Marco Martin committed
441
442
}

443
void FontAASettings::setHinting(int idx)
Marco Martin's avatar
Marco Martin committed
444
{
445
    if (m_state.hinting == idx) {
Marco Martin's avatar
Marco Martin committed
446
        return;
447
    }
448

449
    m_state.hinting = idx;
Marco Martin's avatar
Marco Martin committed
450
    emit hintingCurrentIndexChanged();
451
452
}

453
454
455
456
457
void FontAASettings::setHintingCurrentIndex(int idx)
{
    setHinting(KXftConfig::Hint::None + idx);
}

Marco Martin's avatar
Marco Martin committed
458
459
int FontAASettings::hintingCurrentIndex()
{
460
    return m_state.hinting - KXftConfig::Hint::None;
Marco Martin's avatar
Marco Martin committed
461
}
462

Marco Martin's avatar
Marco Martin committed
463
bool FontAASettings::needsSave() const
464
{
465
    return m_state != m_originalState;
Marco Martin's avatar
Marco Martin committed
466
}
467

Benjamin Port's avatar
Benjamin Port committed
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
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);
}
491

Marco Martin's avatar
Marco Martin committed
492
/**** KFonts ****/
493

Marco Martin's avatar
Marco Martin committed
494
495
KFonts::KFonts(QObject *parent, const QVariantList &args)
    : KQuickAddons::ConfigModule(parent, args)
Benjamin Port's avatar
Benjamin Port committed
496
    , m_settings(new FontsSettings(this))
Marco Martin's avatar
Marco Martin committed
497
498
    , m_fontAASettings(new FontAASettings(this))
{
499
    KAboutData* about = new KAboutData("kcm_fonts", i18n("Fonts"),
Marco Martin's avatar
Marco Martin committed
500
501
502
503
                                       "0.1", QString(), KAboutLicense::LGPL);
    about->addAuthor(i18n("Antonis Tsiapaliokas"), QString(), "antonis.tsiapaliokas@kde.org");
    setAboutData(about);
    qmlRegisterType<QStandardItemModel>();
Benjamin Port's avatar
Benjamin Port committed
504
505
    qmlRegisterType<FontsSettings>();

506
    setButtons(Apply | Default | Help);
Marco Martin's avatar
Marco Martin committed
507
508
509
510

    auto updateState = [this]() {
        setNeedsSave(m_fontAASettings->needsSave());
    };
511

Benjamin Port's avatar
Benjamin Port committed
512
513
514
515
516
517
518
519
    connect(m_settings, &FontsSettings::configChanged, this, &KFonts::updateNeedsSave);
    connect(m_settings, &FontsSettings::fontChanged, this, &KFonts::updateNeedsSave);
    connect(m_settings, &FontsSettings::fixedChanged, this, &KFonts::updateNeedsSave);
    connect(m_settings, &FontsSettings::smallestReadableFont, this, &KFonts::updateNeedsSave);
    connect(m_settings, &FontsSettings::toolBarFont, this, &KFonts::updateNeedsSave);
    connect(m_settings, &FontsSettings::menuFont, this, &KFonts::updateNeedsSave);
    connect(m_settings, &FontsSettings::activeFont, this, &KFonts::updateNeedsSave);

Marco Martin's avatar
Marco Martin committed
520
521
    connect(m_fontAASettings, &FontAASettings::subPixelCurrentIndexChanged, this, updateState);
    connect(m_fontAASettings, &FontAASettings::hintingCurrentIndexChanged, this, updateState);
522
523
    connect(m_fontAASettings, &FontAASettings::excludeChanged, this, updateState);
    connect(m_fontAASettings, &FontAASettings::excludeFromChanged, this, updateState);
Marco Martin's avatar
Marco Martin committed
524
525
526
527
528
529
530
531
532
533
    connect(m_fontAASettings, &FontAASettings::excludeToChanged, this, updateState);
    connect(m_fontAASettings, &FontAASettings::antiAliasingChanged, this, updateState);
    connect(m_fontAASettings, &FontAASettings::aliasingChanged, this, updateState);
    connect(m_fontAASettings, &FontAASettings::dpiChanged, this, updateState);
}

KFonts::~KFonts()
{
}

Benjamin Port's avatar
Benjamin Port committed
534
FontsSettings *KFonts::fontsSettings() const
Marco Martin's avatar
Marco Martin committed
535
{
Benjamin Port's avatar
Benjamin Port committed
536
537
    return m_settings;
}
538

Benjamin Port's avatar
Benjamin Port committed
539
540
541
void KFonts::defaults()
{
    m_settings->setDefaults();
Marco Martin's avatar
Marco Martin committed
542
543
    m_fontAASettings->defaults();
}
544

Benjamin Port's avatar
Benjamin Port committed
545
void KFonts::setNearestExistingFonts()
Marco Martin's avatar
Marco Martin committed
546
{
Benjamin Port's avatar
Benjamin Port committed
547
548
549
550
551
552
553
    m_settings->setFont(nearestExistingFont(m_settings->font()));
    m_settings->setFixed(nearestExistingFont(m_settings->fixed()));
    m_settings->setSmallestReadableFont(nearestExistingFont(m_settings->smallestReadableFont()));
    m_settings->setToolBarFont(nearestExistingFont(m_settings->toolBarFont()));
    m_settings->setMenuFont(nearestExistingFont(m_settings->menuFont()));
    m_settings->setActiveFont(nearestExistingFont(m_settings->activeFont()));
}
554

Benjamin Port's avatar
Benjamin Port committed
555
556
557
558
559
void KFonts::load()
{
    m_settings->load();
    setNearestExistingFonts();
    engine()->addImageProvider("preview", new PreviewImageProvider(m_settings->font()));
Marco Martin's avatar
Marco Martin committed
560
561
562

    m_fontAASettings->load();
    setNeedsSave(false);
563
564
}

Marco Martin's avatar
Marco Martin committed
565
void KFonts::save()
566
{
Benjamin Port's avatar
Benjamin Port committed
567
    m_settings->save();
568

Marco Martin's avatar
Marco Martin committed
569
570
571
    KConfig _cfgfonts("kcmfonts");
    KConfigGroup cfgfonts(&_cfgfonts, "General");

572
573
574
575
    FontAASettings::AASetting aaSetting = FontAASettings::AASystem;
    if (m_fontAASettings->antiAliasingNeedsSave()) {
        aaSetting = m_fontAASettings->antiAliasing() ? FontAASettings::AAEnabled : FontAASettings::AADisabled;
    }
Marco Martin's avatar
Marco Martin committed
576
577
578
579
580
581
582
583
    cfgfonts.writeEntry("dontChangeAASettings", aaSetting == FontAASettings::AASystem);

    if (aaSetting == FontAASettings::AAEnabled) {
        m_fontAASettings->save(KXftConfig::AntiAliasing::Enabled);
    } else if (aaSetting == FontAASettings::AADisabled) {
        m_fontAASettings->save(KXftConfig::AntiAliasing::Disabled);
    } else {
        m_fontAASettings->save(KXftConfig::AntiAliasing::NotSet);
584
    }
Marco Martin's avatar
Marco Martin committed
585
586
587
588
589
590
591

    KGlobalSettings::self()->emitChange(KGlobalSettings::FontChanged);

    runRdb(KRdbExportXftSettings | KRdbExportGtkTheme);

    emit fontsHaveChanged();
    setNeedsSave(false);
592
593
}

Marco Martin's avatar
Marco Martin committed
594
void KFonts::updateNeedsSave()
595
{
Benjamin Port's avatar
Benjamin Port committed
596
    setNeedsSave(m_settings->isSaveNeeded() || m_fontAASettings->needsSave());
597
598
}

Marco Martin's avatar
Marco Martin committed
599
void KFonts::adjustAllFonts()
600
{
Benjamin Port's avatar
Benjamin Port committed
601
    QFont font = m_settings->font();
602
    KFontChooser::FontDiffFlags fontDiffFlags;
Marco Martin's avatar
Marco Martin committed
603
    int ret = KFontDialog::getFontDiff(font, fontDiffFlags, KFontChooser::NoDisplayFlags);
604
605

    if (ret == KDialog::Accepted && fontDiffFlags) {
Benjamin Port's avatar
Benjamin Port committed
606
607
608
609
610
611
612
613
        m_settings->setFont(applyFontDiff(m_settings->font(), font, fontDiffFlags));
        m_settings->setMenuFont(applyFontDiff(m_settings->menuFont(), font, fontDiffFlags));
        m_settings->setToolBarFont(applyFontDiff(m_settings->toolBarFont(), font, fontDiffFlags));
        m_settings->setActiveFont(applyFontDiff(m_settings->activeFont(), font, fontDiffFlags));
        m_settings->setSmallestReadableFont(applyFontDiff(m_settings->smallestReadableFont(), font, fontDiffFlags));
        const QFont adjustedFont = applyFontDiff(m_settings->fixed(), font, fontDiffFlags);
        if (QFontInfo(adjustedFont).fixedPitch()) {
            m_settings->setFixed(adjustedFont);
614
615
        }
    }
616
617
}

Marco Martin's avatar
Marco Martin committed
618
QFont KFonts::applyFontDiff(const QFont &fnt, const QFont &newFont, int fontDiffFlags)
619
{
Marco Martin's avatar
Marco Martin committed
620
    QFont font(fnt);
621

Marco Martin's avatar
Marco Martin committed
622
623
    if (fontDiffFlags & KFontChooser::FontDiffSize) {
        font.setPointSizeF(newFont.pointSizeF());
624
    }
Marco Martin's avatar
Marco Martin committed
625
626
627
628
629
630
631
632
633
634
635
    if ((fontDiffFlags & KFontChooser::FontDiffFamily)) {
        font.setFamily(newFont.family());
    }
    if (fontDiffFlags & KFontChooser::FontDiffStyle) {
        font.setWeight(newFont.weight());
        font.setStyle(newFont.style());
        font.setUnderline(newFont.underline());
        font.setStyleName(newFont.styleName());
    }

    return font;
636
637
638
639
}

#include "fonts.moc"