QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgsfontmanager.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsfontmanager.cpp
3 ------------------
4 Date : June 2022
5 Copyright : (C) 2022 Nyall Dawson
6 Email : nyall dot dawson at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16#include "qgsfontmanager.h"
17#include "qgsreadwritelocker.h"
18#include "qgsapplication.h"
20#include "qgsziputils.h"
22#include "qgssettingstree.h"
23
24#include <QRegularExpression>
25#include <QRegularExpressionMatch>
26#include <QDir>
27#include <QFontDatabase>
28#include <QTemporaryFile>
29#include <QTemporaryDir>
30
31const QgsSettingsEntryStringList *QgsFontManager::settingsFontFamilyReplacements = new QgsSettingsEntryStringList( QStringLiteral( "fontFamilyReplacements" ), QgsSettingsTree::sTreeFonts, QStringList(), QStringLiteral( "Automatic font family replacements" ) );
32
33const QgsSettingsEntryBool *QgsFontManager::settingsDownloadMissingFonts = new QgsSettingsEntryBool( QStringLiteral( "downloadMissingFonts" ), QgsSettingsTree::sTreeFonts, true, QStringLiteral( "Automatically download missing fonts whenever possible" ) );
34
36 : QObject( parent )
37{
38 const QStringList replacements = settingsFontFamilyReplacements->value();
39 for ( const QString &replacement : replacements )
40 {
41 const thread_local QRegularExpression rxReplacement( QStringLiteral( "(.*?):(.*)" ) );
42 const QRegularExpressionMatch match = rxReplacement.match( replacement );
43 if ( match.hasMatch() )
44 {
45 mFamilyReplacements.insert( match.captured( 1 ), match.captured( 2 ) );
46 mLowerCaseFamilyReplacements.insert( match.captured( 1 ).toLower(), match.captured( 2 ) );
47 }
48 }
49}
50
51QMap<QString, QString> QgsFontManager::fontFamilyReplacements() const
52{
53 QgsReadWriteLocker locker( mReplacementLock, QgsReadWriteLocker::Read );
54 return mFamilyReplacements;
55}
56
57void QgsFontManager::addFontFamilyReplacement( const QString &original, const QString &replacement )
58{
59 QgsReadWriteLocker locker( mReplacementLock, QgsReadWriteLocker::Write );
60 if ( !replacement.isEmpty() )
61 {
62 mFamilyReplacements.insert( original, replacement );
63 mLowerCaseFamilyReplacements.insert( original.toLower(), replacement );
64 }
65 else
66 {
67 mFamilyReplacements.remove( original );
68 mLowerCaseFamilyReplacements.remove( original.toLower() );
69 }
70 storeFamilyReplacements();
71}
72
73void QgsFontManager::setFontFamilyReplacements( const QMap<QString, QString> &replacements )
74{
75 QgsReadWriteLocker locker( mReplacementLock, QgsReadWriteLocker::Write );
76 mFamilyReplacements = replacements;
77 mLowerCaseFamilyReplacements.clear();
78 for ( auto it = mFamilyReplacements.constBegin(); it != mFamilyReplacements.constEnd(); ++it )
79 mLowerCaseFamilyReplacements.insert( it.key().toLower(), it.value() );
80
81 storeFamilyReplacements();
82}
83
84QString QgsFontManager::processFontFamilyName( const QString &name ) const
85{
86 QgsReadWriteLocker locker( mReplacementLock, QgsReadWriteLocker::Read );
87 auto it = mLowerCaseFamilyReplacements.constFind( name.toLower() );
88 if ( it != mLowerCaseFamilyReplacements.constEnd() )
89 return it.value();
90 else
91 return name;
92}
93
94void QgsFontManager::storeFamilyReplacements()
95{
96 QStringList replacements;
97 for ( auto it = mFamilyReplacements.constBegin(); it != mFamilyReplacements.constEnd(); ++it )
98 replacements << QStringLiteral( "%1:%2" ).arg( it.key(), it.value() );
100}
101
103{
104 QgsReadWriteLocker locker( mReplacementLock, QgsReadWriteLocker::Write );
105 const QString userProfileFontsDir = QgsApplication::qgisSettingsDirPath() + "fonts";
106 QStringList fontDirs { userProfileFontsDir };
107
108 fontDirs.append( mUserFontDirectories );
109
110 for ( const QString &dir : std::as_const( fontDirs ) )
111 {
112 if ( !QFile::exists( dir ) && !QDir().mkpath( dir ) )
113 {
114 QgsDebugError( QStringLiteral( "Cannot create local fonts dir: %1" ).arg( dir ) );
115 return;
116 }
117
118 installFontsFromDirectory( dir );
119 }
120}
121
122void QgsFontManager::installFontsFromDirectory( const QString &dir )
123{
124 const QFileInfoList fileInfoList = QDir( dir ).entryInfoList( QStringList( QStringLiteral( "*" ) ), QDir::Files );
125 QFileInfoList::const_iterator infoIt = fileInfoList.constBegin();
126 for ( ; infoIt != fileInfoList.constEnd(); ++infoIt )
127 {
128 const int id = QFontDatabase::addApplicationFont( infoIt->filePath() );
129 if ( id == -1 )
130 {
131 QgsDebugError( QStringLiteral( "The user font %1 could not be installed" ).arg( infoIt->filePath() ) );
132 mUserFontToFamilyMap.remove( infoIt->filePath() );
133 mUserFontToIdMap.remove( infoIt->filePath() );
134 }
135 else
136 {
137 mUserFontToFamilyMap.insert( infoIt->filePath(), QFontDatabase::applicationFontFamilies( id ) );
138 mUserFontToIdMap.insert( infoIt->filePath(), id );
139 }
140 }
141}
142
143bool QgsFontManager::tryToDownloadFontFamily( const QString &family, QString &matchedFamily )
144{
145 matchedFamily.clear();
147 return false;
148
149 QgsReadWriteLocker locker( mReplacementLock, QgsReadWriteLocker::Read );
150 auto it = mPendingFontDownloads.constFind( family );
151 if ( it != mPendingFontDownloads.constEnd() )
152 {
153 matchedFamily = it.value();
154 return true;
155 }
156 locker.unlock();
157
158 const QString url = urlForFontDownload( family, matchedFamily );
159 if ( url.isEmpty() )
160 return false;
161
162 // It's possible that the font family laundering applied in urlForFontDownload has cleaned up the font
163 // family to a valid font which already exists on the system. In this case we shouldn't try to download
164 // the font again.
165 const QFont testFont( matchedFamily );
166 if ( testFont.exactMatch() )
167 return true;
168
170 mPendingFontDownloads.insert( family, matchedFamily );
171 if ( !mEnableFontDownloads )
172 {
173 mDeferredFontDownloads.insert( url, family );
174 }
175 else
176 {
177 locker.unlock();
178 downloadAndInstallFont( QUrl( url ), family );
179 }
180 return true;
181}
182
184{
185 if ( mEnableFontDownloads )
186 return;
187
188 mEnableFontDownloads = true;
189 QgsReadWriteLocker locker( mReplacementLock, QgsReadWriteLocker::Read );
190 if ( !mDeferredFontDownloads.isEmpty() )
191 {
193 for ( auto it = mDeferredFontDownloads.constBegin(); it != mDeferredFontDownloads.constEnd(); ++it )
194 {
195 downloadAndInstallFont( QUrl( it.key() ), it.value() );
196 }
197 mDeferredFontDownloads.clear();
198 }
199}
200
201QString QgsFontManager::urlForFontDownload( const QString &family, QString &matchedFamily ) const
202{
203 const thread_local QStringList sGoogleFonts
204 {
205 QStringLiteral( "ABeeZee" ),
206 QStringLiteral( "ADLaM Display" ),
207 QStringLiteral( "Abel" ),
208 QStringLiteral( "Abhaya Libre" ),
209 QStringLiteral( "Aboreto" ),
210 QStringLiteral( "Abril Fatface" ),
211 QStringLiteral( "Abyssinica SIL" ),
212 QStringLiteral( "Aclonica" ),
213 QStringLiteral( "Acme" ),
214 QStringLiteral( "Actor" ),
215 QStringLiteral( "Adamina" ),
216 QStringLiteral( "Advent Pro" ),
217 QStringLiteral( "Agdasima" ),
218 QStringLiteral( "Aguafina Script" ),
219 QStringLiteral( "Akatab" ),
220 QStringLiteral( "Akaya Kanadaka" ),
221 QStringLiteral( "Akaya Telivigala" ),
222 QStringLiteral( "Akronim" ),
223 QStringLiteral( "Akshar" ),
224 QStringLiteral( "Aladin" ),
225 QStringLiteral( "Alata" ),
226 QStringLiteral( "Alatsi" ),
227 QStringLiteral( "Albert Sans" ),
228 QStringLiteral( "Aldrich" ),
229 QStringLiteral( "Alef" ),
230 QStringLiteral( "Alegreya" ),
231 QStringLiteral( "Alegreya SC" ),
232 QStringLiteral( "Alegreya Sans" ),
233 QStringLiteral( "Alegreya Sans SC" ),
234 QStringLiteral( "Aleo" ),
235 QStringLiteral( "Alex Brush" ),
236 QStringLiteral( "Alexandria" ),
237 QStringLiteral( "Alfa Slab One" ),
238 QStringLiteral( "Alice" ),
239 QStringLiteral( "Alike" ),
240 QStringLiteral( "Alike Angular" ),
241 QStringLiteral( "Alkalami" ),
242 QStringLiteral( "Alkatra" ),
243 QStringLiteral( "Allan" ),
244 QStringLiteral( "Allerta" ),
245 QStringLiteral( "Allerta Stencil" ),
246 QStringLiteral( "Allison" ),
247 QStringLiteral( "Allura" ),
248 QStringLiteral( "Almarai" ),
249 QStringLiteral( "Almendra" ),
250 QStringLiteral( "Almendra Display" ),
251 QStringLiteral( "Almendra SC" ),
252 QStringLiteral( "Alumni Sans" ),
253 QStringLiteral( "Alumni Sans Collegiate One" ),
254 QStringLiteral( "Alumni Sans Inline One" ),
255 QStringLiteral( "Alumni Sans Pinstripe" ),
256 QStringLiteral( "Amarante" ),
257 QStringLiteral( "Amaranth" ),
258 QStringLiteral( "Amatic SC" ),
259 QStringLiteral( "Amethysta" ),
260 QStringLiteral( "Amiko" ),
261 QStringLiteral( "Amiri" ),
262 QStringLiteral( "Amiri Quran" ),
263 QStringLiteral( "Amita" ),
264 QStringLiteral( "Anaheim" ),
265 QStringLiteral( "Andada" ),
266 QStringLiteral( "Andada Pro" ),
267 QStringLiteral( "Andika" ),
268 QStringLiteral( "Anek Bangla" ),
269 QStringLiteral( "Anek Devanagari" ),
270 QStringLiteral( "Anek Gujarati" ),
271 QStringLiteral( "Anek Gurmukhi" ),
272 QStringLiteral( "Anek Kannada" ),
273 QStringLiteral( "Anek Latin" ),
274 QStringLiteral( "Anek Malayalam" ),
275 QStringLiteral( "Anek Odia" ),
276 QStringLiteral( "Anek Tamil" ),
277 QStringLiteral( "Anek Telugu" ),
278 QStringLiteral( "Angkor" ),
279 QStringLiteral( "Annie Use Your Telescope" ),
280 QStringLiteral( "Anonymous Pro" ),
281 QStringLiteral( "Antic" ),
282 QStringLiteral( "Antic Didone" ),
283 QStringLiteral( "Antic Slab" ),
284 QStringLiteral( "Anton" ),
285 QStringLiteral( "Antonio" ),
286 QStringLiteral( "Anuphan" ),
287 QStringLiteral( "Anybody" ),
288 QStringLiteral( "Aoboshi One" ),
289 QStringLiteral( "Arapey" ),
290 QStringLiteral( "Arbutus" ),
291 QStringLiteral( "Arbutus Slab" ),
292 QStringLiteral( "Architects Daughter" ),
293 QStringLiteral( "Archivo" ),
294 QStringLiteral( "Archivo Black" ),
295 QStringLiteral( "Archivo Narrow" ),
296 QStringLiteral( "Are You Serious" ),
297 QStringLiteral( "Aref Ruqaa" ),
298 QStringLiteral( "Aref Ruqaa Ink" ),
299 QStringLiteral( "Arima" ),
300 QStringLiteral( "Arimo" ),
301 QStringLiteral( "Arizonia" ),
302 QStringLiteral( "Armata" ),
303 QStringLiteral( "Arsenal" ),
304 QStringLiteral( "Artifika" ),
305 QStringLiteral( "Arvo" ),
306 QStringLiteral( "Arya" ),
307 QStringLiteral( "Asap" ),
308 QStringLiteral( "Asap Condensed" ),
309 QStringLiteral( "Asar" ),
310 QStringLiteral( "Asset" ),
311 QStringLiteral( "Assistant" ),
312 QStringLiteral( "Astloch" ),
313 QStringLiteral( "Asul" ),
314 QStringLiteral( "Athiti" ),
315 QStringLiteral( "Atkinson Hyperlegible" ),
316 QStringLiteral( "Atma" ),
317 QStringLiteral( "Atomic Age" ),
318 QStringLiteral( "Aubrey" ),
319 QStringLiteral( "Audiowide" ),
320 QStringLiteral( "Autour One" ),
321 QStringLiteral( "Average" ),
322 QStringLiteral( "Average Sans" ),
323 QStringLiteral( "Averia Gruesa Libre" ),
324 QStringLiteral( "Averia Libre" ),
325 QStringLiteral( "Averia Sans Libre" ),
326 QStringLiteral( "Averia Serif Libre" ),
327 QStringLiteral( "Azeret Mono" ),
328 QStringLiteral( "B612" ),
329 QStringLiteral( "B612 Mono" ),
330 QStringLiteral( "BIZ UDGothic" ),
331 QStringLiteral( "BIZ UDMincho" ),
332 QStringLiteral( "BIZ UDPGothic" ),
333 QStringLiteral( "BIZ UDPMincho" ),
334 QStringLiteral( "Babylonica" ),
335 QStringLiteral( "Bacasime Antique" ),
336 QStringLiteral( "Bad Script" ),
337 QStringLiteral( "Bagel Fat One" ),
338 QStringLiteral( "Bahiana" ),
339 QStringLiteral( "Bahianita" ),
340 QStringLiteral( "Bai Jamjuree" ),
341 QStringLiteral( "Bakbak One" ),
342 QStringLiteral( "Ballet" ),
343 QStringLiteral( "Baloo 2" ),
344 QStringLiteral( "Baloo Bhai 2" ),
345 QStringLiteral( "Baloo Bhaijaan 2" ),
346 QStringLiteral( "Baloo Bhaina 2" ),
347 QStringLiteral( "Baloo Chettan 2" ),
348 QStringLiteral( "Baloo Da 2" ),
349 QStringLiteral( "Baloo Paaji 2" ),
350 QStringLiteral( "Baloo Tamma 2" ),
351 QStringLiteral( "Baloo Tammudu 2" ),
352 QStringLiteral( "Baloo Thambi 2" ),
353 QStringLiteral( "Balsamiq Sans" ),
354 QStringLiteral( "Balthazar" ),
355 QStringLiteral( "Bangers" ),
356 QStringLiteral( "Barlow" ),
357 QStringLiteral( "Barlow Condensed" ),
358 QStringLiteral( "Barlow Semi Condensed" ),
359 QStringLiteral( "Barriecito" ),
360 QStringLiteral( "Barrio" ),
361 QStringLiteral( "Basic" ),
362 QStringLiteral( "Baskervville" ),
363 QStringLiteral( "Battambang" ),
364 QStringLiteral( "Baumans" ),
365 QStringLiteral( "Bayon" ),
366 QStringLiteral( "Be Vietnam Pro" ),
367 QStringLiteral( "Beau Rivage" ),
368 QStringLiteral( "Bebas Neue" ),
369 QStringLiteral( "Belanosima" ),
370 QStringLiteral( "Belgrano" ),
371 QStringLiteral( "Bellefair" ),
372 QStringLiteral( "Belleza" ),
373 QStringLiteral( "Bellota" ),
374 QStringLiteral( "Bellota Text" ),
375 QStringLiteral( "BenchNine" ),
376 QStringLiteral( "Benne" ),
377 QStringLiteral( "Bentham" ),
378 QStringLiteral( "Berkshire Swash" ),
379 QStringLiteral( "Besley" ),
380 QStringLiteral( "Beth Ellen" ),
381 QStringLiteral( "Bevan" ),
382 QStringLiteral( "BhuTuka Expanded One" ),
383 QStringLiteral( "Big Shoulders Display" ),
384 QStringLiteral( "Big Shoulders Inline Display" ),
385 QStringLiteral( "Big Shoulders Inline Text" ),
386 QStringLiteral( "Big Shoulders Stencil Display" ),
387 QStringLiteral( "Big Shoulders Stencil Text" ),
388 QStringLiteral( "Big Shoulders Text" ),
389 QStringLiteral( "Bigelow Rules" ),
390 QStringLiteral( "Bigshot One" ),
391 QStringLiteral( "Bilbo" ),
392 QStringLiteral( "Bilbo Swash Caps" ),
393 QStringLiteral( "BioRhyme" ),
394 QStringLiteral( "BioRhyme Expanded" ),
395 QStringLiteral( "Birthstone" ),
396 QStringLiteral( "Birthstone Bounce" ),
397 QStringLiteral( "Biryani" ),
398 QStringLiteral( "Bitter" ),
399 QStringLiteral( "Black And White Picture" ),
400 QStringLiteral( "Black Han Sans" ),
401 QStringLiteral( "Black Ops One" ),
402 QStringLiteral( "Blaka" ),
403 QStringLiteral( "Blaka Hollow" ),
404 QStringLiteral( "Blaka Ink" ),
405 QStringLiteral( "Blinker" ),
406 QStringLiteral( "Bodoni Moda" ),
407 QStringLiteral( "Bokor" ),
408 QStringLiteral( "Bona Nova" ),
409 QStringLiteral( "Bonbon" ),
410 QStringLiteral( "Bonheur Royale" ),
411 QStringLiteral( "Boogaloo" ),
412 QStringLiteral( "Borel" ),
413 QStringLiteral( "Bowlby One" ),
414 QStringLiteral( "Bowlby One SC" ),
415 QStringLiteral( "Braah One" ),
416 QStringLiteral( "Brawler" ),
417 QStringLiteral( "Bree Serif" ),
418 QStringLiteral( "Bricolage Grotesque" ),
419 QStringLiteral( "Bruno Ace" ),
420 QStringLiteral( "Bruno Ace SC" ),
421 QStringLiteral( "Brygada 1918" ),
422 QStringLiteral( "Bubblegum Sans" ),
423 QStringLiteral( "Bubbler One" ),
424 QStringLiteral( "Buda" ),
425 QStringLiteral( "Buenard" ),
426 QStringLiteral( "Bungee" ),
427 QStringLiteral( "Bungee Hairline" ),
428 QStringLiteral( "Bungee Inline" ),
429 QStringLiteral( "Bungee Outline" ),
430 QStringLiteral( "Bungee Shade" ),
431 QStringLiteral( "Bungee Spice" ),
432 QStringLiteral( "Butcherman" ),
433 QStringLiteral( "Butterfly Kids" ),
434 QStringLiteral( "Cabin" ),
435 QStringLiteral( "Cabin Condensed" ),
436 QStringLiteral( "Cabin Sketch" ),
437 QStringLiteral( "Caesar Dressing" ),
438 QStringLiteral( "Cagliostro" ),
439 QStringLiteral( "Cairo" ),
440 QStringLiteral( "Cairo Play" ),
441 QStringLiteral( "Caladea" ),
442 QStringLiteral( "Calistoga" ),
443 QStringLiteral( "Calligraffitti" ),
444 QStringLiteral( "Cambay" ),
445 QStringLiteral( "Cambo" ),
446 QStringLiteral( "Candal" ),
447 QStringLiteral( "Cantarell" ),
448 QStringLiteral( "Cantata One" ),
449 QStringLiteral( "Cantora One" ),
450 QStringLiteral( "Caprasimo" ),
451 QStringLiteral( "Capriola" ),
452 QStringLiteral( "Caramel" ),
453 QStringLiteral( "Carattere" ),
454 QStringLiteral( "Cardo" ),
455 QStringLiteral( "Carlito" ),
456 QStringLiteral( "Carme" ),
457 QStringLiteral( "Carrois Gothic" ),
458 QStringLiteral( "Carrois Gothic SC" ),
459 QStringLiteral( "Carter One" ),
460 QStringLiteral( "Castoro" ),
461 QStringLiteral( "Castoro Titling" ),
462 QStringLiteral( "Catamaran" ),
463 QStringLiteral( "Caudex" ),
464 QStringLiteral( "Caveat" ),
465 QStringLiteral( "Caveat Brush" ),
466 QStringLiteral( "Cedarville Cursive" ),
467 QStringLiteral( "Ceviche One" ),
468 QStringLiteral( "Chakra Petch" ),
469 QStringLiteral( "Changa" ),
470 QStringLiteral( "Changa One" ),
471 QStringLiteral( "Chango" ),
472 QStringLiteral( "Charis SIL" ),
473 QStringLiteral( "Charm" ),
474 QStringLiteral( "Charmonman" ),
475 QStringLiteral( "Chathura" ),
476 QStringLiteral( "Chau Philomene One" ),
477 QStringLiteral( "Chela One" ),
478 QStringLiteral( "Chelsea Market" ),
479 QStringLiteral( "Chenla" ),
480 QStringLiteral( "Cherish" ),
481 QStringLiteral( "Cherry Bomb One" ),
482 QStringLiteral( "Cherry Cream Soda" ),
483 QStringLiteral( "Cherry Swash" ),
484 QStringLiteral( "Chewy" ),
485 QStringLiteral( "Chicle" ),
486 QStringLiteral( "Chilanka" ),
487 QStringLiteral( "Chivo" ),
488 QStringLiteral( "Chivo Mono" ),
489 QStringLiteral( "Chokokutai" ),
490 QStringLiteral( "Chonburi" ),
491 QStringLiteral( "Cinzel" ),
492 QStringLiteral( "Cinzel Decorative" ),
493 QStringLiteral( "Clicker Script" ),
494 QStringLiteral( "Climate Crisis" ),
495 QStringLiteral( "Coda" ),
496 QStringLiteral( "Coda Caption" ),
497 QStringLiteral( "Codystar" ),
498 QStringLiteral( "Coiny" ),
499 QStringLiteral( "Combo" ),
500 QStringLiteral( "Comfortaa" ),
501 QStringLiteral( "Comforter" ),
502 QStringLiteral( "Comforter Brush" ),
503 QStringLiteral( "Comic Neue" ),
504 QStringLiteral( "Coming Soon" ),
505 QStringLiteral( "Comme" ),
506 QStringLiteral( "Commissioner" ),
507 QStringLiteral( "Concert One" ),
508 QStringLiteral( "Condiment" ),
509 QStringLiteral( "Content" ),
510 QStringLiteral( "Contrail One" ),
511 QStringLiteral( "Convergence" ),
512 QStringLiteral( "Cookie" ),
513 QStringLiteral( "Copse" ),
514 QStringLiteral( "Corben" ),
515 QStringLiteral( "Corinthia" ),
516 QStringLiteral( "Cormorant" ),
517 QStringLiteral( "Cormorant Garamond" ),
518 QStringLiteral( "Cormorant Infant" ),
519 QStringLiteral( "Cormorant SC" ),
520 QStringLiteral( "Cormorant Unicase" ),
521 QStringLiteral( "Cormorant Upright" ),
522 QStringLiteral( "Courgette" ),
523 QStringLiteral( "Courier Prime" ),
524 QStringLiteral( "Cousine" ),
525 QStringLiteral( "Coustard" ),
526 QStringLiteral( "Covered By Your Grace" ),
527 QStringLiteral( "Crafty Girls" ),
528 QStringLiteral( "Creepster" ),
529 QStringLiteral( "Crete Round" ),
530 QStringLiteral( "Crimson Pro" ),
531 QStringLiteral( "Crimson Text" ),
532 QStringLiteral( "Croissant One" ),
533 QStringLiteral( "Crushed" ),
534 QStringLiteral( "Cuprum" ),
535 QStringLiteral( "Cute Font" ),
536 QStringLiteral( "Cutive" ),
537 QStringLiteral( "Cutive Mono" ),
538 QStringLiteral( "DM Mono" ),
539 QStringLiteral( "DM Sans" ),
540 QStringLiteral( "DM Serif Display" ),
541 QStringLiteral( "DM Serif Text" ),
542 QStringLiteral( "Dai Banna SIL" ),
543 QStringLiteral( "Damion" ),
544 QStringLiteral( "Dancing Script" ),
545 QStringLiteral( "Dangrek" ),
546 QStringLiteral( "Darker Grotesque" ),
547 QStringLiteral( "Darumadrop One" ),
548 QStringLiteral( "David Libre" ),
549 QStringLiteral( "Dawning of a New Day" ),
550 QStringLiteral( "Days One" ),
551 QStringLiteral( "Dekko" ),
552 QStringLiteral( "Dela Gothic One" ),
553 QStringLiteral( "Delicious Handrawn" ),
554 QStringLiteral( "Delius" ),
555 QStringLiteral( "Delius Swash Caps" ),
556 QStringLiteral( "Delius Unicase" ),
557 QStringLiteral( "Della Respira" ),
558 QStringLiteral( "Denk One" ),
559 QStringLiteral( "Devonshire" ),
560 QStringLiteral( "Dhurjati" ),
561 QStringLiteral( "Didact Gothic" ),
562 QStringLiteral( "Diphylleia" ),
563 QStringLiteral( "Diplomata" ),
564 QStringLiteral( "Diplomata SC" ),
565 QStringLiteral( "Do Hyeon" ),
566 QStringLiteral( "Dokdo" ),
567 QStringLiteral( "Domine" ),
568 QStringLiteral( "Donegal One" ),
569 QStringLiteral( "Dongle" ),
570 QStringLiteral( "Doppio One" ),
571 QStringLiteral( "Dorsa" ),
572 QStringLiteral( "Dosis" ),
573 QStringLiteral( "DotGothic16" ),
574 QStringLiteral( "Dr Sugiyama" ),
575 QStringLiteral( "Droid Sans" ),
576 QStringLiteral( "Droid Sans Mono" ),
577 QStringLiteral( "Droid Serif" ),
578 QStringLiteral( "Duru Sans" ),
579 QStringLiteral( "DynaPuff" ),
580 QStringLiteral( "Dynalight" ),
581 QStringLiteral( "EB Garamond" ),
582 QStringLiteral( "Eagle Lake" ),
583 QStringLiteral( "East Sea Dokdo" ),
584 QStringLiteral( "Eater" ),
585 QStringLiteral( "Economica" ),
586 QStringLiteral( "Eczar" ),
587 QStringLiteral( "Edu NSW ACT Foundation" ),
588 QStringLiteral( "Edu QLD Beginner" ),
589 QStringLiteral( "Edu SA Beginner" ),
590 QStringLiteral( "Edu TAS Beginner" ),
591 QStringLiteral( "Edu VIC WA NT Beginner" ),
592 QStringLiteral( "Ek Mukta" ),
593 QStringLiteral( "El Messiri" ),
594 QStringLiteral( "Electrolize" ),
595 QStringLiteral( "Elsie" ),
596 QStringLiteral( "Elsie Swash Caps" ),
597 QStringLiteral( "Emblema One" ),
598 QStringLiteral( "Emilys Candy" ),
599 QStringLiteral( "Encode Sans" ),
600 QStringLiteral( "Encode Sans Condensed" ),
601 QStringLiteral( "Encode Sans Expanded" ),
602 QStringLiteral( "Encode Sans SC" ),
603 QStringLiteral( "Encode Sans Semi Condensed" ),
604 QStringLiteral( "Encode Sans Semi Expanded" ),
605 QStringLiteral( "Engagement" ),
606 QStringLiteral( "Englebert" ),
607 QStringLiteral( "Enriqueta" ),
608 QStringLiteral( "Ephesis" ),
609 QStringLiteral( "Epilogue" ),
610 QStringLiteral( "Erica One" ),
611 QStringLiteral( "Esteban" ),
612 QStringLiteral( "Estonia" ),
613 QStringLiteral( "Euphoria Script" ),
614 QStringLiteral( "Ewert" ),
615 QStringLiteral( "Exo" ),
616 QStringLiteral( "Exo 2" ),
617 QStringLiteral( "Expletus Sans" ),
618 QStringLiteral( "Explora" ),
619 QStringLiteral( "Fahkwang" ),
620 QStringLiteral( "Familjen Grotesk" ),
621 QStringLiteral( "Fanwood Text" ),
622 QStringLiteral( "Farro" ),
623 QStringLiteral( "Farsan" ),
624 QStringLiteral( "Fascinate" ),
625 QStringLiteral( "Fascinate Inline" ),
626 QStringLiteral( "Faster One" ),
627 QStringLiteral( "Fasthand" ),
628 QStringLiteral( "Fauna One" ),
629 QStringLiteral( "Faustina" ),
630 QStringLiteral( "Federant" ),
631 QStringLiteral( "Federo" ),
632 QStringLiteral( "Felipa" ),
633 QStringLiteral( "Fenix" ),
634 QStringLiteral( "Festive" ),
635 QStringLiteral( "Figtree" ),
636 QStringLiteral( "Finger Paint" ),
637 QStringLiteral( "Finlandica" ),
638 QStringLiteral( "Fira Code" ),
639 QStringLiteral( "Fira Mono" ),
640 QStringLiteral( "Fira Sans" ),
641 QStringLiteral( "Fira Sans Condensed" ),
642 QStringLiteral( "Fira Sans Extra Condensed" ),
643 QStringLiteral( "Fira Sans Extra Condensed " ),
644 QStringLiteral( "Fjalla One" ),
645 QStringLiteral( "Fjord One" ),
646 QStringLiteral( "Flamenco" ),
647 QStringLiteral( "Flavors" ),
648 QStringLiteral( "Fleur De Leah" ),
649 QStringLiteral( "Flow Block" ),
650 QStringLiteral( "Flow Circular" ),
651 QStringLiteral( "Flow Rounded" ),
652 QStringLiteral( "Foldit" ),
653 QStringLiteral( "Fondamento" ),
654 QStringLiteral( "Fontdiner Swanky" ),
655 QStringLiteral( "Forum" ),
656 QStringLiteral( "Fragment Mono" ),
657 QStringLiteral( "Francois One" ),
658 QStringLiteral( "Frank Ruhl Libre" ),
659 QStringLiteral( "Fraunces" ),
660 QStringLiteral( "Freckle Face" ),
661 QStringLiteral( "Fredericka the Great" ),
662 QStringLiteral( "Fredoka" ),
663 QStringLiteral( "Fredoka One" ),
664 QStringLiteral( "Freehand" ),
665 QStringLiteral( "Fresca" ),
666 QStringLiteral( "Frijole" ),
667 QStringLiteral( "Fruktur" ),
668 QStringLiteral( "Fugaz One" ),
669 QStringLiteral( "Fuggles" ),
670 QStringLiteral( "Fuzzy Bubbles" ),
671 QStringLiteral( "GFS Didot" ),
672 QStringLiteral( "GFS Neohellenic" ),
673 QStringLiteral( "Gabriela" ),
674 QStringLiteral( "Gaegu" ),
675 QStringLiteral( "Gafata" ),
676 QStringLiteral( "Gajraj One" ),
677 QStringLiteral( "Galada" ),
678 QStringLiteral( "Galdeano" ),
679 QStringLiteral( "Galindo" ),
680 QStringLiteral( "Gamja Flower" ),
681 QStringLiteral( "Gantari" ),
682 QStringLiteral( "Gasoek One" ),
683 QStringLiteral( "Gayathri" ),
684 QStringLiteral( "Gelasio" ),
685 QStringLiteral( "Gemunu Libre" ),
686 QStringLiteral( "Genos" ),
687 QStringLiteral( "Gentium Basic" ),
688 QStringLiteral( "Gentium Book Basic" ),
689 QStringLiteral( "Gentium Book Plus" ),
690 QStringLiteral( "Gentium Plus" ),
691 QStringLiteral( "Geo" ),
692 QStringLiteral( "Geologica" ),
693 QStringLiteral( "Georama" ),
694 QStringLiteral( "Geostar" ),
695 QStringLiteral( "Geostar Fill" ),
696 QStringLiteral( "Germania One" ),
697 QStringLiteral( "Gideon Roman" ),
698 QStringLiteral( "Gidugu" ),
699 QStringLiteral( "Gilda Display" ),
700 QStringLiteral( "Girassol" ),
701 QStringLiteral( "Give You Glory" ),
702 QStringLiteral( "Glass Antiqua" ),
703 QStringLiteral( "Glegoo" ),
704 QStringLiteral( "Gloock" ),
705 QStringLiteral( "Gloria Hallelujah" ),
706 QStringLiteral( "Glory" ),
707 QStringLiteral( "Gluten" ),
708 QStringLiteral( "Goblin One" ),
709 QStringLiteral( "Gochi Hand" ),
710 QStringLiteral( "Goldman" ),
711 QStringLiteral( "Golos Text" ),
712 QStringLiteral( "Gorditas" ),
713 QStringLiteral( "Gothic A1" ),
714 QStringLiteral( "Gotu" ),
715 QStringLiteral( "Goudy Bookletter 1911" ),
716 QStringLiteral( "Gowun Batang" ),
717 QStringLiteral( "Gowun Dodum" ),
718 QStringLiteral( "Graduate" ),
719 QStringLiteral( "Grand Hotel" ),
720 QStringLiteral( "Grandiflora One" ),
721 QStringLiteral( "Grandstander" ),
722 QStringLiteral( "Grape Nuts" ),
723 QStringLiteral( "Gravitas One" ),
724 QStringLiteral( "Great Vibes" ),
725 QStringLiteral( "Grechen Fuemen" ),
726 QStringLiteral( "Grenze" ),
727 QStringLiteral( "Grenze Gotisch" ),
728 QStringLiteral( "Grey Qo" ),
729 QStringLiteral( "Griffy" ),
730 QStringLiteral( "Gruppo" ),
731 QStringLiteral( "Gudea" ),
732 QStringLiteral( "Gugi" ),
733 QStringLiteral( "Gulzar" ),
734 QStringLiteral( "Gupter" ),
735 QStringLiteral( "Gurajada" ),
736 QStringLiteral( "Gwendolyn" ),
737 QStringLiteral( "Habibi" ),
738 QStringLiteral( "Hachi Maru Pop" ),
739 QStringLiteral( "Hahmlet" ),
740 QStringLiteral( "Halant" ),
741 QStringLiteral( "Hammersmith One" ),
742 QStringLiteral( "Hanalei" ),
743 QStringLiteral( "Hanalei Fill" ),
744 QStringLiteral( "Handjet" ),
745 QStringLiteral( "Handlee" ),
746 QStringLiteral( "Hanken Grotesk" ),
747 QStringLiteral( "Hanuman" ),
748 QStringLiteral( "Happy Monkey" ),
749 QStringLiteral( "Harmattan" ),
750 QStringLiteral( "Headland One" ),
751 QStringLiteral( "Heebo" ),
752 QStringLiteral( "Henny Penny" ),
753 QStringLiteral( "Hepta Slab" ),
754 QStringLiteral( "Herr Von Muellerhoff" ),
755 QStringLiteral( "Hi Melody" ),
756 QStringLiteral( "Hina Mincho" ),
757 QStringLiteral( "Hind" ),
758 QStringLiteral( "Hind Guntur" ),
759 QStringLiteral( "Hind Madurai" ),
760 QStringLiteral( "Hind Siliguri" ),
761 QStringLiteral( "Hind Vadodara" ),
762 QStringLiteral( "Holtwood One SC" ),
763 QStringLiteral( "Homemade Apple" ),
764 QStringLiteral( "Homenaje" ),
765 QStringLiteral( "Hubballi" ),
766 QStringLiteral( "Hurricane" ),
767 QStringLiteral( "IBM Plex Mono" ),
768 QStringLiteral( "IBM Plex Sans" ),
769 QStringLiteral( "IBM Plex Sans Arabic" ),
770 QStringLiteral( "IBM Plex Sans Condensed" ),
771 QStringLiteral( "IBM Plex Sans Devanagari" ),
772 QStringLiteral( "IBM Plex Sans Hebrew" ),
773 QStringLiteral( "IBM Plex Sans JP" ),
774 QStringLiteral( "IBM Plex Sans KR" ),
775 QStringLiteral( "IBM Plex Sans Thai" ),
776 QStringLiteral( "IBM Plex Sans Thai Looped" ),
777 QStringLiteral( "IBM Plex Serif" ),
778 QStringLiteral( "IM Fell DW Pica" ),
779 QStringLiteral( "IM Fell DW Pica SC" ),
780 QStringLiteral( "IM Fell Double Pica" ),
781 QStringLiteral( "IM Fell Double Pica SC" ),
782 QStringLiteral( "IM Fell English" ),
783 QStringLiteral( "IM Fell English SC" ),
784 QStringLiteral( "IM Fell French Canon" ),
785 QStringLiteral( "IM Fell French Canon SC" ),
786 QStringLiteral( "IM Fell Great Primer" ),
787 QStringLiteral( "IM Fell Great Primer SC" ),
788 QStringLiteral( "Ibarra Real Nova" ),
789 QStringLiteral( "Iceberg" ),
790 QStringLiteral( "Iceland" ),
791 QStringLiteral( "Imbue" ),
792 QStringLiteral( "Imperial Script" ),
793 QStringLiteral( "Imprima" ),
794 QStringLiteral( "Inconsolata" ),
795 QStringLiteral( "Inder" ),
796 QStringLiteral( "Indie Flower" ),
797 QStringLiteral( "Ingrid Darling" ),
798 QStringLiteral( "Inika" ),
799 QStringLiteral( "Inknut Antiqua" ),
800 QStringLiteral( "Inria Sans" ),
801 QStringLiteral( "Inria Serif" ),
802 QStringLiteral( "Inspiration" ),
803 QStringLiteral( "Instrument Sans" ),
804 QStringLiteral( "Instrument Serif" ),
805 QStringLiteral( "Inter" ),
806 QStringLiteral( "Inter Tight" ),
807 QStringLiteral( "Irish Grover" ),
808 QStringLiteral( "Island Moments" ),
809 QStringLiteral( "Istok Web" ),
810 QStringLiteral( "Italiana" ),
811 QStringLiteral( "Italianno" ),
812 QStringLiteral( "Itim" ),
813 QStringLiteral( "Jacques Francois" ),
814 QStringLiteral( "Jacques Francois Shadow" ),
815 QStringLiteral( "Jaldi" ),
816 QStringLiteral( "JetBrains Mono" ),
817 QStringLiteral( "Jim Nightshade" ),
818 QStringLiteral( "Joan" ),
819 QStringLiteral( "Jockey One" ),
820 QStringLiteral( "Jolly Lodger" ),
821 QStringLiteral( "Jomhuria" ),
822 QStringLiteral( "Jomolhari" ),
823 QStringLiteral( "Josefin Sans" ),
824 QStringLiteral( "Josefin Slab" ),
825 QStringLiteral( "Jost" ),
826 QStringLiteral( "Joti One" ),
827 QStringLiteral( "Jua" ),
828 QStringLiteral( "Judson" ),
829 QStringLiteral( "Julee" ),
830 QStringLiteral( "Julius Sans One" ),
831 QStringLiteral( "Junge" ),
832 QStringLiteral( "Jura" ),
833 QStringLiteral( "Just Another Hand" ),
834 QStringLiteral( "Just Me Again Down Here" ),
835 QStringLiteral( "K2D" ),
836 QStringLiteral( "Kablammo" ),
837 QStringLiteral( "Kadwa" ),
838 QStringLiteral( "Kaisei Decol" ),
839 QStringLiteral( "Kaisei HarunoUmi" ),
840 QStringLiteral( "Kaisei Opti" ),
841 QStringLiteral( "Kaisei Tokumin" ),
842 QStringLiteral( "Kalam" ),
843 QStringLiteral( "Kameron" ),
844 QStringLiteral( "Kanit" ),
845 QStringLiteral( "Kantumruy" ),
846 QStringLiteral( "Kantumruy Pro" ),
847 QStringLiteral( "Karantina" ),
848 QStringLiteral( "Karla" ),
849 QStringLiteral( "Karma" ),
850 QStringLiteral( "Katibeh" ),
851 QStringLiteral( "Kaushan Script" ),
852 QStringLiteral( "Kavivanar" ),
853 QStringLiteral( "Kavoon" ),
854 QStringLiteral( "Kdam Thmor" ),
855 QStringLiteral( "Kdam Thmor Pro" ),
856 QStringLiteral( "Keania One" ),
857 QStringLiteral( "Kelly Slab" ),
858 QStringLiteral( "Kenia" ),
859 QStringLiteral( "Khand" ),
860 QStringLiteral( "Khmer" ),
861 QStringLiteral( "Khula" ),
862 QStringLiteral( "Kings" ),
863 QStringLiteral( "Kirang Haerang" ),
864 QStringLiteral( "Kite One" ),
865 QStringLiteral( "Kiwi Maru" ),
866 QStringLiteral( "Klee One" ),
867 QStringLiteral( "Knewave" ),
868 QStringLiteral( "KoHo" ),
869 QStringLiteral( "Kodchasan" ),
870 QStringLiteral( "Koh Santepheap" ),
871 QStringLiteral( "Kolker Brush" ),
872 QStringLiteral( "Konkhmer Sleokchher" ),
873 QStringLiteral( "Kosugi" ),
874 QStringLiteral( "Kosugi Maru" ),
875 QStringLiteral( "Kotta One" ),
876 QStringLiteral( "Koulen" ),
877 QStringLiteral( "Kranky" ),
878 QStringLiteral( "Kreon" ),
879 QStringLiteral( "Kristi" ),
880 QStringLiteral( "Krona One" ),
881 QStringLiteral( "Krub" ),
882 QStringLiteral( "Kufam" ),
883 QStringLiteral( "Kulim Park" ),
884 QStringLiteral( "Kumar One" ),
885 QStringLiteral( "Kumar One Outline" ),
886 QStringLiteral( "Kumbh Sans" ),
887 QStringLiteral( "Kurale" ),
888 QStringLiteral( "La Belle Aurore" ),
889 QStringLiteral( "Labrada" ),
890 QStringLiteral( "Lacquer" ),
891 QStringLiteral( "Laila" ),
892 QStringLiteral( "Lakki Reddy" ),
893 QStringLiteral( "Lalezar" ),
894 QStringLiteral( "Lancelot" ),
895 QStringLiteral( "Langar" ),
896 QStringLiteral( "Lateef" ),
897 QStringLiteral( "Lato" ),
898 QStringLiteral( "Lavishly Yours" ),
899 QStringLiteral( "League Gothic" ),
900 QStringLiteral( "League Script" ),
901 QStringLiteral( "League Spartan" ),
902 QStringLiteral( "Leckerli One" ),
903 QStringLiteral( "Ledger" ),
904 QStringLiteral( "Lekton" ),
905 QStringLiteral( "Lemon" ),
906 QStringLiteral( "Lemonada" ),
907 QStringLiteral( "Lexend" ),
908 QStringLiteral( "Lexend Deca" ),
909 QStringLiteral( "Lexend Exa" ),
910 QStringLiteral( "Lexend Giga" ),
911 QStringLiteral( "Lexend Mega" ),
912 QStringLiteral( "Lexend Peta" ),
913 QStringLiteral( "Lexend Tera" ),
914 QStringLiteral( "Lexend Zetta" ),
915 QStringLiteral( "Libre Barcode 128" ),
916 QStringLiteral( "Libre Barcode 128 Text" ),
917 QStringLiteral( "Libre Barcode 39" ),
918 QStringLiteral( "Libre Barcode 39 Extended" ),
919 QStringLiteral( "Libre Barcode 39 Extended Text" ),
920 QStringLiteral( "Libre Barcode 39 Text" ),
921 QStringLiteral( "Libre Barcode EAN13 Text" ),
922 QStringLiteral( "Libre Baskerville" ),
923 QStringLiteral( "Libre Bodoni" ),
924 QStringLiteral( "Libre Caslon Display" ),
925 QStringLiteral( "Libre Caslon Text" ),
926 QStringLiteral( "Libre Franklin" ),
927 QStringLiteral( "Licorice" ),
928 QStringLiteral( "Life Savers" ),
929 QStringLiteral( "Lilita One" ),
930 QStringLiteral( "Lily Script One" ),
931 QStringLiteral( "Limelight" ),
932 QStringLiteral( "Linden Hill" ),
933 QStringLiteral( "Lisu Bosa" ),
934 QStringLiteral( "Literata" ),
935 QStringLiteral( "Liu Jian Mao Cao" ),
936 QStringLiteral( "Livvic" ),
937 QStringLiteral( "Lobster" ),
938 QStringLiteral( "Lobster Two" ),
939 QStringLiteral( "Londrina Outline" ),
940 QStringLiteral( "Londrina Shadow" ),
941 QStringLiteral( "Londrina Sketch" ),
942 QStringLiteral( "Londrina Solid" ),
943 QStringLiteral( "Long Cang" ),
944 QStringLiteral( "Lora" ),
945 QStringLiteral( "Love Light" ),
946 QStringLiteral( "Love Ya Like A Sister" ),
947 QStringLiteral( "Loved by the King" ),
948 QStringLiteral( "Lovers Quarrel" ),
949 QStringLiteral( "Luckiest Guy" ),
950 QStringLiteral( "Lugrasimo" ),
951 QStringLiteral( "Lumanosimo" ),
952 QStringLiteral( "Lunasima" ),
953 QStringLiteral( "Lusitana" ),
954 QStringLiteral( "Lustria" ),
955 QStringLiteral( "Luxurious Roman" ),
956 QStringLiteral( "Luxurious Script" ),
957 QStringLiteral( "M PLUS 1" ),
958 QStringLiteral( "M PLUS 1 Code" ),
959 QStringLiteral( "M PLUS 1p" ),
960 QStringLiteral( "M PLUS 2" ),
961 QStringLiteral( "M PLUS Code Latin" ),
962 QStringLiteral( "M PLUS Rounded 1c" ),
963 QStringLiteral( "Ma Shan Zheng" ),
964 QStringLiteral( "Macondo" ),
965 QStringLiteral( "Macondo Swash Caps" ),
966 QStringLiteral( "Mada" ),
967 QStringLiteral( "Magra" ),
968 QStringLiteral( "Maiden Orange" ),
969 QStringLiteral( "Maitree" ),
970 QStringLiteral( "Major Mono Display" ),
971 QStringLiteral( "Mako" ),
972 QStringLiteral( "Mali" ),
973 QStringLiteral( "Mallanna" ),
974 QStringLiteral( "Mandali" ),
975 QStringLiteral( "Manjari" ),
976 QStringLiteral( "Manrope" ),
977 QStringLiteral( "Mansalva" ),
978 QStringLiteral( "Manuale" ),
979 QStringLiteral( "Marcellus" ),
980 QStringLiteral( "Marcellus SC" ),
981 QStringLiteral( "Marck Script" ),
982 QStringLiteral( "Margarine" ),
983 QStringLiteral( "Marhey" ),
984 QStringLiteral( "Markazi Text" ),
985 QStringLiteral( "Marko One" ),
986 QStringLiteral( "Marmelad" ),
987 QStringLiteral( "Martel" ),
988 QStringLiteral( "Martel Sans" ),
989 QStringLiteral( "Martian Mono" ),
990 QStringLiteral( "Marvel" ),
991 QStringLiteral( "Mate" ),
992 QStringLiteral( "Mate SC" ),
993 QStringLiteral( "Material Icons" ),
994 QStringLiteral( "Material Icons Outlined" ),
995 QStringLiteral( "Material Icons Round" ),
996 QStringLiteral( "Material Icons Sharp" ),
997 QStringLiteral( "Material Icons Two Tone" ),
998 QStringLiteral( "Material Symbols Outlined" ),
999 QStringLiteral( "Material Symbols Rounded" ),
1000 QStringLiteral( "Material Symbols Sharp" ),
1001 QStringLiteral( "Maven Pro" ),
1002 QStringLiteral( "McLaren" ),
1003 QStringLiteral( "Mea Culpa" ),
1004 QStringLiteral( "Meddon" ),
1005 QStringLiteral( "MedievalSharp" ),
1006 QStringLiteral( "Medula One" ),
1007 QStringLiteral( "Meera Inimai" ),
1008 QStringLiteral( "Megrim" ),
1009 QStringLiteral( "Meie Script" ),
1010 QStringLiteral( "Meow Script" ),
1011 QStringLiteral( "Merienda" ),
1012 QStringLiteral( "Merienda One" ),
1013 QStringLiteral( "Merriweather" ),
1014 QStringLiteral( "Merriweather Sans" ),
1015 QStringLiteral( "Metal" ),
1016 QStringLiteral( "Metal Mania" ),
1017 QStringLiteral( "Metamorphous" ),
1018 QStringLiteral( "Metrophobic" ),
1019 QStringLiteral( "Michroma" ),
1020 QStringLiteral( "Milonga" ),
1021 QStringLiteral( "Miltonian" ),
1022 QStringLiteral( "Miltonian Tattoo" ),
1023 QStringLiteral( "Mina" ),
1024 QStringLiteral( "Mingzat" ),
1025 QStringLiteral( "Miniver" ),
1026 QStringLiteral( "Miriam Libre" ),
1027 QStringLiteral( "Mirza" ),
1028 QStringLiteral( "Miss Fajardose" ),
1029 QStringLiteral( "Mitr" ),
1030 QStringLiteral( "Mochiy Pop One" ),
1031 QStringLiteral( "Mochiy Pop P One" ),
1032 QStringLiteral( "Modak" ),
1033 QStringLiteral( "Modern Antiqua" ),
1034 QStringLiteral( "Mogra" ),
1035 QStringLiteral( "Mohave" ),
1036 QStringLiteral( "Moirai One" ),
1037 QStringLiteral( "Molengo" ),
1038 QStringLiteral( "Molle" ),
1039 QStringLiteral( "Monda" ),
1040 QStringLiteral( "Monofett" ),
1041 QStringLiteral( "Monomaniac One" ),
1042 QStringLiteral( "Monoton" ),
1043 QStringLiteral( "Monsieur La Doulaise" ),
1044 QStringLiteral( "Montaga" ),
1045 QStringLiteral( "Montagu Slab" ),
1046 QStringLiteral( "MonteCarlo" ),
1047 QStringLiteral( "Montez" ),
1048 QStringLiteral( "Montserrat" ),
1049 QStringLiteral( "Montserrat Alternates" ),
1050 QStringLiteral( "Montserrat Subrayada" ),
1051 QStringLiteral( "Moo Lah Lah" ),
1052 QStringLiteral( "Moon Dance" ),
1053 QStringLiteral( "Moul" ),
1054 QStringLiteral( "Moulpali" ),
1055 QStringLiteral( "Mountains of Christmas" ),
1056 QStringLiteral( "Mouse Memoirs" ),
1057 QStringLiteral( "Mr Bedfort" ),
1058 QStringLiteral( "Mr Dafoe" ),
1059 QStringLiteral( "Mr De Haviland" ),
1060 QStringLiteral( "Mrs Saint Delafield" ),
1061 QStringLiteral( "Mrs Sheppards" ),
1062 QStringLiteral( "Ms Madi" ),
1063 QStringLiteral( "Mukta" ),
1064 QStringLiteral( "Mukta Mahee" ),
1065 QStringLiteral( "Mukta Malar" ),
1066 QStringLiteral( "Mukta Vaani" ),
1067 QStringLiteral( "Muli" ),
1068 QStringLiteral( "Mulish" ),
1069 QStringLiteral( "Murecho" ),
1070 QStringLiteral( "MuseoModerno" ),
1071 QStringLiteral( "My Soul" ),
1072 QStringLiteral( "Mynerve" ),
1073 QStringLiteral( "Mystery Quest" ),
1074 QStringLiteral( "NTR" ),
1075 QStringLiteral( "Nabla" ),
1076 QStringLiteral( "Nanum Brush Script" ),
1077 QStringLiteral( "Nanum Gothic" ),
1078 QStringLiteral( "Nanum Gothic Coding" ),
1079 QStringLiteral( "Nanum Myeongjo" ),
1080 QStringLiteral( "Nanum Pen Script" ),
1081 QStringLiteral( "Narnoor" ),
1082 QStringLiteral( "Neonderthaw" ),
1083 QStringLiteral( "Nerko One" ),
1084 QStringLiteral( "Neucha" ),
1085 QStringLiteral( "Neuton" ),
1086 QStringLiteral( "New Rocker" ),
1087 QStringLiteral( "New Tegomin" ),
1088 QStringLiteral( "News Cycle" ),
1089 QStringLiteral( "Newsreader" ),
1090 QStringLiteral( "Niconne" ),
1091 QStringLiteral( "Niramit" ),
1092 QStringLiteral( "Nixie One" ),
1093 QStringLiteral( "Nobile" ),
1094 QStringLiteral( "Nokora" ),
1095 QStringLiteral( "Norican" ),
1096 QStringLiteral( "Nosifer" ),
1097 QStringLiteral( "Notable" ),
1098 QStringLiteral( "Nothing You Could Do" ),
1099 QStringLiteral( "Noticia Text" ),
1100 QStringLiteral( "Noto Color Emoji" ),
1101 QStringLiteral( "Noto Emoji" ),
1102 QStringLiteral( "Noto Kufi Arabic" ),
1103 QStringLiteral( "Noto Music" ),
1104 QStringLiteral( "Noto Naskh Arabic" ),
1105 QStringLiteral( "Noto Nastaliq Urdu" ),
1106 QStringLiteral( "Noto Rashi Hebrew" ),
1107 QStringLiteral( "Noto Sans" ),
1108 QStringLiteral( "Noto Sans Adlam" ),
1109 QStringLiteral( "Noto Sans Adlam Unjoined" ),
1110 QStringLiteral( "Noto Sans Anatolian Hieroglyphs" ),
1111 QStringLiteral( "Noto Sans Arabic" ),
1112 QStringLiteral( "Noto Sans Armenian" ),
1113 QStringLiteral( "Noto Sans Avestan" ),
1114 QStringLiteral( "Noto Sans Balinese" ),
1115 QStringLiteral( "Noto Sans Bamum" ),
1116 QStringLiteral( "Noto Sans Bassa Vah" ),
1117 QStringLiteral( "Noto Sans Batak" ),
1118 QStringLiteral( "Noto Sans Bengali" ),
1119 QStringLiteral( "Noto Sans Bhaiksuki" ),
1120 QStringLiteral( "Noto Sans Brahmi" ),
1121 QStringLiteral( "Noto Sans Buginese" ),
1122 QStringLiteral( "Noto Sans Buhid" ),
1123 QStringLiteral( "Noto Sans Canadian Aboriginal" ),
1124 QStringLiteral( "Noto Sans Carian" ),
1125 QStringLiteral( "Noto Sans Caucasian Albanian" ),
1126 QStringLiteral( "Noto Sans Chakma" ),
1127 QStringLiteral( "Noto Sans Cham" ),
1128 QStringLiteral( "Noto Sans Cherokee" ),
1129 QStringLiteral( "Noto Sans Chorasmian" ),
1130 QStringLiteral( "Noto Sans Coptic" ),
1131 QStringLiteral( "Noto Sans Cuneiform" ),
1132 QStringLiteral( "Noto Sans Cypriot" ),
1133 QStringLiteral( "Noto Sans Cypro Minoan" ),
1134 QStringLiteral( "Noto Sans Deseret" ),
1135 QStringLiteral( "Noto Sans Devanagari" ),
1136 QStringLiteral( "Noto Sans Display" ),
1137 QStringLiteral( "Noto Sans Duployan" ),
1138 QStringLiteral( "Noto Sans Egyptian Hieroglyphs" ),
1139 QStringLiteral( "Noto Sans Elbasan" ),
1140 QStringLiteral( "Noto Sans Elymaic" ),
1141 QStringLiteral( "Noto Sans Ethiopic" ),
1142 QStringLiteral( "Noto Sans Georgian" ),
1143 QStringLiteral( "Noto Sans Glagolitic" ),
1144 QStringLiteral( "Noto Sans Gothic" ),
1145 QStringLiteral( "Noto Sans Grantha" ),
1146 QStringLiteral( "Noto Sans Gujarati" ),
1147 QStringLiteral( "Noto Sans Gunjala Gondi" ),
1148 QStringLiteral( "Noto Sans Gurmukhi" ),
1149 QStringLiteral( "Noto Sans HK" ),
1150 QStringLiteral( "Noto Sans Hanifi Rohingya" ),
1151 QStringLiteral( "Noto Sans Hanunoo" ),
1152 QStringLiteral( "Noto Sans Hatran" ),
1153 QStringLiteral( "Noto Sans Hebrew" ),
1154 QStringLiteral( "Noto Sans Imperial Aramaic" ),
1155 QStringLiteral( "Noto Sans Indic Siyaq Numbers" ),
1156 QStringLiteral( "Noto Sans Inscriptional Pahlavi" ),
1157 QStringLiteral( "Noto Sans Inscriptional Parthian" ),
1158 QStringLiteral( "Noto Sans JP" ),
1159 QStringLiteral( "Noto Sans Japanese" ),
1160 QStringLiteral( "Noto Sans Javanese" ),
1161 QStringLiteral( "Noto Sans KR" ),
1162 QStringLiteral( "Noto Sans Kaithi" ),
1163 QStringLiteral( "Noto Sans Kannada" ),
1164 QStringLiteral( "Noto Sans Kayah Li" ),
1165 QStringLiteral( "Noto Sans Kharoshthi" ),
1166 QStringLiteral( "Noto Sans Khmer" ),
1167 QStringLiteral( "Noto Sans Khojki" ),
1168 QStringLiteral( "Noto Sans Khudawadi" ),
1169 QStringLiteral( "Noto Sans Korean" ),
1170 QStringLiteral( "Noto Sans Lao" ),
1171 QStringLiteral( "Noto Sans Lao Looped" ),
1172 QStringLiteral( "Noto Sans Lepcha" ),
1173 QStringLiteral( "Noto Sans Limbu" ),
1174 QStringLiteral( "Noto Sans Linear A" ),
1175 QStringLiteral( "Noto Sans Linear B" ),
1176 QStringLiteral( "Noto Sans Lisu" ),
1177 QStringLiteral( "Noto Sans Lycian" ),
1178 QStringLiteral( "Noto Sans Lydian" ),
1179 QStringLiteral( "Noto Sans Mahajani" ),
1180 QStringLiteral( "Noto Sans Malayalam" ),
1181 QStringLiteral( "Noto Sans Mandaic" ),
1182 QStringLiteral( "Noto Sans Manichaean" ),
1183 QStringLiteral( "Noto Sans Marchen" ),
1184 QStringLiteral( "Noto Sans Masaram Gondi" ),
1185 QStringLiteral( "Noto Sans Math" ),
1186 QStringLiteral( "Noto Sans Mayan Numerals" ),
1187 QStringLiteral( "Noto Sans Medefaidrin" ),
1188 QStringLiteral( "Noto Sans Meetei Mayek" ),
1189 QStringLiteral( "Noto Sans Mende Kikakui" ),
1190 QStringLiteral( "Noto Sans Meroitic" ),
1191 QStringLiteral( "Noto Sans Miao" ),
1192 QStringLiteral( "Noto Sans Modi" ),
1193 QStringLiteral( "Noto Sans Mongolian" ),
1194 QStringLiteral( "Noto Sans Mono" ),
1195 QStringLiteral( "Noto Sans Mro" ),
1196 QStringLiteral( "Noto Sans Multani" ),
1197 QStringLiteral( "Noto Sans Myanmar" ),
1198 QStringLiteral( "Noto Sans NKo" ),
1199 QStringLiteral( "Noto Sans Nabataean" ),
1200 QStringLiteral( "Noto Sans Nag Mundari" ),
1201 QStringLiteral( "Noto Sans Nandinagari" ),
1202 QStringLiteral( "Noto Sans New Tai Lue" ),
1203 QStringLiteral( "Noto Sans Newa" ),
1204 QStringLiteral( "Noto Sans Nushu" ),
1205 QStringLiteral( "Noto Sans Ogham" ),
1206 QStringLiteral( "Noto Sans Ol Chiki" ),
1207 QStringLiteral( "Noto Sans Old Hungarian" ),
1208 QStringLiteral( "Noto Sans Old Italic" ),
1209 QStringLiteral( "Noto Sans Old North Arabian" ),
1210 QStringLiteral( "Noto Sans Old Permic" ),
1211 QStringLiteral( "Noto Sans Old Persian" ),
1212 QStringLiteral( "Noto Sans Old Sogdian" ),
1213 QStringLiteral( "Noto Sans Old South Arabian" ),
1214 QStringLiteral( "Noto Sans Old Turkic" ),
1215 QStringLiteral( "Noto Sans Oriya" ),
1216 QStringLiteral( "Noto Sans Osage" ),
1217 QStringLiteral( "Noto Sans Osmanya" ),
1218 QStringLiteral( "Noto Sans Pahawh Hmong" ),
1219 QStringLiteral( "Noto Sans Palmyrene" ),
1220 QStringLiteral( "Noto Sans Pau Cin Hau" ),
1221 QStringLiteral( "Noto Sans Phags Pa" ),
1222 QStringLiteral( "Noto Sans Phoenician" ),
1223 QStringLiteral( "Noto Sans Psalter Pahlavi" ),
1224 QStringLiteral( "Noto Sans Rejang" ),
1225 QStringLiteral( "Noto Sans Runic" ),
1226 QStringLiteral( "Noto Sans SC" ),
1227 QStringLiteral( "Noto Sans Samaritan" ),
1228 QStringLiteral( "Noto Sans Saurashtra" ),
1229 QStringLiteral( "Noto Sans Sharada" ),
1230 QStringLiteral( "Noto Sans Shavian" ),
1231 QStringLiteral( "Noto Sans Siddham" ),
1232 QStringLiteral( "Noto Sans SignWriting" ),
1233 QStringLiteral( "Noto Sans Sinhala" ),
1234 QStringLiteral( "Noto Sans Sogdian" ),
1235 QStringLiteral( "Noto Sans Sora Sompeng" ),
1236 QStringLiteral( "Noto Sans Soyombo" ),
1237 QStringLiteral( "Noto Sans Sundanese" ),
1238 QStringLiteral( "Noto Sans Syloti Nagri" ),
1239 QStringLiteral( "Noto Sans Symbols" ),
1240 QStringLiteral( "Noto Sans Symbols 2" ),
1241 QStringLiteral( "Noto Sans Syriac" ),
1242 QStringLiteral( "Noto Sans Syriac Eastern" ),
1243 QStringLiteral( "Noto Sans TC" ),
1244 QStringLiteral( "Noto Sans Tagalog" ),
1245 QStringLiteral( "Noto Sans Tagbanwa" ),
1246 QStringLiteral( "Noto Sans Tai Le" ),
1247 QStringLiteral( "Noto Sans Tai Tham" ),
1248 QStringLiteral( "Noto Sans Tai Viet" ),
1249 QStringLiteral( "Noto Sans Takri" ),
1250 QStringLiteral( "Noto Sans Tamil" ),
1251 QStringLiteral( "Noto Sans Tamil Supplement" ),
1252 QStringLiteral( "Noto Sans Tangsa" ),
1253 QStringLiteral( "Noto Sans Telugu" ),
1254 QStringLiteral( "Noto Sans Thaana" ),
1255 QStringLiteral( "Noto Sans Thai" ),
1256 QStringLiteral( "Noto Sans Thai Looped" ),
1257 QStringLiteral( "Noto Sans Tifinagh" ),
1258 QStringLiteral( "Noto Sans Tirhuta" ),
1259 QStringLiteral( "Noto Sans Ugaritic" ),
1260 QStringLiteral( "Noto Sans Vai" ),
1261 QStringLiteral( "Noto Sans Vithkuqi" ),
1262 QStringLiteral( "Noto Sans Wancho" ),
1263 QStringLiteral( "Noto Sans Warang Citi" ),
1264 QStringLiteral( "Noto Sans Yi" ),
1265 QStringLiteral( "Noto Sans Zanabazar Square" ),
1266 QStringLiteral( "Noto Serif" ),
1267 QStringLiteral( "Noto Serif Ahom" ),
1268 QStringLiteral( "Noto Serif Armenian" ),
1269 QStringLiteral( "Noto Serif Balinese" ),
1270 QStringLiteral( "Noto Serif Bengali" ),
1271 QStringLiteral( "Noto Serif Devanagari" ),
1272 QStringLiteral( "Noto Serif Display" ),
1273 QStringLiteral( "Noto Serif Dogra" ),
1274 QStringLiteral( "Noto Serif Ethiopic" ),
1275 QStringLiteral( "Noto Serif Georgian" ),
1276 QStringLiteral( "Noto Serif Grantha" ),
1277 QStringLiteral( "Noto Serif Gujarati" ),
1278 QStringLiteral( "Noto Serif Gurmukhi" ),
1279 QStringLiteral( "Noto Serif HK" ),
1280 QStringLiteral( "Noto Serif Hebrew" ),
1281 QStringLiteral( "Noto Serif JP" ),
1282 QStringLiteral( "Noto Serif KR" ),
1283 QStringLiteral( "Noto Serif Kannada" ),
1284 QStringLiteral( "Noto Serif Khitan Small Script" ),
1285 QStringLiteral( "Noto Serif Khmer" ),
1286 QStringLiteral( "Noto Serif Khojki" ),
1287 QStringLiteral( "Noto Serif Lao" ),
1288 QStringLiteral( "Noto Serif Makasar" ),
1289 QStringLiteral( "Noto Serif Malayalam" ),
1290 QStringLiteral( "Noto Serif Myanmar" ),
1291 QStringLiteral( "Noto Serif NP Hmong" ),
1292 QStringLiteral( "Noto Serif Oriya" ),
1293 QStringLiteral( "Noto Serif Ottoman Siyaq" ),
1294 QStringLiteral( "Noto Serif SC" ),
1295 QStringLiteral( "Noto Serif Sinhala" ),
1296 QStringLiteral( "Noto Serif TC" ),
1297 QStringLiteral( "Noto Serif Tamil" ),
1298 QStringLiteral( "Noto Serif Tangut" ),
1299 QStringLiteral( "Noto Serif Telugu" ),
1300 QStringLiteral( "Noto Serif Thai" ),
1301 QStringLiteral( "Noto Serif Tibetan" ),
1302 QStringLiteral( "Noto Serif Toto" ),
1303 QStringLiteral( "Noto Serif Vithkuqi" ),
1304 QStringLiteral( "Noto Serif Yezidi" ),
1305 QStringLiteral( "Noto Traditional Nushu" ),
1306 QStringLiteral( "Nova Cut" ),
1307 QStringLiteral( "Nova Flat" ),
1308 QStringLiteral( "Nova Mono" ),
1309 QStringLiteral( "Nova Oval" ),
1310 QStringLiteral( "Nova Round" ),
1311 QStringLiteral( "Nova Script" ),
1312 QStringLiteral( "Nova Slim" ),
1313 QStringLiteral( "Nova Square" ),
1314 QStringLiteral( "Numans" ),
1315 QStringLiteral( "Nunito" ),
1316 QStringLiteral( "Nunito Sans" ),
1317 QStringLiteral( "Nuosu SIL" ),
1318 QStringLiteral( "Odibee Sans" ),
1319 QStringLiteral( "Odor Mean Chey" ),
1320 QStringLiteral( "Offside" ),
1321 QStringLiteral( "Oi" ),
1322 QStringLiteral( "Old Standard TT" ),
1323 QStringLiteral( "Oldenburg" ),
1324 QStringLiteral( "Ole" ),
1325 QStringLiteral( "Oleo Script" ),
1326 QStringLiteral( "Oleo Script Swash Caps" ),
1327 QStringLiteral( "Oooh Baby" ),
1328 QStringLiteral( "Open Sans" ),
1329 QStringLiteral( "Open Sans Condensed" ),
1330 QStringLiteral( "Oranienbaum" ),
1331 QStringLiteral( "Orbit" ),
1332 QStringLiteral( "Orbitron" ),
1333 QStringLiteral( "Oregano" ),
1334 QStringLiteral( "Orelega One" ),
1335 QStringLiteral( "Orienta" ),
1336 QStringLiteral( "Original Surfer" ),
1337 QStringLiteral( "Oswald" ),
1338 QStringLiteral( "Outfit" ),
1339 QStringLiteral( "Over the Rainbow" ),
1340 QStringLiteral( "Overlock" ),
1341 QStringLiteral( "Overlock SC" ),
1342 QStringLiteral( "Overpass" ),
1343 QStringLiteral( "Overpass Mono" ),
1344 QStringLiteral( "Ovo" ),
1345 QStringLiteral( "Oxanium" ),
1346 QStringLiteral( "Oxygen" ),
1347 QStringLiteral( "Oxygen Mono" ),
1348 QStringLiteral( "PT Mono" ),
1349 QStringLiteral( "PT Sans" ),
1350 QStringLiteral( "PT Sans Caption" ),
1351 QStringLiteral( "PT Sans Narrow" ),
1352 QStringLiteral( "PT Serif" ),
1353 QStringLiteral( "PT Serif Caption" ),
1354 QStringLiteral( "Pacifico" ),
1355 QStringLiteral( "Padauk" ),
1356 QStringLiteral( "Padyakke Expanded One" ),
1357 QStringLiteral( "Palanquin" ),
1358 QStringLiteral( "Palanquin Dark" ),
1359 QStringLiteral( "Palette Mosaic" ),
1360 QStringLiteral( "Pangolin" ),
1361 QStringLiteral( "Paprika" ),
1362 QStringLiteral( "Parisienne" ),
1363 QStringLiteral( "Passero One" ),
1364 QStringLiteral( "Passion One" ),
1365 QStringLiteral( "Passions Conflict" ),
1366 QStringLiteral( "Pathway Extreme" ),
1367 QStringLiteral( "Pathway Gothic One" ),
1368 QStringLiteral( "Patrick Hand" ),
1369 QStringLiteral( "Patrick Hand SC" ),
1370 QStringLiteral( "Pattaya" ),
1371 QStringLiteral( "Patua One" ),
1372 QStringLiteral( "Pavanam" ),
1373 QStringLiteral( "Paytone One" ),
1374 QStringLiteral( "Peddana" ),
1375 QStringLiteral( "Peralta" ),
1376 QStringLiteral( "Permanent Marker" ),
1377 QStringLiteral( "Petemoss" ),
1378 QStringLiteral( "Petit Formal Script" ),
1379 QStringLiteral( "Petrona" ),
1380 QStringLiteral( "Philosopher" ),
1381 QStringLiteral( "Phudu" ),
1382 QStringLiteral( "Piazzolla" ),
1383 QStringLiteral( "Piedra" ),
1384 QStringLiteral( "Pinyon Script" ),
1385 QStringLiteral( "Pirata One" ),
1386 QStringLiteral( "Plaster" ),
1387 QStringLiteral( "Play" ),
1388 QStringLiteral( "Playball" ),
1389 QStringLiteral( "Playfair" ),
1390 QStringLiteral( "Playfair Display" ),
1391 QStringLiteral( "Playfair Display SC" ),
1392 QStringLiteral( "Plus Jakarta Sans" ),
1393 QStringLiteral( "Podkova" ),
1394 QStringLiteral( "Poiret One" ),
1395 QStringLiteral( "Poller One" ),
1396 QStringLiteral( "Poltawski Nowy" ),
1397 QStringLiteral( "Poly" ),
1398 QStringLiteral( "Pompiere" ),
1399 QStringLiteral( "Pontano Sans" ),
1400 QStringLiteral( "Poor Story" ),
1401 QStringLiteral( "Poppins" ),
1402 QStringLiteral( "Port Lligat Sans" ),
1403 QStringLiteral( "Port Lligat Slab" ),
1404 QStringLiteral( "Potta One" ),
1405 QStringLiteral( "Pragati Narrow" ),
1406 QStringLiteral( "Praise" ),
1407 QStringLiteral( "Prata" ),
1408 QStringLiteral( "Preahvihear" ),
1409 QStringLiteral( "Press Start 2P" ),
1410 QStringLiteral( "Pridi" ),
1411 QStringLiteral( "Princess Sofia" ),
1412 QStringLiteral( "Prociono" ),
1413 QStringLiteral( "Prompt" ),
1414 QStringLiteral( "Prosto One" ),
1415 QStringLiteral( "Proza Libre" ),
1416 QStringLiteral( "Public Sans" ),
1417 QStringLiteral( "Puppies Play" ),
1418 QStringLiteral( "Puritan" ),
1419 QStringLiteral( "Purple Purse" ),
1420 QStringLiteral( "Qahiri" ),
1421 QStringLiteral( "Quando" ),
1422 QStringLiteral( "Quantico" ),
1423 QStringLiteral( "Quattrocento" ),
1424 QStringLiteral( "Quattrocento Sans" ),
1425 QStringLiteral( "Questrial" ),
1426 QStringLiteral( "Quicksand" ),
1427 QStringLiteral( "Quintessential" ),
1428 QStringLiteral( "Qwigley" ),
1429 QStringLiteral( "Qwitcher Grypen" ),
1430 QStringLiteral( "REM" ),
1431 QStringLiteral( "Racing Sans One" ),
1432 QStringLiteral( "Radio Canada" ),
1433 QStringLiteral( "Radley" ),
1434 QStringLiteral( "Rajdhani" ),
1435 QStringLiteral( "Rakkas" ),
1436 QStringLiteral( "Raleway" ),
1437 QStringLiteral( "Raleway Dots" ),
1438 QStringLiteral( "Ramabhadra" ),
1439 QStringLiteral( "Ramaraja" ),
1440 QStringLiteral( "Rambla" ),
1441 QStringLiteral( "Rammetto One" ),
1442 QStringLiteral( "Rampart One" ),
1443 QStringLiteral( "Ranchers" ),
1444 QStringLiteral( "Rancho" ),
1445 QStringLiteral( "Ranga" ),
1446 QStringLiteral( "Rasa" ),
1447 QStringLiteral( "Rationale" ),
1448 QStringLiteral( "Ravi Prakash" ),
1449 QStringLiteral( "Readex Pro" ),
1450 QStringLiteral( "Recursive" ),
1451 QStringLiteral( "Red Hat Display" ),
1452 QStringLiteral( "Red Hat Mono" ),
1453 QStringLiteral( "Red Hat Text" ),
1454 QStringLiteral( "Red Rose" ),
1455 QStringLiteral( "Redacted" ),
1456 QStringLiteral( "Redacted Script" ),
1457 QStringLiteral( "Redressed" ),
1458 QStringLiteral( "Reem Kufi" ),
1459 QStringLiteral( "Reem Kufi Fun" ),
1460 QStringLiteral( "Reem Kufi Ink" ),
1461 QStringLiteral( "Reenie Beanie" ),
1462 QStringLiteral( "Reggae One" ),
1463 QStringLiteral( "Revalia" ),
1464 QStringLiteral( "Rhodium Libre" ),
1465 QStringLiteral( "Ribeye" ),
1466 QStringLiteral( "Ribeye Marrow" ),
1467 QStringLiteral( "Righteous" ),
1468 QStringLiteral( "Risque" ),
1469 QStringLiteral( "Road Rage" ),
1470 QStringLiteral( "Roboto" ),
1471 QStringLiteral( "Roboto Condensed" ),
1472 QStringLiteral( "Roboto Flex" ),
1473 QStringLiteral( "Roboto Mono" ),
1474 QStringLiteral( "Roboto Serif" ),
1475 QStringLiteral( "Roboto Slab" ),
1476 QStringLiteral( "Rochester" ),
1477 QStringLiteral( "Rock 3D" ),
1478 QStringLiteral( "Rock Salt" ),
1479 QStringLiteral( "RocknRoll One" ),
1480 QStringLiteral( "Rokkitt" ),
1481 QStringLiteral( "Romanesco" ),
1482 QStringLiteral( "Ropa Sans" ),
1483 QStringLiteral( "Rosario" ),
1484 QStringLiteral( "Rosarivo" ),
1485 QStringLiteral( "Rouge Script" ),
1486 QStringLiteral( "Rowdies" ),
1487 QStringLiteral( "Rozha One" ),
1488 QStringLiteral( "Rubik" ),
1489 QStringLiteral( "Rubik 80s Fade" ),
1490 QStringLiteral( "Rubik Beastly" ),
1491 QStringLiteral( "Rubik Bubbles" ),
1492 QStringLiteral( "Rubik Burned" ),
1493 QStringLiteral( "Rubik Dirt" ),
1494 QStringLiteral( "Rubik Distressed" ),
1495 QStringLiteral( "Rubik Gemstones" ),
1496 QStringLiteral( "Rubik Glitch" ),
1497 QStringLiteral( "Rubik Iso" ),
1498 QStringLiteral( "Rubik Marker Hatch" ),
1499 QStringLiteral( "Rubik Maze" ),
1500 QStringLiteral( "Rubik Microbe" ),
1501 QStringLiteral( "Rubik Mono One" ),
1502 QStringLiteral( "Rubik Moonrocks" ),
1503 QStringLiteral( "Rubik One" ),
1504 QStringLiteral( "Rubik Pixels" ),
1505 QStringLiteral( "Rubik Puddles" ),
1506 QStringLiteral( "Rubik Spray Paint" ),
1507 QStringLiteral( "Rubik Storm" ),
1508 QStringLiteral( "Rubik Vinyl" ),
1509 QStringLiteral( "Rubik Wet Paint" ),
1510 QStringLiteral( "Ruda" ),
1511 QStringLiteral( "Rufina" ),
1512 QStringLiteral( "Ruge Boogie" ),
1513 QStringLiteral( "Ruluko" ),
1514 QStringLiteral( "Rum Raisin" ),
1515 QStringLiteral( "Ruslan Display" ),
1516 QStringLiteral( "Russo One" ),
1517 QStringLiteral( "Ruthie" ),
1518 QStringLiteral( "Ruwudu" ),
1519 QStringLiteral( "Rye" ),
1520 QStringLiteral( "STIX Two Text" ),
1521 QStringLiteral( "Sacramento" ),
1522 QStringLiteral( "Sahitya" ),
1523 QStringLiteral( "Sail" ),
1524 QStringLiteral( "Saira" ),
1525 QStringLiteral( "Saira Condensed" ),
1526 QStringLiteral( "Saira Extra Condensed" ),
1527 QStringLiteral( "Saira Semi Condensed" ),
1528 QStringLiteral( "Saira Stencil One" ),
1529 QStringLiteral( "Salsa" ),
1530 QStringLiteral( "Sanchez" ),
1531 QStringLiteral( "Sancreek" ),
1532 QStringLiteral( "Sansita" ),
1533 QStringLiteral( "Sansita One" ),
1534 QStringLiteral( "Sansita Swashed" ),
1535 QStringLiteral( "Sarabun" ),
1536 QStringLiteral( "Sarala" ),
1537 QStringLiteral( "Sarina" ),
1538 QStringLiteral( "Sarpanch" ),
1539 QStringLiteral( "Sassy Frass" ),
1540 QStringLiteral( "Satisfy" ),
1541 QStringLiteral( "Sawarabi Gothic" ),
1542 QStringLiteral( "Sawarabi Mincho" ),
1543 QStringLiteral( "Scada" ),
1544 QStringLiteral( "Scheherazade" ),
1545 QStringLiteral( "Scheherazade New" ),
1546 QStringLiteral( "Schibsted Grotesk" ),
1547 QStringLiteral( "Schoolbell" ),
1548 QStringLiteral( "Scope One" ),
1549 QStringLiteral( "Seaweed Script" ),
1550 QStringLiteral( "Secular One" ),
1551 QStringLiteral( "Sedgwick Ave" ),
1552 QStringLiteral( "Sedgwick Ave Display" ),
1553 QStringLiteral( "Sen" ),
1554 QStringLiteral( "Send Flowers" ),
1555 QStringLiteral( "Sevillana" ),
1556 QStringLiteral( "Seymour One" ),
1557 QStringLiteral( "Shadows Into Light" ),
1558 QStringLiteral( "Shadows Into Light Two" ),
1559 QStringLiteral( "Shalimar" ),
1560 QStringLiteral( "Shantell Sans" ),
1561 QStringLiteral( "Shanti" ),
1562 QStringLiteral( "Share" ),
1563 QStringLiteral( "Share Tech" ),
1564 QStringLiteral( "Share Tech Mono" ),
1565 QStringLiteral( "Shippori Antique" ),
1566 QStringLiteral( "Shippori Antique B1" ),
1567 QStringLiteral( "Shippori Mincho" ),
1568 QStringLiteral( "Shippori Mincho B1" ),
1569 QStringLiteral( "Shizuru" ),
1570 QStringLiteral( "Shojumaru" ),
1571 QStringLiteral( "Short Stack" ),
1572 QStringLiteral( "Shrikhand" ),
1573 QStringLiteral( "Siemreap" ),
1574 QStringLiteral( "Sigmar" ),
1575 QStringLiteral( "Sigmar One" ),
1576 QStringLiteral( "Signika" ),
1577 QStringLiteral( "Signika Negative" ),
1578 QStringLiteral( "Silkscreen" ),
1579 QStringLiteral( "Simonetta" ),
1580 QStringLiteral( "Single Day" ),
1581 QStringLiteral( "Sintony" ),
1582 QStringLiteral( "Sirin Stencil" ),
1583 QStringLiteral( "Six Caps" ),
1584 QStringLiteral( "Skranji" ),
1585 QStringLiteral( "Slabo 13px" ),
1586 QStringLiteral( "Slabo 27px" ),
1587 QStringLiteral( "Slackey" ),
1588 QStringLiteral( "Slackside One" ),
1589 QStringLiteral( "Smokum" ),
1590 QStringLiteral( "Smooch" ),
1591 QStringLiteral( "Smooch Sans" ),
1592 QStringLiteral( "Smythe" ),
1593 QStringLiteral( "Sniglet" ),
1594 QStringLiteral( "Snippet" ),
1595 QStringLiteral( "Snowburst One" ),
1596 QStringLiteral( "Sofadi One" ),
1597 QStringLiteral( "Sofia" ),
1598 QStringLiteral( "Sofia Sans" ),
1599 QStringLiteral( "Sofia Sans Condensed" ),
1600 QStringLiteral( "Sofia Sans Extra Condensed" ),
1601 QStringLiteral( "Sofia Sans Semi Condensed" ),
1602 QStringLiteral( "Solitreo" ),
1603 QStringLiteral( "Solway" ),
1604 QStringLiteral( "Song Myung" ),
1605 QStringLiteral( "Sono" ),
1606 QStringLiteral( "Sonsie One" ),
1607 QStringLiteral( "Sora" ),
1608 QStringLiteral( "Sorts Mill Goudy" ),
1609 QStringLiteral( "Source Code Pro" ),
1610 QStringLiteral( "Source Sans 3" ),
1611 QStringLiteral( "Source Sans Pro" ),
1612 QStringLiteral( "Source Serif 4" ),
1613 QStringLiteral( "Source Serif Pro" ),
1614 QStringLiteral( "Space Grotesk" ),
1615 QStringLiteral( "Space Mono" ),
1616 QStringLiteral( "Special Elite" ),
1617 QStringLiteral( "Spectral" ),
1618 QStringLiteral( "Spectral SC" ),
1619 QStringLiteral( "Spicy Rice" ),
1620 QStringLiteral( "Spinnaker" ),
1621 QStringLiteral( "Spirax" ),
1622 QStringLiteral( "Splash" ),
1623 QStringLiteral( "Spline Sans" ),
1624 QStringLiteral( "Spline Sans Mono" ),
1625 QStringLiteral( "Squada One" ),
1626 QStringLiteral( "Square Peg" ),
1627 QStringLiteral( "Sree Krushnadevaraya" ),
1628 QStringLiteral( "Sriracha" ),
1629 QStringLiteral( "Srisakdi" ),
1630 QStringLiteral( "Staatliches" ),
1631 QStringLiteral( "Stalemate" ),
1632 QStringLiteral( "Stalinist One" ),
1633 QStringLiteral( "Stardos Stencil" ),
1634 QStringLiteral( "Stick" ),
1635 QStringLiteral( "Stick No Bills" ),
1636 QStringLiteral( "Stint Ultra Condensed" ),
1637 QStringLiteral( "Stint Ultra Expanded" ),
1638 QStringLiteral( "Stoke" ),
1639 QStringLiteral( "Strait" ),
1640 QStringLiteral( "Style Script" ),
1641 QStringLiteral( "Stylish" ),
1642 QStringLiteral( "Sue Ellen Francisco" ),
1643 QStringLiteral( "Suez One" ),
1644 QStringLiteral( "Sulphur Point" ),
1645 QStringLiteral( "Sumana" ),
1646 QStringLiteral( "Sunflower" ),
1647 QStringLiteral( "Sunshiney" ),
1648 QStringLiteral( "Supermercado One" ),
1649 QStringLiteral( "Sura" ),
1650 QStringLiteral( "Suranna" ),
1651 QStringLiteral( "Suravaram" ),
1652 QStringLiteral( "Suwannaphum" ),
1653 QStringLiteral( "Swanky and Moo Moo" ),
1654 QStringLiteral( "Syncopate" ),
1655 QStringLiteral( "Syne" ),
1656 QStringLiteral( "Syne Mono" ),
1657 QStringLiteral( "Syne Tactile" ),
1658 QStringLiteral( "Tai Heritage Pro" ),
1659 QStringLiteral( "Tajawal" ),
1660 QStringLiteral( "Tangerine" ),
1661 QStringLiteral( "Tapestry" ),
1662 QStringLiteral( "Taprom" ),
1663 QStringLiteral( "Tauri" ),
1664 QStringLiteral( "Taviraj" ),
1665 QStringLiteral( "Teko" ),
1666 QStringLiteral( "Tektur" ),
1667 QStringLiteral( "Telex" ),
1668 QStringLiteral( "Tenali Ramakrishna" ),
1669 QStringLiteral( "Tenor Sans" ),
1670 QStringLiteral( "Text Me One" ),
1671 QStringLiteral( "Texturina" ),
1672 QStringLiteral( "Thasadith" ),
1673 QStringLiteral( "The Girl Next Door" ),
1674 QStringLiteral( "The Nautigal" ),
1675 QStringLiteral( "Tienne" ),
1676 QStringLiteral( "Tillana" ),
1677 QStringLiteral( "Tilt Neon" ),
1678 QStringLiteral( "Tilt Prism" ),
1679 QStringLiteral( "Tilt Warp" ),
1680 QStringLiteral( "Timmana" ),
1681 QStringLiteral( "Tinos" ),
1682 QStringLiteral( "Tiro Bangla" ),
1683 QStringLiteral( "Tiro Devanagari Hindi" ),
1684 QStringLiteral( "Tiro Devanagari Marathi" ),
1685 QStringLiteral( "Tiro Devanagari Sanskrit" ),
1686 QStringLiteral( "Tiro Gurmukhi" ),
1687 QStringLiteral( "Tiro Kannada" ),
1688 QStringLiteral( "Tiro Tamil" ),
1689 QStringLiteral( "Tiro Telugu" ),
1690 QStringLiteral( "Titan One" ),
1691 QStringLiteral( "Titillium Web" ),
1692 QStringLiteral( "Tomorrow" ),
1693 QStringLiteral( "Tourney" ),
1694 QStringLiteral( "Trade Winds" ),
1695 QStringLiteral( "Train One" ),
1696 QStringLiteral( "Trirong" ),
1697 QStringLiteral( "Trispace" ),
1698 QStringLiteral( "Trocchi" ),
1699 QStringLiteral( "Trochut" ),
1700 QStringLiteral( "Truculenta" ),
1701 QStringLiteral( "Trykker" ),
1702 QStringLiteral( "Tsukimi Rounded" ),
1703 QStringLiteral( "Tulpen One" ),
1704 QStringLiteral( "Turret Road" ),
1705 QStringLiteral( "Twinkle Star" ),
1706 QStringLiteral( "Ubuntu" ),
1707 QStringLiteral( "Ubuntu Condensed" ),
1708 QStringLiteral( "Ubuntu Mono" ),
1709 QStringLiteral( "Uchen" ),
1710 QStringLiteral( "Ultra" ),
1711 QStringLiteral( "Unbounded" ),
1712 QStringLiteral( "Uncial Antiqua" ),
1713 QStringLiteral( "Underdog" ),
1714 QStringLiteral( "Unica One" ),
1715 QStringLiteral( "UnifrakturCook" ),
1716 QStringLiteral( "UnifrakturMaguntia" ),
1717 QStringLiteral( "Unkempt" ),
1718 QStringLiteral( "Unlock" ),
1719 QStringLiteral( "Unna" ),
1720 QStringLiteral( "Updock" ),
1721 QStringLiteral( "Urbanist" ),
1722 QStringLiteral( "VT323" ),
1723 QStringLiteral( "Vampiro One" ),
1724 QStringLiteral( "Varela" ),
1725 QStringLiteral( "Varela Round" ),
1726 QStringLiteral( "Varta" ),
1727 QStringLiteral( "Vast Shadow" ),
1728 QStringLiteral( "Vazirmatn" ),
1729 QStringLiteral( "Vesper Libre" ),
1730 QStringLiteral( "Viaoda Libre" ),
1731 QStringLiteral( "Vibes" ),
1732 QStringLiteral( "Vibur" ),
1733 QStringLiteral( "Victor Mono" ),
1734 QStringLiteral( "Vidaloka" ),
1735 QStringLiteral( "Viga" ),
1736 QStringLiteral( "Vina Sans" ),
1737 QStringLiteral( "Voces" ),
1738 QStringLiteral( "Volkhov" ),
1739 QStringLiteral( "Vollkorn" ),
1740 QStringLiteral( "Vollkorn SC" ),
1741 QStringLiteral( "Voltaire" ),
1742 QStringLiteral( "Vujahday Script" ),
1743 QStringLiteral( "Waiting for the Sunrise" ),
1744 QStringLiteral( "Wallpoet" ),
1745 QStringLiteral( "Walter Turncoat" ),
1746 QStringLiteral( "Warnes" ),
1747 QStringLiteral( "Water Brush" ),
1748 QStringLiteral( "Waterfall" ),
1749 QStringLiteral( "Wavefont" ),
1750 QStringLiteral( "Wellfleet" ),
1751 QStringLiteral( "Wendy One" ),
1752 QStringLiteral( "Whisper" ),
1753 QStringLiteral( "WindSong" ),
1754 QStringLiteral( "Wire One" ),
1755 QStringLiteral( "Wix Madefor Display" ),
1756 QStringLiteral( "Wix Madefor Text" ),
1757 QStringLiteral( "Work Sans" ),
1758 QStringLiteral( "Xanh Mono" ),
1759 QStringLiteral( "Yaldevi" ),
1760 QStringLiteral( "Yanone Kaffeesatz" ),
1761 QStringLiteral( "Yantramanav" ),
1762 QStringLiteral( "Yatra One" ),
1763 QStringLiteral( "Yellowtail" ),
1764 QStringLiteral( "Yeon Sung" ),
1765 QStringLiteral( "Yeseva One" ),
1766 QStringLiteral( "Yesteryear" ),
1767 QStringLiteral( "Yomogi" ),
1768 QStringLiteral( "Yrsa" ),
1769 QStringLiteral( "Ysabeau" ),
1770 QStringLiteral( "Ysabeau Infant" ),
1771 QStringLiteral( "Ysabeau Office" ),
1772 QStringLiteral( "Ysabeau SC" ),
1773 QStringLiteral( "Yuji Boku" ),
1774 QStringLiteral( "Yuji Hentaigana Akari" ),
1775 QStringLiteral( "Yuji Hentaigana Akebono" ),
1776 QStringLiteral( "Yuji Mai" ),
1777 QStringLiteral( "Yuji Syuku" ),
1778 QStringLiteral( "Yusei Magic" ),
1779 QStringLiteral( "ZCOOL KuaiLe" ),
1780 QStringLiteral( "ZCOOL QingKe HuangYou" ),
1781 QStringLiteral( "ZCOOL XiaoWei" ),
1782 QStringLiteral( "Zen Antique" ),
1783 QStringLiteral( "Zen Antique Soft" ),
1784 QStringLiteral( "Zen Dots" ),
1785 QStringLiteral( "Zen Kaku Gothic Antique" ),
1786 QStringLiteral( "Zen Kaku Gothic New" ),
1787 QStringLiteral( "Zen Kurenaido" ),
1788 QStringLiteral( "Zen Loop" ),
1789 QStringLiteral( "Zen Maru Gothic" ),
1790 QStringLiteral( "Zen Old Mincho" ),
1791 QStringLiteral( "Zen Tokyo Zoo" ),
1792 QStringLiteral( "Zeyada" ),
1793 QStringLiteral( "Zhi Mang Xing" ),
1794 QStringLiteral( "Zilla Slab" ),
1795 QStringLiteral( "Zilla Slab Highlight" ),
1796 };
1797
1798 auto cleanFontFamily = []( const QString & family ) -> QString
1799 {
1800 const thread_local QRegularExpression charsToRemove( QStringLiteral( "[^a-z]" ) );
1801 const thread_local QRegularExpression styleNames( QStringLiteral( "(?:normal|regular|light|bold|black|demi|italic|oblique|medium|thin)" ) );
1802
1803 QString processed = family.toLower();
1804 processed.replace( styleNames, QString() );
1805 return processed.replace( charsToRemove, QString() );
1806 };
1807
1808 matchedFamily.clear();
1809 const QString cleanedFamily = cleanFontFamily( family );
1810 for ( const QString &candidate : sGoogleFonts )
1811 {
1812 if ( cleanFontFamily( candidate ) == cleanedFamily )
1813 {
1814 QString paramName = candidate;
1815 paramName.replace( ' ', '+' );
1816 matchedFamily = candidate;
1817 return QStringLiteral( "https://fonts.google.com/download?family=%1" ).arg( paramName );
1818 }
1819 }
1820 return QString();
1821}
1822
1823void QgsFontManager::downloadAndInstallFont( const QUrl &url, const QString &identifier )
1824{
1825 QString description;
1826 if ( identifier.isEmpty() )
1827 {
1828 description = tr( "Installing fonts from %1" ).arg( url.toString() );
1829 }
1830 else
1831 {
1832 description = tr( "Installing %1" ).arg( identifier );
1833 }
1834
1835 QgsNetworkContentFetcherTask *task = new QgsNetworkContentFetcherTask( url, QString(), QgsTask::CanCancel, description );
1836 connect( task, &QgsNetworkContentFetcherTask::fetched, this, [this, task, url, identifier]
1837 {
1838 if ( task->reply()->error() != QNetworkReply::NoError )
1839 {
1840 emit fontDownloadErrorOccurred( url, identifier, task->reply()->errorString() );
1841 }
1842 else
1843 {
1844 QString errorMessage;
1845 QStringList families;
1846 QString licenseDetails;
1847 if ( installFontsFromData( task->reply()->readAll(), errorMessage, families, licenseDetails, task->contentDispositionFilename() ) )
1848 {
1849 QgsReadWriteLocker locker( mReplacementLock, QgsReadWriteLocker::Write );
1850 mPendingFontDownloads.remove( identifier );
1851 locker.unlock();
1852
1853 emit fontDownloaded( families, licenseDetails );
1854 }
1855 else
1856 {
1857 QgsReadWriteLocker locker( mReplacementLock, QgsReadWriteLocker::Write );
1858 mPendingFontDownloads.remove( identifier );
1859 locker.unlock();
1860
1861 emit fontDownloadErrorOccurred( url, identifier, errorMessage );
1862 }
1863 }
1864 } );
1866}
1867
1868bool QgsFontManager::installFontsFromData( const QByteArray &data, QString &errorMessage, QStringList &families, QString &licenseDetails, const QString &filename )
1869{
1870 errorMessage.clear();
1871 families.clear();
1872 licenseDetails.clear();
1873
1874 QTemporaryFile tempFile;
1875 QTemporaryDir tempDir;
1876
1877 QgsReadWriteLocker locker( mReplacementLock, QgsReadWriteLocker::Read );
1878 const QString userFontsDir = mUserFontDirectories.empty() ? ( QgsApplication::qgisSettingsDirPath() + "fonts" ) : mUserFontDirectories.at( 0 );
1879 locker.unlock();
1880
1881 const QDir fontsDir( userFontsDir );
1882
1883 if ( !tempFile.open() )
1884 {
1885 errorMessage = tr( "Could not write font data to a temporary file" );
1886 return false;
1887 }
1888
1889 tempFile.write( data );
1890 tempFile.close();
1891
1892 QString sourcePath = tempFile.fileName();
1893
1894 //try to install the data directly as a font
1895 int id = QFontDatabase::addApplicationFont( sourcePath );
1896 if ( id != -1 )
1897 {
1898 // successfully loaded data as a font
1899 const QStringList foundFamilies = QFontDatabase::applicationFontFamilies( id );
1900 // remove the application font, as we'll copy it to the final destination and re-add from there
1901 QFontDatabase::removeApplicationFont( id );
1902
1903 if ( foundFamilies.empty() )
1904 {
1905 errorMessage = tr( "Could not find any families in font" );
1906 return false;
1907 }
1908
1909 QgsDebugMsgLevel( QStringLiteral( "Found fonts %1" ).arg( foundFamilies.join( ',' ) ), 2 );
1910 families = foundFamilies;
1911 // guess a good name for the file, by taking the first family name from the font
1912 const QString family = families.at( 0 );
1913 const QString destPath = fontsDir.filePath( filename.isEmpty() ? family : filename );
1914 if ( !QFile::copy( sourcePath, destPath ) )
1915 {
1916 errorMessage = tr( "Could not copy font to %1" ).arg( destPath );
1917 return false;
1918 }
1919
1920 id = QFontDatabase::addApplicationFont( destPath );
1921 if ( id == -1 )
1922 {
1923 errorMessage = tr( "Could not install font from %1" ).arg( destPath );
1924 return false;
1925 }
1926 else
1927 {
1929 mUserFontToFamilyMap.insert( destPath, foundFamilies );
1930 mUserFontToIdMap.insert( destPath, id );
1931 }
1932 return true;
1933 }
1934 else
1935 {
1936 // font install failed, but maybe it's a zip file
1937 QStringList files;
1938 if ( QgsZipUtils::unzip( tempFile.fileName(), tempDir.path(), files ) )
1939 {
1941 for ( const QString &file : std::as_const( files ) )
1942 {
1943 const QFileInfo fi( file );
1944 if ( fi.fileName().compare( QLatin1String( "OFL.txt" ), Qt::CaseInsensitive ) == 0
1945 || fi.fileName().compare( QLatin1String( "LICENSE.txt" ), Qt::CaseInsensitive ) == 0 )
1946 {
1947 QFile licenseFile( file );
1948 if ( licenseFile.open( QIODevice::ReadOnly ) )
1949 {
1950 QTextStream in( &licenseFile );
1951 const QString license = in.readAll();
1952 licenseDetails.append( license );
1953 }
1954 }
1955 else if ( fi.suffix().compare( QLatin1String( "ttf" ), Qt::CaseInsensitive ) == 0 ||
1956 fi.suffix().compare( QLatin1String( "otf" ), Qt::CaseInsensitive ) == 0 )
1957 {
1958 sourcePath = file;
1959 id = QFontDatabase::addApplicationFont( sourcePath );
1960 if ( id != -1 )
1961 {
1962 QFontDatabase::removeApplicationFont( id );
1963 const QString destPath = fontsDir.filePath( fi.fileName() );
1964 // dest path may already exist for zip files -- e.g if a single zip contains a number of font variants
1965 if ( !QFile::exists( destPath ) && !QFile::copy( sourcePath, destPath ) )
1966 {
1967 errorMessage = tr( "Could not copy font to %1" ).arg( destPath );
1968 return false;
1969 }
1970 id = QFontDatabase::addApplicationFont( destPath );
1971 if ( id == -1 )
1972 {
1973 errorMessage = tr( "Could not install font from %1" ).arg( destPath );
1974 return false;
1975 }
1976 const QStringList foundFamilies = QFontDatabase::applicationFontFamilies( id );
1977 mUserFontToFamilyMap.insert( destPath, foundFamilies );
1978 mUserFontToIdMap.insert( destPath, id );
1979 for ( const QString &found : foundFamilies )
1980 {
1981 if ( !families.contains( found ) )
1982 families << found;
1983 }
1984 }
1985 }
1986 }
1987 return true;
1988 }
1989 }
1990
1991 errorMessage = tr( "Could not read fonts from data" );
1992 return false;
1993}
1994
1995void QgsFontManager::addUserFontDirectory( const QString &directory )
1996{
1997 QgsReadWriteLocker locker( mReplacementLock, QgsReadWriteLocker::Read );
1998 if ( mUserFontDirectories.contains( directory ) )
1999 return;
2000
2002 mUserFontDirectories.append( directory );
2003 locker.unlock();
2004
2005 if ( !QFile::exists( directory ) && !QDir().mkpath( directory ) )
2006 {
2007 QgsDebugError( QStringLiteral( "Cannot create local fonts dir: %1" ).arg( directory ) );
2008 return;
2009 }
2010
2011 installFontsFromDirectory( directory );
2012}
2013
2014QMap<QString, QStringList> QgsFontManager::userFontToFamilyMap() const
2015{
2016 QgsReadWriteLocker locker( mReplacementLock, QgsReadWriteLocker::Read );
2017 return mUserFontToFamilyMap;
2018}
2019
2020bool QgsFontManager::removeUserFont( const QString &path )
2021{
2022 QgsReadWriteLocker locker( mReplacementLock, QgsReadWriteLocker::Write );
2023 const int id = mUserFontToIdMap.value( path, -1 );
2024 if ( id != -1 )
2025 QFontDatabase::removeApplicationFont( id );
2026 QFile::remove( path );
2027 mUserFontToIdMap.remove( path );
2028 mUserFontToFamilyMap.remove( path );
2029 return true;
2030}
static QString qgisSettingsDirPath()
Returns the path to the settings directory in user's home dir.
static QgsTaskManager * taskManager()
Returns the application's task manager, used for managing application wide background task handling.
void addFontFamilyReplacement(const QString &original, const QString &replacement)
Adds a new font replacement from the original font family to a replacement font family.
bool removeUserFont(const QString &path)
Removes the user font at the specified path.
bool installFontsFromData(const QByteArray &data, QString &errorMessage, QStringList &families, QString &licenseDetails, const QString &filename=QString())
Installs local user fonts from the specified raw data.
QMap< QString, QString > fontFamilyReplacements() const
Returns the map of automatic font family replacements.
void installUserFonts()
Installs user fonts from the profile/fonts directory as application fonts.
void addUserFontDirectory(const QString &directory)
Adds a directory to use for user fonts.
void setFontFamilyReplacements(const QMap< QString, QString > &replacements)
Sets the map of automatic font family replacements.
void downloadAndInstallFont(const QUrl &url, const QString &identifier=QString())
Downloads a font and installs in the user's profile/fonts directory as an application font.
void enableFontDownloadsForSession()
Enables font downloads the the current QGIS session.
QString urlForFontDownload(const QString &family, QString &matchedFamily) const
Returns the URL at which the font family can be downloaded.
static const QgsSettingsEntryStringList * settingsFontFamilyReplacements
Settings entry for font family replacements.
QString processFontFamilyName(const QString &name) const
Processes a font family name, applying any matching fontFamilyReplacements() to the name.
QMap< QString, QStringList > userFontToFamilyMap() const
Returns the mapping of installed user fonts to font families.
QgsFontManager(QObject *parent=nullptr)
Constructor for QgsFontManager, with the specified parent object.
static const QgsSettingsEntryBool * settingsDownloadMissingFonts
Settings entry for font family replacements.
bool tryToDownloadFontFamily(const QString &family, QString &matchedFamily)
Tries to download and install the specified font family.
Handles HTTP network content fetching in a background task.
void fetched()
Emitted when the network content has been fetched, regardless of whether the fetch was successful or ...
QNetworkReply * reply()
Returns the network reply.
The QgsReadWriteLocker class is a convenience class that simplifies locking and unlocking QReadWriteL...
@ Write
Lock for write.
@ Read
Lock for read.
void unlock()
Unlocks the lock.
void changeMode(Mode mode)
Change the mode of the lock to mode.
T value(const QString &dynamicKeyPart=QString()) const
Returns settings value.
bool setValue(const T &value, const QString &dynamicKeyPart=QString()) const
Set settings value.
A boolean settings entry.
A string list settings entry.
static QgsSettingsTreeNode * sTreeFonts
long addTask(QgsTask *task, int priority=0)
Adds a task to the manager.
@ CanCancel
Task can be canceled.
CORE_EXPORT bool unzip(const QString &zip, const QString &dir, QStringList &files, bool checkConsistency=true)
Unzip a zip file in an output directory.
Definition: qgsziputils.cpp:37
CORE_EXPORT const QStringList files(const QString &zip)
Returns the list of files within a zip file.
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
#define QgsDebugError(str)
Definition: qgslogger.h:38