1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 
3 /*
4     Rosegarden
5     A MIDI and audio sequencer and musical notation editor.
6     Copyright 2000-2021 the Rosegarden development team.
7 
8     Other copyrights also apply to some parts of this work.  Please
9     see the AUTHORS file and individual file headers for details.
10 
11     This program is free software; you can redistribute it and/or
12     modify it under the terms of the GNU General Public License as
13     published by the Free Software Foundation; either version 2 of the
14     License, or (at your option) any later version.  See the file
15     COPYING included with this distribution for more information.
16 */
17 
18 #define RG_MODULE_STRING "[SystemFont]"
19 
20 //#define RG_NO_DEBUG_PRINT 1
21 
22 // "qtextstream.h must be included before any header file that defines Status"
23 #include <QTextStream>
24 
25 // "qmetatype.h must be included before any header file that defines Bool"
26 #include <QMetaType>
27 
28 #include "misc/Debug.h"
29 #include "misc/Strings.h"
30 #include "base/Profiler.h"
31 #include "gui/general/ResourceFinder.h"
32 #include "NoteFontMap.h"
33 
34 #include <QFont>
35 #include <QFontInfo>
36 #include <QFontDatabase>
37 #include <QFileInfo>
38 #include <QPixmap>
39 #include <QSharedPointer>
40 #include <QString>
41 
42 #include "SystemFont.h"
43 #include "SystemFontQt.h"
44 
45 #include <iostream>
46 
47 
48 namespace Rosegarden
49 {
50 
~SystemFont()51 SystemFont::~SystemFont()
52 {}
53 
54 SystemFont *
loadSystemFont(const SystemFontSpec & spec)55 SystemFont::loadSystemFont(const SystemFontSpec &spec)
56 {
57     //Profiler profiler("SystemFont::loadSystemFont");
58 
59     QString name = spec.first;
60     int size = spec.second;
61 
62     RG_DEBUG << "loadSystemFont(): name is " << name << ", size " << size;
63 
64     if (name == "DEFAULT") {
65         QFont font;
66         font.setPixelSize(size);
67         return new SystemFontQt(font);
68     }
69 
70     static bool haveFonts = false;
71     if (!haveFonts) {
72         unbundleFonts();
73         haveFonts = true;
74     }
75 
76     static QHash<QString, QSharedPointer<QFont> > qFontMap;
77 
78     if (qFontMap.contains(name)) {
79         if (qFontMap[name] == nullptr) return nullptr;
80         QFont qfont(*qFontMap[name]);
81         qfont.setPixelSize(size);
82         return new SystemFontQt(qfont);
83     }
84 
85     QFont qfont(name, size, QFont::Normal);
86     qfont.setPixelSize(size);
87 
88     QFontInfo info(qfont);
89 
90     RG_DEBUG << "loadSystemFont(): [Qt]: wanted family " << name << " at size " << size << ", got family " << info.family() << " (exactMatch " << info.exactMatch() << ")";
91 
92     QString family = info.family().toLower();
93 
94     if (family == name.toLower()) {
95         qFontMap[name].reset(new QFont(qfont));
96         return new SystemFontQt(qfont);
97     } else {
98         int bracket = family.indexOf(" [");
99         if (bracket > 1) family = family.left(bracket);
100         if (family == name.toLower()) {
101             qFontMap[name].reset(new QFont(qfont));
102             return new SystemFontQt(qfont);
103         }
104     }
105 
106     RG_DEBUG << "loadSystemFont(): [Qt]: Wrong family returned, failing";
107     qFontMap[name] = {};
108     return nullptr;
109 }
110 
111 void
unbundleFonts()112 SystemFont::unbundleFonts()
113 {
114     QStringList fontFiles;
115     fontFiles << ResourceFinder().getResourceFiles("fonts", "pfa");
116     fontFiles << ResourceFinder().getResourceFiles("fonts", "pfb");
117     fontFiles << ResourceFinder().getResourceFiles("fonts", "ttf");
118     fontFiles << ResourceFinder().getResourceFiles("fonts", "otf");
119 
120     RG_DEBUG << "unbundleFonts(): Found font files: " << fontFiles;
121 
122     for (QStringList::const_iterator i = fontFiles.constBegin();
123          i != fontFiles.constEnd(); ++i) {
124         QString fontFile(*i);
125         QString name = QFileInfo(fontFile).fileName();
126         if (fontFile.startsWith(":")) {
127             ResourceFinder().unbundleResource("fonts", name);
128             fontFile = ResourceFinder().getResourcePath("fonts", name);
129             if (fontFile.startsWith(":")) { // unbundling failed
130                 continue;
131             }
132         }
133         addFont(fontFile);
134     }
135 }
136 
137 void
addFont(QString fileName)138 SystemFont::addFont(QString fileName)
139 {
140     QFontDatabase::addApplicationFont(fileName);
141     RG_DEBUG << "addFont(): Added font file" << fileName << "to Qt font database";
142 }
143 
144 }
145