24#include <QRegularExpression> 
   25#include <QRegularExpressionMatch> 
   27#include <QFontDatabase> 
   28#include <QTemporaryFile> 
   29#include <QTemporaryDir> 
   39  for ( 
const QString &replacement : replacements )
 
   41    const thread_local QRegularExpression rxReplacement( QStringLiteral( 
"(.*?):(.*)" ) );
 
   42    const QRegularExpressionMatch match = rxReplacement.match( replacement );
 
   43    if ( match.hasMatch() )
 
   45      mFamilyReplacements.insert( match.captured( 1 ), match.captured( 2 ) );
 
   46      mLowerCaseFamilyReplacements.insert( match.captured( 1 ).toLower(), match.captured( 2 ) );
 
   54  return mFamilyReplacements;
 
   60  if ( !replacement.isEmpty() )
 
   62    mFamilyReplacements.insert( original, replacement );
 
   63    mLowerCaseFamilyReplacements.insert( original.toLower(), replacement );
 
   67    mFamilyReplacements.remove( original );
 
   68    mLowerCaseFamilyReplacements.remove( original.toLower() );
 
   70  storeFamilyReplacements();
 
   76  mFamilyReplacements = replacements;
 
   77  mLowerCaseFamilyReplacements.clear();
 
   78  for ( 
auto it = mFamilyReplacements.constBegin(); it != mFamilyReplacements.constEnd(); ++it )
 
   79    mLowerCaseFamilyReplacements.insert( it.key().toLower(), it.value() );
 
   81  storeFamilyReplacements();
 
   87  auto it = mLowerCaseFamilyReplacements.constFind( name.toLower() );
 
   88  if ( it != mLowerCaseFamilyReplacements.constEnd() )
 
   94void QgsFontManager::storeFamilyReplacements()
 
   96  QStringList replacements;
 
   97  for ( 
auto it = mFamilyReplacements.constBegin(); it != mFamilyReplacements.constEnd(); ++it )
 
   98    replacements << QStringLiteral( 
"%1:%2" ).arg( it.key(), it.value() );
 
  106  QStringList fontDirs { userProfileFontsDir };
 
  108  fontDirs.append( mUserFontDirectories );
 
  110  for ( 
const QString &dir : std::as_const( fontDirs ) )
 
  112    if ( !QFile::exists( dir ) && !QDir().mkpath( dir ) )
 
  114      QgsDebugError( QStringLiteral( 
"Cannot create local fonts dir: %1" ).arg( dir ) );
 
  118    installFontsFromDirectory( dir );
 
  122void QgsFontManager::installFontsFromDirectory( 
const QString &dir )
 
  124  const QFileInfoList fileInfoList = QDir( dir ).entryInfoList( QStringList( QStringLiteral( 
"*" ) ), QDir::Files );
 
  125  QFileInfoList::const_iterator infoIt = fileInfoList.constBegin();
 
  126  for ( ; infoIt != fileInfoList.constEnd(); ++infoIt )
 
  128    const int id = QFontDatabase::addApplicationFont( infoIt->filePath() );
 
  131      QgsDebugError( QStringLiteral( 
"The user font %1 could not be installed" ).arg( infoIt->filePath() ) );
 
  132      mUserFontToFamilyMap.remove( infoIt->filePath() );
 
  133      mUserFontToIdMap.remove( infoIt->filePath() );
 
  137      mUserFontToFamilyMap.insert( infoIt->filePath(), QFontDatabase::applicationFontFamilies( 
id ) );
 
  138      mUserFontToIdMap.insert( infoIt->filePath(), 
id );
 
  145  matchedFamily.clear();
 
  150  auto it = mPendingFontDownloads.constFind( family );
 
  151  if ( it != mPendingFontDownloads.constEnd() )
 
  153    matchedFamily = it.value();
 
  165  const QFont testFont( matchedFamily );
 
  166  if ( testFont.exactMatch() )
 
  170  mPendingFontDownloads.insert( family, matchedFamily );
 
  171  if ( !mEnableFontDownloads )
 
  173    mDeferredFontDownloads.insert( url, family );
 
  185  if ( mEnableFontDownloads )
 
  188  mEnableFontDownloads = 
true;
 
  190  if ( !mDeferredFontDownloads.isEmpty() )
 
  193    for ( 
auto it = mDeferredFontDownloads.constBegin(); it != mDeferredFontDownloads.constEnd(); ++it )
 
  197    mDeferredFontDownloads.clear();
 
  203  const thread_local QStringList sGoogleFonts
 
  205    QStringLiteral( 
"ABeeZee" ),
 
  206    QStringLiteral( 
"Abel" ),
 
  207    QStringLiteral( 
"Abril Fatface" ),
 
  208    QStringLiteral( 
"Aclonica" ),
 
  209    QStringLiteral( 
"Acme" ),
 
  210    QStringLiteral( 
"Actor" ),
 
  211    QStringLiteral( 
"Adamina" ),
 
  212    QStringLiteral( 
"Advent Pro" ),
 
  213    QStringLiteral( 
"Aguafina Script" ),
 
  214    QStringLiteral( 
"Akronim" ),
 
  215    QStringLiteral( 
"Aladin" ),
 
  216    QStringLiteral( 
"Aldrich" ),
 
  217    QStringLiteral( 
"Alef" ),
 
  218    QStringLiteral( 
"Alegreya" ),
 
  219    QStringLiteral( 
"Alegreya SC" ),
 
  220    QStringLiteral( 
"Alegreya Sans" ),
 
  221    QStringLiteral( 
"Alegreya Sans SC" ),
 
  222    QStringLiteral( 
"Alex Brush" ),
 
  223    QStringLiteral( 
"Alfa Slab One" ),
 
  224    QStringLiteral( 
"Alice" ),
 
  225    QStringLiteral( 
"Alike" ),
 
  226    QStringLiteral( 
"Alike Angular" ),
 
  227    QStringLiteral( 
"Allan" ),
 
  228    QStringLiteral( 
"Allerta" ),
 
  229    QStringLiteral( 
"Allerta Stencil" ),
 
  230    QStringLiteral( 
"Allura" ),
 
  231    QStringLiteral( 
"Almendra" ),
 
  232    QStringLiteral( 
"Almendra Display" ),
 
  233    QStringLiteral( 
"Almendra SC" ),
 
  234    QStringLiteral( 
"Amarante" ),
 
  235    QStringLiteral( 
"Amaranth" ),
 
  236    QStringLiteral( 
"Amatic SC" ),
 
  237    QStringLiteral( 
"Amethysta" ),
 
  238    QStringLiteral( 
"Amiri" ),
 
  239    QStringLiteral( 
"Anaheim" ),
 
  240    QStringLiteral( 
"Andada" ),
 
  241    QStringLiteral( 
"Andika" ),
 
  242    QStringLiteral( 
"Angkor" ),
 
  243    QStringLiteral( 
"Annie Use Your Telescope" ),
 
  244    QStringLiteral( 
"Anonymous Pro" ),
 
  245    QStringLiteral( 
"Antic" ),
 
  246    QStringLiteral( 
"Antic Didone" ),
 
  247    QStringLiteral( 
"Antic Slab" ),
 
  248    QStringLiteral( 
"Anton" ),
 
  249    QStringLiteral( 
"Arapey" ),
 
  250    QStringLiteral( 
"Arbutus" ),
 
  251    QStringLiteral( 
"Arbutus Slab" ),
 
  252    QStringLiteral( 
"Architects Daughter" ),
 
  253    QStringLiteral( 
"Archivo" ),
 
  254    QStringLiteral( 
"Archivo Black" ),
 
  255    QStringLiteral( 
"Archivo Narrow" ),
 
  256    QStringLiteral( 
"Arimo" ),
 
  257    QStringLiteral( 
"Arizonia" ),
 
  258    QStringLiteral( 
"Armata" ),
 
  259    QStringLiteral( 
"Artifika" ),
 
  260    QStringLiteral( 
"Arvo" ),
 
  261    QStringLiteral( 
"Asap" ),
 
  262    QStringLiteral( 
"Asset" ),
 
  263    QStringLiteral( 
"Astloch" ),
 
  264    QStringLiteral( 
"Asul" ),
 
  265    QStringLiteral( 
"Atomic Age" ),
 
  266    QStringLiteral( 
"Aubrey" ),
 
  267    QStringLiteral( 
"Audiowide" ),
 
  268    QStringLiteral( 
"Autour One" ),
 
  269    QStringLiteral( 
"Average" ),
 
  270    QStringLiteral( 
"Average Sans" ),
 
  271    QStringLiteral( 
"Averia Gruesa Libre" ),
 
  272    QStringLiteral( 
"Averia Libre" ),
 
  273    QStringLiteral( 
"Averia Sans Libre" ),
 
  274    QStringLiteral( 
"Averia Serif Libre" ),
 
  275    QStringLiteral( 
"Bad Script" ),
 
  276    QStringLiteral( 
"Balthazar" ),
 
  277    QStringLiteral( 
"Bangers" ),
 
  278    QStringLiteral( 
"Barlow" ),
 
  279    QStringLiteral( 
"Basic" ),
 
  280    QStringLiteral( 
"Battambang" ),
 
  281    QStringLiteral( 
"Baumans" ),
 
  282    QStringLiteral( 
"Bayon" ),
 
  283    QStringLiteral( 
"Belgrano" ),
 
  284    QStringLiteral( 
"Belleza" ),
 
  285    QStringLiteral( 
"BenchNine" ),
 
  286    QStringLiteral( 
"Bentham" ),
 
  287    QStringLiteral( 
"Berkshire Swash" ),
 
  288    QStringLiteral( 
"Bevan" ),
 
  289    QStringLiteral( 
"Bigelow Rules" ),
 
  290    QStringLiteral( 
"Bigshot One" ),
 
  291    QStringLiteral( 
"Bilbo" ),
 
  292    QStringLiteral( 
"Bilbo Swash Caps" ),
 
  293    QStringLiteral( 
"Biryani" ),
 
  294    QStringLiteral( 
"Bitter" ),
 
  295    QStringLiteral( 
"Black Ops One" ),
 
  296    QStringLiteral( 
"Bokor" ),
 
  297    QStringLiteral( 
"Bonbon" ),
 
  298    QStringLiteral( 
"Boogaloo" ),
 
  299    QStringLiteral( 
"Bowlby One" ),
 
  300    QStringLiteral( 
"Bowlby One SC" ),
 
  301    QStringLiteral( 
"Brawler" ),
 
  302    QStringLiteral( 
"Bree Serif" ),
 
  303    QStringLiteral( 
"Bubblegum Sans" ),
 
  304    QStringLiteral( 
"Bubbler One" ),
 
  305    QStringLiteral( 
"Buda" ),
 
  306    QStringLiteral( 
"Buenard" ),
 
  307    QStringLiteral( 
"Butcherman" ),
 
  308    QStringLiteral( 
"Butterfly Kids" ),
 
  309    QStringLiteral( 
"Cabin" ),
 
  310    QStringLiteral( 
"Cabin Condensed" ),
 
  311    QStringLiteral( 
"Cabin Sketch" ),
 
  312    QStringLiteral( 
"Caesar Dressing" ),
 
  313    QStringLiteral( 
"Cagliostro" ),
 
  314    QStringLiteral( 
"Calligraffitti" ),
 
  315    QStringLiteral( 
"Cambay" ),
 
  316    QStringLiteral( 
"Cambo" ),
 
  317    QStringLiteral( 
"Candal" ),
 
  318    QStringLiteral( 
"Cantarell" ),
 
  319    QStringLiteral( 
"Cantata One" ),
 
  320    QStringLiteral( 
"Cantora One" ),
 
  321    QStringLiteral( 
"Capriola" ),
 
  322    QStringLiteral( 
"Cardo" ),
 
  323    QStringLiteral( 
"Carme" ),
 
  324    QStringLiteral( 
"Carrois Gothic" ),
 
  325    QStringLiteral( 
"Carrois Gothic SC" ),
 
  326    QStringLiteral( 
"Carter One" ),
 
  327    QStringLiteral( 
"Caudex" ),
 
  328    QStringLiteral( 
"Cedarville Cursive" ),
 
  329    QStringLiteral( 
"Ceviche One" ),
 
  330    QStringLiteral( 
"Changa One" ),
 
  331    QStringLiteral( 
"Chango" ),
 
  332    QStringLiteral( 
"Chau Philomene One" ),
 
  333    QStringLiteral( 
"Chela One" ),
 
  334    QStringLiteral( 
"Chelsea Market" ),
 
  335    QStringLiteral( 
"Chenla" ),
 
  336    QStringLiteral( 
"Cherry Cream Soda" ),
 
  337    QStringLiteral( 
"Cherry Swash" ),
 
  338    QStringLiteral( 
"Chewy" ),
 
  339    QStringLiteral( 
"Chicle" ),
 
  340    QStringLiteral( 
"Chivo" ),
 
  341    QStringLiteral( 
"Cinzel" ),
 
  342    QStringLiteral( 
"Cinzel Decorative" ),
 
  343    QStringLiteral( 
"Clicker Script" ),
 
  344    QStringLiteral( 
"Coda" ),
 
  345    QStringLiteral( 
"Coda Caption" ),
 
  346    QStringLiteral( 
"Codystar" ),
 
  347    QStringLiteral( 
"Combo" ),
 
  348    QStringLiteral( 
"Comfortaa" ),
 
  349    QStringLiteral( 
"Coming Soon" ),
 
  350    QStringLiteral( 
"Concert One" ),
 
  351    QStringLiteral( 
"Condiment" ),
 
  352    QStringLiteral( 
"Content" ),
 
  353    QStringLiteral( 
"Contrail One" ),
 
  354    QStringLiteral( 
"Convergence" ),
 
  355    QStringLiteral( 
"Cookie" ),
 
  356    QStringLiteral( 
"Copse" ),
 
  357    QStringLiteral( 
"Corben" ),
 
  358    QStringLiteral( 
"Courgette" ),
 
  359    QStringLiteral( 
"Cousine" ),
 
  360    QStringLiteral( 
"Coustard" ),
 
  361    QStringLiteral( 
"Covered By Your Grace" ),
 
  362    QStringLiteral( 
"Crafty Girls" ),
 
  363    QStringLiteral( 
"Creepster" ),
 
  364    QStringLiteral( 
"Crete Round" ),
 
  365    QStringLiteral( 
"Crimson Text" ),
 
  366    QStringLiteral( 
"Croissant One" ),
 
  367    QStringLiteral( 
"Crushed" ),
 
  368    QStringLiteral( 
"Cuprum" ),
 
  369    QStringLiteral( 
"Cutive" ),
 
  370    QStringLiteral( 
"Cutive Mono" ),
 
  371    QStringLiteral( 
"Damion" ),
 
  372    QStringLiteral( 
"Dancing Script" ),
 
  373    QStringLiteral( 
"Dangrek" ),
 
  374    QStringLiteral( 
"Dawning of a New Day" ),
 
  375    QStringLiteral( 
"Days One" ),
 
  376    QStringLiteral( 
"Dekko" ),
 
  377    QStringLiteral( 
"Delius" ),
 
  378    QStringLiteral( 
"Delius Swash Caps" ),
 
  379    QStringLiteral( 
"Delius Unicase" ),
 
  380    QStringLiteral( 
"Della Respira" ),
 
  381    QStringLiteral( 
"Denk One" ),
 
  382    QStringLiteral( 
"Devonshire" ),
 
  383    QStringLiteral( 
"Dhurjati" ),
 
  384    QStringLiteral( 
"Didact Gothic" ),
 
  385    QStringLiteral( 
"Diplomata" ),
 
  386    QStringLiteral( 
"Diplomata SC" ),
 
  387    QStringLiteral( 
"Domine" ),
 
  388    QStringLiteral( 
"Donegal One" ),
 
  389    QStringLiteral( 
"Doppio One" ),
 
  390    QStringLiteral( 
"Dorsa" ),
 
  391    QStringLiteral( 
"Dosis" ),
 
  392    QStringLiteral( 
"Dr Sugiyama" ),
 
  393    QStringLiteral( 
"Droid Sans" ),
 
  394    QStringLiteral( 
"Droid Sans Mono" ),
 
  395    QStringLiteral( 
"Droid Serif" ),
 
  396    QStringLiteral( 
"Duru Sans" ),
 
  397    QStringLiteral( 
"Dynalight" ),
 
  398    QStringLiteral( 
"EB Garamond" ),
 
  399    QStringLiteral( 
"Eagle Lake" ),
 
  400    QStringLiteral( 
"Eater" ),
 
  401    QStringLiteral( 
"Economica" ),
 
  402    QStringLiteral( 
"Ek Mukta" ),
 
  403    QStringLiteral( 
"Electrolize" ),
 
  404    QStringLiteral( 
"Elsie" ),
 
  405    QStringLiteral( 
"Elsie Swash Caps" ),
 
  406    QStringLiteral( 
"Emblema One" ),
 
  407    QStringLiteral( 
"Emilys Candy" ),
 
  408    QStringLiteral( 
"Engagement" ),
 
  409    QStringLiteral( 
"Englebert" ),
 
  410    QStringLiteral( 
"Enriqueta" ),
 
  411    QStringLiteral( 
"Erica One" ),
 
  412    QStringLiteral( 
"Esteban" ),
 
  413    QStringLiteral( 
"Euphoria Script" ),
 
  414    QStringLiteral( 
"Ewert" ),
 
  415    QStringLiteral( 
"Exo" ),
 
  416    QStringLiteral( 
"Exo 2" ),
 
  417    QStringLiteral( 
"Expletus Sans" ),
 
  418    QStringLiteral( 
"Fanwood Text" ),
 
  419    QStringLiteral( 
"Fascinate" ),
 
  420    QStringLiteral( 
"Fascinate Inline" ),
 
  421    QStringLiteral( 
"Faster One" ),
 
  422    QStringLiteral( 
"Fasthand" ),
 
  423    QStringLiteral( 
"Fauna One" ),
 
  424    QStringLiteral( 
"Federant" ),
 
  425    QStringLiteral( 
"Federo" ),
 
  426    QStringLiteral( 
"Felipa" ),
 
  427    QStringLiteral( 
"Fenix" ),
 
  428    QStringLiteral( 
"Finger Paint" ),
 
  429    QStringLiteral( 
"Fira Code" ),
 
  430    QStringLiteral( 
"Fira Mono" ),
 
  431    QStringLiteral( 
"Fira Sans" ),
 
  432    QStringLiteral( 
"Fira Sans Condensed" ),
 
  433    QStringLiteral( 
"Fira Sans Extra Condensed " ),
 
  434    QStringLiteral( 
"Fjalla One" ),
 
  435    QStringLiteral( 
"Fjord One" ),
 
  436    QStringLiteral( 
"Flamenco" ),
 
  437    QStringLiteral( 
"Flavors" ),
 
  438    QStringLiteral( 
"Fondamento" ),
 
  439    QStringLiteral( 
"Fontdiner Swanky" ),
 
  440    QStringLiteral( 
"Forum" ),
 
  441    QStringLiteral( 
"Francois One" ),
 
  442    QStringLiteral( 
"Freckle Face" ),
 
  443    QStringLiteral( 
"Fredericka the Great" ),
 
  444    QStringLiteral( 
"Fredoka One" ),
 
  445    QStringLiteral( 
"Freehand" ),
 
  446    QStringLiteral( 
"Fresca" ),
 
  447    QStringLiteral( 
"Frijole" ),
 
  448    QStringLiteral( 
"Fruktur" ),
 
  449    QStringLiteral( 
"Fugaz One" ),
 
  450    QStringLiteral( 
"GFS Didot" ),
 
  451    QStringLiteral( 
"GFS Neohellenic" ),
 
  452    QStringLiteral( 
"Gabriela" ),
 
  453    QStringLiteral( 
"Gafata" ),
 
  454    QStringLiteral( 
"Galdeano" ),
 
  455    QStringLiteral( 
"Galindo" ),
 
  456    QStringLiteral( 
"Gentium Basic" ),
 
  457    QStringLiteral( 
"Gentium Book Basic" ),
 
  458    QStringLiteral( 
"Geo" ),
 
  459    QStringLiteral( 
"Geostar" ),
 
  460    QStringLiteral( 
"Geostar Fill" ),
 
  461    QStringLiteral( 
"Germania One" ),
 
  462    QStringLiteral( 
"Gidugu" ),
 
  463    QStringLiteral( 
"Gilda Display" ),
 
  464    QStringLiteral( 
"Give You Glory" ),
 
  465    QStringLiteral( 
"Glass Antiqua" ),
 
  466    QStringLiteral( 
"Glegoo" ),
 
  467    QStringLiteral( 
"Gloria Hallelujah" ),
 
  468    QStringLiteral( 
"Goblin One" ),
 
  469    QStringLiteral( 
"Gochi Hand" ),
 
  470    QStringLiteral( 
"Gorditas" ),
 
  471    QStringLiteral( 
"Goudy Bookletter 1911" ),
 
  472    QStringLiteral( 
"Graduate" ),
 
  473    QStringLiteral( 
"Grand Hotel" ),
 
  474    QStringLiteral( 
"Gravitas One" ),
 
  475    QStringLiteral( 
"Great Vibes" ),
 
  476    QStringLiteral( 
"Griffy" ),
 
  477    QStringLiteral( 
"Gruppo" ),
 
  478    QStringLiteral( 
"Gudea" ),
 
  479    QStringLiteral( 
"Gurajada" ),
 
  480    QStringLiteral( 
"Habibi" ),
 
  481    QStringLiteral( 
"Halant" ),
 
  482    QStringLiteral( 
"Hammersmith One" ),
 
  483    QStringLiteral( 
"Hanalei" ),
 
  484    QStringLiteral( 
"Hanalei Fill" ),
 
  485    QStringLiteral( 
"Handlee" ),
 
  486    QStringLiteral( 
"Hanuman" ),
 
  487    QStringLiteral( 
"Happy Monkey" ),
 
  488    QStringLiteral( 
"Headland One" ),
 
  489    QStringLiteral( 
"Henny Penny" ),
 
  490    QStringLiteral( 
"Herr Von Muellerhoff" ),
 
  491    QStringLiteral( 
"Hind" ),
 
  492    QStringLiteral( 
"Holtwood One SC" ),
 
  493    QStringLiteral( 
"Homemade Apple" ),
 
  494    QStringLiteral( 
"Homenaje" ),
 
  495    QStringLiteral( 
"IM Fell DW Pica" ),
 
  496    QStringLiteral( 
"IM Fell DW Pica SC" ),
 
  497    QStringLiteral( 
"IM Fell Double Pica" ),
 
  498    QStringLiteral( 
"IM Fell Double Pica SC" ),
 
  499    QStringLiteral( 
"IM Fell English" ),
 
  500    QStringLiteral( 
"IM Fell English SC" ),
 
  501    QStringLiteral( 
"IM Fell French Canon" ),
 
  502    QStringLiteral( 
"IM Fell French Canon SC" ),
 
  503    QStringLiteral( 
"IM Fell Great Primer" ),
 
  504    QStringLiteral( 
"IM Fell Great Primer SC" ),
 
  505    QStringLiteral( 
"Iceberg" ),
 
  506    QStringLiteral( 
"Iceland" ),
 
  507    QStringLiteral( 
"Imprima" ),
 
  508    QStringLiteral( 
"Inconsolata" ),
 
  509    QStringLiteral( 
"Inder" ),
 
  510    QStringLiteral( 
"Indie Flower" ),
 
  511    QStringLiteral( 
"Inika" ),
 
  512    QStringLiteral( 
"Inter" ),
 
  513    QStringLiteral( 
"Irish Grover" ),
 
  514    QStringLiteral( 
"Istok Web" ),
 
  515    QStringLiteral( 
"Italiana" ),
 
  516    QStringLiteral( 
"Italianno" ),
 
  517    QStringLiteral( 
"Jacques Francois" ),
 
  518    QStringLiteral( 
"Jacques Francois Shadow" ),
 
  519    QStringLiteral( 
"Jaldi" ),
 
  520    QStringLiteral( 
"Jim Nightshade" ),
 
  521    QStringLiteral( 
"Jockey One" ),
 
  522    QStringLiteral( 
"Jolly Lodger" ),
 
  523    QStringLiteral( 
"Josefin Sans" ),
 
  524    QStringLiteral( 
"Josefin Slab" ),
 
  525    QStringLiteral( 
"Joti One" ),
 
  526    QStringLiteral( 
"Judson" ),
 
  527    QStringLiteral( 
"Julee" ),
 
  528    QStringLiteral( 
"Julius Sans One" ),
 
  529    QStringLiteral( 
"Junge" ),
 
  530    QStringLiteral( 
"Jura" ),
 
  531    QStringLiteral( 
"Just Another Hand" ),
 
  532    QStringLiteral( 
"Just Me Again Down Here" ),
 
  533    QStringLiteral( 
"Kalam" ),
 
  534    QStringLiteral( 
"Kameron" ),
 
  535    QStringLiteral( 
"Kantumruy" ),
 
  536    QStringLiteral( 
"Karla" ),
 
  537    QStringLiteral( 
"Karma" ),
 
  538    QStringLiteral( 
"Kaushan Script" ),
 
  539    QStringLiteral( 
"Kavoon" ),
 
  540    QStringLiteral( 
"Kdam Thmor" ),
 
  541    QStringLiteral( 
"Keania One" ),
 
  542    QStringLiteral( 
"Kelly Slab" ),
 
  543    QStringLiteral( 
"Kenia" ),
 
  544    QStringLiteral( 
"Khand" ),
 
  545    QStringLiteral( 
"Khmer" ),
 
  546    QStringLiteral( 
"Khula" ),
 
  547    QStringLiteral( 
"Kite One" ),
 
  548    QStringLiteral( 
"Knewave" ),
 
  549    QStringLiteral( 
"Kotta One" ),
 
  550    QStringLiteral( 
"Koulen" ),
 
  551    QStringLiteral( 
"Kranky" ),
 
  552    QStringLiteral( 
"Kreon" ),
 
  553    QStringLiteral( 
"Kristi" ),
 
  554    QStringLiteral( 
"Krona One" ),
 
  555    QStringLiteral( 
"La Belle Aurore" ),
 
  556    QStringLiteral( 
"Laila" ),
 
  557    QStringLiteral( 
"Lakki Reddy" ),
 
  558    QStringLiteral( 
"Lancelot" ),
 
  559    QStringLiteral( 
"Lateef" ),
 
  560    QStringLiteral( 
"Lato" ),
 
  561    QStringLiteral( 
"League Script" ),
 
  562    QStringLiteral( 
"Leckerli One" ),
 
  563    QStringLiteral( 
"Ledger" ),
 
  564    QStringLiteral( 
"Lekton" ),
 
  565    QStringLiteral( 
"Lemon" ),
 
  566    QStringLiteral( 
"Libre Baskerville" ),
 
  567    QStringLiteral( 
"Life Savers" ),
 
  568    QStringLiteral( 
"Lilita One" ),
 
  569    QStringLiteral( 
"Lily Script One" ),
 
  570    QStringLiteral( 
"Limelight" ),
 
  571    QStringLiteral( 
"Linden Hill" ),
 
  572    QStringLiteral( 
"Lobster" ),
 
  573    QStringLiteral( 
"Lobster Two" ),
 
  574    QStringLiteral( 
"Londrina Outline" ),
 
  575    QStringLiteral( 
"Londrina Shadow" ),
 
  576    QStringLiteral( 
"Londrina Sketch" ),
 
  577    QStringLiteral( 
"Londrina Solid" ),
 
  578    QStringLiteral( 
"Lora" ),
 
  579    QStringLiteral( 
"Love Ya Like A Sister" ),
 
  580    QStringLiteral( 
"Loved by the King" ),
 
  581    QStringLiteral( 
"Lovers Quarrel" ),
 
  582    QStringLiteral( 
"Luckiest Guy" ),
 
  583    QStringLiteral( 
"Lusitana" ),
 
  584    QStringLiteral( 
"Lustria" ),
 
  585    QStringLiteral( 
"Macondo" ),
 
  586    QStringLiteral( 
"Macondo Swash Caps" ),
 
  587    QStringLiteral( 
"Magra" ),
 
  588    QStringLiteral( 
"Maiden Orange" ),
 
  589    QStringLiteral( 
"Mako" ),
 
  590    QStringLiteral( 
"Mallanna" ),
 
  591    QStringLiteral( 
"Mandali" ),
 
  592    QStringLiteral( 
"Marcellus" ),
 
  593    QStringLiteral( 
"Marcellus SC" ),
 
  594    QStringLiteral( 
"Marck Script" ),
 
  595    QStringLiteral( 
"Margarine" ),
 
  596    QStringLiteral( 
"Marko One" ),
 
  597    QStringLiteral( 
"Marmelad" ),
 
  598    QStringLiteral( 
"Martel" ),
 
  599    QStringLiteral( 
"Martel Sans" ),
 
  600    QStringLiteral( 
"Marvel" ),
 
  601    QStringLiteral( 
"Mate" ),
 
  602    QStringLiteral( 
"Mate SC" ),
 
  603    QStringLiteral( 
"Maven Pro" ),
 
  604    QStringLiteral( 
"McLaren" ),
 
  605    QStringLiteral( 
"Meddon" ),
 
  606    QStringLiteral( 
"MedievalSharp" ),
 
  607    QStringLiteral( 
"Medula One" ),
 
  608    QStringLiteral( 
"Megrim" ),
 
  609    QStringLiteral( 
"Meie Script" ),
 
  610    QStringLiteral( 
"Merienda" ),
 
  611    QStringLiteral( 
"Merienda One" ),
 
  612    QStringLiteral( 
"Merriweather" ),
 
  613    QStringLiteral( 
"Merriweather Sans" ),
 
  614    QStringLiteral( 
"Metal" ),
 
  615    QStringLiteral( 
"Metal Mania" ),
 
  616    QStringLiteral( 
"Metamorphous" ),
 
  617    QStringLiteral( 
"Metrophobic" ),
 
  618    QStringLiteral( 
"Michroma" ),
 
  619    QStringLiteral( 
"Milonga" ),
 
  620    QStringLiteral( 
"Miltonian" ),
 
  621    QStringLiteral( 
"Miltonian Tattoo" ),
 
  622    QStringLiteral( 
"Miniver" ),
 
  623    QStringLiteral( 
"Miss Fajardose" ),
 
  624    QStringLiteral( 
"Modak" ),
 
  625    QStringLiteral( 
"Modern Antiqua" ),
 
  626    QStringLiteral( 
"Molengo" ),
 
  627    QStringLiteral( 
"Molle" ),
 
  628    QStringLiteral( 
"Monda" ),
 
  629    QStringLiteral( 
"Monofett" ),
 
  630    QStringLiteral( 
"Monoton" ),
 
  631    QStringLiteral( 
"Monsieur La Doulaise" ),
 
  632    QStringLiteral( 
"Montaga" ),
 
  633    QStringLiteral( 
"Montez" ),
 
  634    QStringLiteral( 
"Montserrat" ),
 
  635    QStringLiteral( 
"Montserrat Alternates" ),
 
  636    QStringLiteral( 
"Montserrat Subrayada" ),
 
  637    QStringLiteral( 
"Moul" ),
 
  638    QStringLiteral( 
"Moulpali" ),
 
  639    QStringLiteral( 
"Mountains of Christmas" ),
 
  640    QStringLiteral( 
"Mouse Memoirs" ),
 
  641    QStringLiteral( 
"Mr Bedfort" ),
 
  642    QStringLiteral( 
"Mr Dafoe" ),
 
  643    QStringLiteral( 
"Mr De Haviland" ),
 
  644    QStringLiteral( 
"Mrs Saint Delafield" ),
 
  645    QStringLiteral( 
"Mrs Sheppards" ),
 
  646    QStringLiteral( 
"Mukta" ),
 
  647    QStringLiteral( 
"Muli" ),
 
  648    QStringLiteral( 
"Mystery Quest" ),
 
  649    QStringLiteral( 
"NTR" ),
 
  650    QStringLiteral( 
"Neucha" ),
 
  651    QStringLiteral( 
"Neuton" ),
 
  652    QStringLiteral( 
"New Rocker" ),
 
  653    QStringLiteral( 
"News Cycle" ),
 
  654    QStringLiteral( 
"Niconne" ),
 
  655    QStringLiteral( 
"Nixie One" ),
 
  656    QStringLiteral( 
"Nobile" ),
 
  657    QStringLiteral( 
"Nokora" ),
 
  658    QStringLiteral( 
"Norican" ),
 
  659    QStringLiteral( 
"Nosifer" ),
 
  660    QStringLiteral( 
"Nothing You Could Do" ),
 
  661    QStringLiteral( 
"Noticia Text" ),
 
  662    QStringLiteral( 
"Noto Sans" ),
 
  663    QStringLiteral( 
"Noto Sans Japanese" ),
 
  664    QStringLiteral( 
"Noto Sans Korean" ),
 
  665    QStringLiteral( 
"Noto Serif" ),
 
  666    QStringLiteral( 
"Nova Cut" ),
 
  667    QStringLiteral( 
"Nova Flat" ),
 
  668    QStringLiteral( 
"Nova Mono" ),
 
  669    QStringLiteral( 
"Nova Oval" ),
 
  670    QStringLiteral( 
"Nova Round" ),
 
  671    QStringLiteral( 
"Nova Script" ),
 
  672    QStringLiteral( 
"Nova Slim" ),
 
  673    QStringLiteral( 
"Nova Square" ),
 
  674    QStringLiteral( 
"Numans" ),
 
  675    QStringLiteral( 
"Nunito" ),
 
  676    QStringLiteral( 
"Nunito Sans" ),
 
  677    QStringLiteral( 
"Odor Mean Chey" ),
 
  678    QStringLiteral( 
"Offside" ),
 
  679    QStringLiteral( 
"Old Standard TT" ),
 
  680    QStringLiteral( 
"Oldenburg" ),
 
  681    QStringLiteral( 
"Oleo Script" ),
 
  682    QStringLiteral( 
"Oleo Script Swash Caps" ),
 
  683    QStringLiteral( 
"Open Sans" ),
 
  684    QStringLiteral( 
"Open Sans Condensed" ),
 
  685    QStringLiteral( 
"Oranienbaum" ),
 
  686    QStringLiteral( 
"Orbitron" ),
 
  687    QStringLiteral( 
"Oregano" ),
 
  688    QStringLiteral( 
"Orienta" ),
 
  689    QStringLiteral( 
"Original Surfer" ),
 
  690    QStringLiteral( 
"Oswald" ),
 
  691    QStringLiteral( 
"Over the Rainbow" ),
 
  692    QStringLiteral( 
"Overlock" ),
 
  693    QStringLiteral( 
"Overlock SC" ),
 
  694    QStringLiteral( 
"Ovo" ),
 
  695    QStringLiteral( 
"Oxygen" ),
 
  696    QStringLiteral( 
"Oxygen Mono" ),
 
  697    QStringLiteral( 
"PT Mono" ),
 
  698    QStringLiteral( 
"PT Sans" ),
 
  699    QStringLiteral( 
"PT Sans Caption" ),
 
  700    QStringLiteral( 
"PT Sans Narrow" ),
 
  701    QStringLiteral( 
"PT Serif" ),
 
  702    QStringLiteral( 
"PT Serif Caption" ),
 
  703    QStringLiteral( 
"Pacifico" ),
 
  704    QStringLiteral( 
"Palanquin" ),
 
  705    QStringLiteral( 
"Palanquin Dark" ),
 
  706    QStringLiteral( 
"Paprika" ),
 
  707    QStringLiteral( 
"Parisienne" ),
 
  708    QStringLiteral( 
"Passero One" ),
 
  709    QStringLiteral( 
"Passion One" ),
 
  710    QStringLiteral( 
"Pathway Gothic One" ),
 
  711    QStringLiteral( 
"Patrick Hand" ),
 
  712    QStringLiteral( 
"Patrick Hand SC" ),
 
  713    QStringLiteral( 
"Patua One" ),
 
  714    QStringLiteral( 
"Paytone One" ),
 
  715    QStringLiteral( 
"Peddana" ),
 
  716    QStringLiteral( 
"Peralta" ),
 
  717    QStringLiteral( 
"Permanent Marker" ),
 
  718    QStringLiteral( 
"Petit Formal Script" ),
 
  719    QStringLiteral( 
"Petrona" ),
 
  720    QStringLiteral( 
"Philosopher" ),
 
  721    QStringLiteral( 
"Piedra" ),
 
  722    QStringLiteral( 
"Pinyon Script" ),
 
  723    QStringLiteral( 
"Pirata One" ),
 
  724    QStringLiteral( 
"Plaster" ),
 
  725    QStringLiteral( 
"Play" ),
 
  726    QStringLiteral( 
"Playball" ),
 
  727    QStringLiteral( 
"Playfair Display" ),
 
  728    QStringLiteral( 
"Playfair Display SC" ),
 
  729    QStringLiteral( 
"Podkova" ),
 
  730    QStringLiteral( 
"Poiret One" ),
 
  731    QStringLiteral( 
"Poller One" ),
 
  732    QStringLiteral( 
"Poly" ),
 
  733    QStringLiteral( 
"Pompiere" ),
 
  734    QStringLiteral( 
"Pontano Sans" ),
 
  735    QStringLiteral( 
"Poppins" ),
 
  736    QStringLiteral( 
"Port Lligat Sans" ),
 
  737    QStringLiteral( 
"Port Lligat Slab" ),
 
  738    QStringLiteral( 
"Pragati Narrow" ),
 
  739    QStringLiteral( 
"Prata" ),
 
  740    QStringLiteral( 
"Preahvihear" ),
 
  741    QStringLiteral( 
"Press Start 2P" ),
 
  742    QStringLiteral( 
"Princess Sofia" ),
 
  743    QStringLiteral( 
"Prociono" ),
 
  744    QStringLiteral( 
"Prosto One" ),
 
  745    QStringLiteral( 
"Puritan" ),
 
  746    QStringLiteral( 
"Purple Purse" ),
 
  747    QStringLiteral( 
"Quando" ),
 
  748    QStringLiteral( 
"Quantico" ),
 
  749    QStringLiteral( 
"Quattrocento" ),
 
  750    QStringLiteral( 
"Quattrocento Sans" ),
 
  751    QStringLiteral( 
"Questrial" ),
 
  752    QStringLiteral( 
"Quicksand" ),
 
  753    QStringLiteral( 
"Quintessential" ),
 
  754    QStringLiteral( 
"Qwigley" ),
 
  755    QStringLiteral( 
"Racing Sans One" ),
 
  756    QStringLiteral( 
"Radley" ),
 
  757    QStringLiteral( 
"Rajdhani" ),
 
  758    QStringLiteral( 
"Raleway" ),
 
  759    QStringLiteral( 
"Raleway Dots" ),
 
  760    QStringLiteral( 
"Ramabhadra" ),
 
  761    QStringLiteral( 
"Ramaraja" ),
 
  762    QStringLiteral( 
"Rambla" ),
 
  763    QStringLiteral( 
"Rammetto One" ),
 
  764    QStringLiteral( 
"Ranchers" ),
 
  765    QStringLiteral( 
"Rancho" ),
 
  766    QStringLiteral( 
"Ranga" ),
 
  767    QStringLiteral( 
"Rationale" ),
 
  768    QStringLiteral( 
"Ravi Prakash" ),
 
  769    QStringLiteral( 
"Redressed" ),
 
  770    QStringLiteral( 
"Reenie Beanie" ),
 
  771    QStringLiteral( 
"Revalia" ),
 
  772    QStringLiteral( 
"Ribeye" ),
 
  773    QStringLiteral( 
"Ribeye Marrow" ),
 
  774    QStringLiteral( 
"Righteous" ),
 
  775    QStringLiteral( 
"Risque" ),
 
  776    QStringLiteral( 
"Roboto" ),
 
  777    QStringLiteral( 
"Roboto Condensed" ),
 
  778    QStringLiteral( 
"Roboto Mono" ),
 
  779    QStringLiteral( 
"Roboto Slab" ),
 
  780    QStringLiteral( 
"Rochester" ),
 
  781    QStringLiteral( 
"Rock Salt" ),
 
  782    QStringLiteral( 
"Rokkitt" ),
 
  783    QStringLiteral( 
"Romanesco" ),
 
  784    QStringLiteral( 
"Ropa Sans" ),
 
  785    QStringLiteral( 
"Rosario" ),
 
  786    QStringLiteral( 
"Rosarivo" ),
 
  787    QStringLiteral( 
"Rouge Script" ),
 
  788    QStringLiteral( 
"Rozha One" ),
 
  789    QStringLiteral( 
"Rubik" ),
 
  790    QStringLiteral( 
"Rubik Mono One" ),
 
  791    QStringLiteral( 
"Rubik One" ),
 
  792    QStringLiteral( 
"Ruda" ),
 
  793    QStringLiteral( 
"Rufina" ),
 
  794    QStringLiteral( 
"Ruge Boogie" ),
 
  795    QStringLiteral( 
"Ruluko" ),
 
  796    QStringLiteral( 
"Rum Raisin" ),
 
  797    QStringLiteral( 
"Ruslan Display" ),
 
  798    QStringLiteral( 
"Russo One" ),
 
  799    QStringLiteral( 
"Ruthie" ),
 
  800    QStringLiteral( 
"Rye" ),
 
  801    QStringLiteral( 
"Sacramento" ),
 
  802    QStringLiteral( 
"Sail" ),
 
  803    QStringLiteral( 
"Salsa" ),
 
  804    QStringLiteral( 
"Sanchez" ),
 
  805    QStringLiteral( 
"Sancreek" ),
 
  806    QStringLiteral( 
"Sansita One" ),
 
  807    QStringLiteral( 
"Sarabun" ),
 
  808    QStringLiteral( 
"Sarina" ),
 
  809    QStringLiteral( 
"Sarpanch" ),
 
  810    QStringLiteral( 
"Satisfy" ),
 
  811    QStringLiteral( 
"Scada" ),
 
  812    QStringLiteral( 
"Scheherazade" ),
 
  813    QStringLiteral( 
"Schoolbell" ),
 
  814    QStringLiteral( 
"Seaweed Script" ),
 
  815    QStringLiteral( 
"Sevillana" ),
 
  816    QStringLiteral( 
"Seymour One" ),
 
  817    QStringLiteral( 
"Shadows Into Light" ),
 
  818    QStringLiteral( 
"Shadows Into Light Two" ),
 
  819    QStringLiteral( 
"Shanti" ),
 
  820    QStringLiteral( 
"Share" ),
 
  821    QStringLiteral( 
"Share Tech" ),
 
  822    QStringLiteral( 
"Share Tech Mono" ),
 
  823    QStringLiteral( 
"Shojumaru" ),
 
  824    QStringLiteral( 
"Short Stack" ),
 
  825    QStringLiteral( 
"Siemreap" ),
 
  826    QStringLiteral( 
"Sigmar One" ),
 
  827    QStringLiteral( 
"Signika" ),
 
  828    QStringLiteral( 
"Signika Negative" ),
 
  829    QStringLiteral( 
"Simonetta" ),
 
  830    QStringLiteral( 
"Sintony" ),
 
  831    QStringLiteral( 
"Sirin Stencil" ),
 
  832    QStringLiteral( 
"Six Caps" ),
 
  833    QStringLiteral( 
"Skranji" ),
 
  834    QStringLiteral( 
"Slabo 13px" ),
 
  835    QStringLiteral( 
"Slabo 27px" ),
 
  836    QStringLiteral( 
"Slackey" ),
 
  837    QStringLiteral( 
"Smokum" ),
 
  838    QStringLiteral( 
"Smythe" ),
 
  839    QStringLiteral( 
"Sniglet" ),
 
  840    QStringLiteral( 
"Snippet" ),
 
  841    QStringLiteral( 
"Snowburst One" ),
 
  842    QStringLiteral( 
"Sofadi One" ),
 
  843    QStringLiteral( 
"Sofia" ),
 
  844    QStringLiteral( 
"Sonsie One" ),
 
  845    QStringLiteral( 
"Sorts Mill Goudy" ),
 
  846    QStringLiteral( 
"Source Code Pro" ),
 
  847    QStringLiteral( 
"Source Sans Pro" ),
 
  848    QStringLiteral( 
"Source Serif Pro" ),
 
  849    QStringLiteral( 
"Special Elite" ),
 
  850    QStringLiteral( 
"Spicy Rice" ),
 
  851    QStringLiteral( 
"Spinnaker" ),
 
  852    QStringLiteral( 
"Spirax" ),
 
  853    QStringLiteral( 
"Squada One" ),
 
  854    QStringLiteral( 
"Sree Krushnadevaraya" ),
 
  855    QStringLiteral( 
"Stalemate" ),
 
  856    QStringLiteral( 
"Stalinist One" ),
 
  857    QStringLiteral( 
"Stardos Stencil" ),
 
  858    QStringLiteral( 
"Stint Ultra Condensed" ),
 
  859    QStringLiteral( 
"Stint Ultra Expanded" ),
 
  860    QStringLiteral( 
"Stoke" ),
 
  861    QStringLiteral( 
"Strait" ),
 
  862    QStringLiteral( 
"Sue Ellen Francisco" ),
 
  863    QStringLiteral( 
"Sunshiney" ),
 
  864    QStringLiteral( 
"Supermercado One" ),
 
  865    QStringLiteral( 
"Suranna" ),
 
  866    QStringLiteral( 
"Suravaram" ),
 
  867    QStringLiteral( 
"Suwannaphum" ),
 
  868    QStringLiteral( 
"Swanky and Moo Moo" ),
 
  869    QStringLiteral( 
"Syncopate" ),
 
  870    QStringLiteral( 
"Tangerine" ),
 
  871    QStringLiteral( 
"Taprom" ),
 
  872    QStringLiteral( 
"Tauri" ),
 
  873    QStringLiteral( 
"Teko" ),
 
  874    QStringLiteral( 
"Telex" ),
 
  875    QStringLiteral( 
"Tenali Ramakrishna" ),
 
  876    QStringLiteral( 
"Tenor Sans" ),
 
  877    QStringLiteral( 
"Text Me One" ),
 
  878    QStringLiteral( 
"The Girl Next Door" ),
 
  879    QStringLiteral( 
"Tienne" ),
 
  880    QStringLiteral( 
"Timmana" ),
 
  881    QStringLiteral( 
"Tinos" ),
 
  882    QStringLiteral( 
"Titan One" ),
 
  883    QStringLiteral( 
"Titillium Web" ),
 
  884    QStringLiteral( 
"Trade Winds" ),
 
  885    QStringLiteral( 
"Trocchi" ),
 
  886    QStringLiteral( 
"Trochut" ),
 
  887    QStringLiteral( 
"Trykker" ),
 
  888    QStringLiteral( 
"Tulpen One" ),
 
  889    QStringLiteral( 
"Ubuntu" ),
 
  890    QStringLiteral( 
"Ubuntu Condensed" ),
 
  891    QStringLiteral( 
"Ubuntu Mono" ),
 
  892    QStringLiteral( 
"Ultra" ),
 
  893    QStringLiteral( 
"Uncial Antiqua" ),
 
  894    QStringLiteral( 
"Underdog" ),
 
  895    QStringLiteral( 
"Unica One" ),
 
  896    QStringLiteral( 
"UnifrakturCook" ),
 
  897    QStringLiteral( 
"UnifrakturMaguntia" ),
 
  898    QStringLiteral( 
"Unkempt" ),
 
  899    QStringLiteral( 
"Unlock" ),
 
  900    QStringLiteral( 
"Unna" ),
 
  901    QStringLiteral( 
"VT323" ),
 
  902    QStringLiteral( 
"Vampiro One" ),
 
  903    QStringLiteral( 
"Varela" ),
 
  904    QStringLiteral( 
"Varela Round" ),
 
  905    QStringLiteral( 
"Vast Shadow" ),
 
  906    QStringLiteral( 
"Vesper Libre" ),
 
  907    QStringLiteral( 
"Vibur" ),
 
  908    QStringLiteral( 
"Vidaloka" ),
 
  909    QStringLiteral( 
"Viga" ),
 
  910    QStringLiteral( 
"Voces" ),
 
  911    QStringLiteral( 
"Volkhov" ),
 
  912    QStringLiteral( 
"Vollkorn" ),
 
  913    QStringLiteral( 
"Voltaire" ),
 
  914    QStringLiteral( 
"Waiting for the Sunrise" ),
 
  915    QStringLiteral( 
"Wallpoet" ),
 
  916    QStringLiteral( 
"Walter Turncoat" ),
 
  917    QStringLiteral( 
"Warnes" ),
 
  918    QStringLiteral( 
"Wellfleet" ),
 
  919    QStringLiteral( 
"Wendy One" ),
 
  920    QStringLiteral( 
"Wire One" ),
 
  921    QStringLiteral( 
"Yanone Kaffeesatz" ),
 
  922    QStringLiteral( 
"Yellowtail" ),
 
  923    QStringLiteral( 
"Yeseva One" ),
 
  924    QStringLiteral( 
"Yesteryear" ),
 
  925    QStringLiteral( 
"Zeyada" ),
 
  928  auto cleanFontFamily = []( 
const QString & family ) -> QString
 
  930    const thread_local QRegularExpression charsToRemove( QStringLiteral( 
"[^a-z]" ) );
 
  931    const thread_local QRegularExpression styleNames( QStringLiteral( 
"(?:normal|regular|light|bold|black|demi|italic|oblique|medium|thin)" ) );
 
  933    QString processed = family.toLower();
 
  934    processed.replace( styleNames, QString() );
 
  935    return processed.replace( charsToRemove, QString() );
 
  938  matchedFamily.clear();
 
  939  const QString cleanedFamily = cleanFontFamily( family );
 
  940  for ( 
const QString &candidate : sGoogleFonts )
 
  942    if ( cleanFontFamily( candidate ) == cleanedFamily )
 
  944      QString paramName = candidate;
 
  945      paramName.replace( 
' ', 
'+' );
 
  946      matchedFamily = candidate;
 
  947      return QStringLiteral( 
"https://fonts.google.com/download?family=%1" ).arg( paramName );
 
  956  if ( identifier.isEmpty() )
 
  958    description = tr( 
"Installing fonts from %1" ).arg( url.toString() );
 
  962    description = tr( 
"Installing %1" ).arg( identifier );
 
  968    if ( task->
reply()->error() != QNetworkReply::NoError )
 
  970      emit fontDownloadErrorOccurred( url, identifier, task->reply()->errorString() );
 
  974      QString errorMessage;
 
  975      QStringList families;
 
  976      QString licenseDetails;
 
  977      if ( installFontsFromData( task->reply()->readAll(), errorMessage, families, licenseDetails, task->contentDispositionFilename() ) )
 
  979        QgsReadWriteLocker locker( mReplacementLock, QgsReadWriteLocker::Write );
 
  980        mPendingFontDownloads.remove( identifier );
 
  983        emit fontDownloaded( families, licenseDetails );
 
  987        QgsReadWriteLocker locker( mReplacementLock, QgsReadWriteLocker::Write );
 
  988        mPendingFontDownloads.remove( identifier );
 
  991        emit fontDownloadErrorOccurred( url, identifier, errorMessage );
 
 1000  errorMessage.clear();
 
 1002  licenseDetails.clear();
 
 1004  QTemporaryFile tempFile;
 
 1005  QTemporaryDir tempDir;
 
 1011  const QDir fontsDir( userFontsDir );
 
 1013  if ( !tempFile.open() )
 
 1015    errorMessage = tr( 
"Could not write font data to a temporary file" );
 
 1019  tempFile.write( data );
 
 1022  QString sourcePath = tempFile.fileName();
 
 1025  int id = QFontDatabase::addApplicationFont( sourcePath );
 
 1029    const QStringList foundFamilies = QFontDatabase::applicationFontFamilies( 
id );
 
 1031    QFontDatabase::removeApplicationFont( 
id );
 
 1033    if ( foundFamilies.empty() )
 
 1035      errorMessage = tr( 
"Could not find any families in font" );
 
 1039    QgsDebugMsgLevel( QStringLiteral( 
"Found fonts %1" ).arg( foundFamilies.join( 
',' ) ), 2 );
 
 1040    families = foundFamilies;
 
 1042    const QString family = families.at( 0 );
 
 1043    const QString destPath = fontsDir.filePath( filename.isEmpty() ? family : filename );
 
 1044    if ( !QFile::copy( sourcePath, destPath ) )
 
 1046      errorMessage = tr( 
"Could not copy font to %1" ).arg( destPath );
 
 1050    id = QFontDatabase::addApplicationFont( destPath );
 
 1053      errorMessage = tr( 
"Could not install font from %1" ).arg( destPath );
 
 1059      mUserFontToFamilyMap.insert( destPath, foundFamilies );
 
 1060      mUserFontToIdMap.insert( destPath, 
id );
 
 1071      for ( 
const QString &file : std::as_const( 
files ) )
 
 1073        const QFileInfo fi( file );
 
 1074        if ( fi.fileName().compare( QLatin1String( 
"OFL.txt" ), Qt::CaseInsensitive ) == 0
 
 1075             || fi.fileName().compare( QLatin1String( 
"LICENSE.txt" ), Qt::CaseInsensitive ) == 0 )
 
 1077          QFile licenseFile( file );
 
 1078          if ( licenseFile.open( QIODevice::ReadOnly ) )
 
 1080            QTextStream in( &licenseFile );
 
 1081            const QString license = in.readAll();
 
 1082            licenseDetails.append( license );
 
 1085        else if ( fi.suffix().compare( QLatin1String( 
"ttf" ), Qt::CaseInsensitive ) == 0 ||
 
 1086                  fi.suffix().compare( QLatin1String( 
"otf" ), Qt::CaseInsensitive ) == 0 )
 
 1089          id = QFontDatabase::addApplicationFont( sourcePath );
 
 1092            QFontDatabase::removeApplicationFont( 
id );
 
 1093            const QString destPath = fontsDir.filePath( fi.fileName() );
 
 1095            if ( !QFile::exists( destPath ) && !QFile::copy( sourcePath, destPath ) )
 
 1097              errorMessage = tr( 
"Could not copy font to %1" ).arg( destPath );
 
 1100            id = QFontDatabase::addApplicationFont( destPath );
 
 1103              errorMessage = tr( 
"Could not install font from %1" ).arg( destPath );
 
 1106            const QStringList foundFamilies = QFontDatabase::applicationFontFamilies( 
id );
 
 1107            mUserFontToFamilyMap.insert( destPath, foundFamilies );
 
 1108            mUserFontToIdMap.insert( destPath, 
id );
 
 1109            for ( 
const QString &found : foundFamilies )
 
 1111              if ( !families.contains( found ) )
 
 1121  errorMessage = tr( 
"Could not read fonts from data" );
 
 1128  if ( mUserFontDirectories.contains( directory ) )
 
 1132  mUserFontDirectories.append( directory );
 
 1135  if ( !QFile::exists( directory ) && !QDir().mkpath( directory ) )
 
 1137    QgsDebugError( QStringLiteral( 
"Cannot create local fonts dir: %1" ).arg( directory ) );
 
 1141  installFontsFromDirectory( directory );
 
 1147  return mUserFontToFamilyMap;
 
 1153  const int id = mUserFontToIdMap.value( path, -1 );
 
 1155    QFontDatabase::removeApplicationFont( 
id );
 
 1156  QFile::remove( path );
 
 1157  mUserFontToIdMap.remove( path );
 
 1158  mUserFontToFamilyMap.remove( path );
 
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...
 
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.
 
CORE_EXPORT const QStringList files(const QString &zip)
Returns the list of files within a zip file.
 
#define QgsDebugMsgLevel(str, level)
 
#define QgsDebugError(str)