Qt ForkAwesome 0.3.0
Library that bundles ForkAwesome for use within Qt applications
Loading...
Searching...
No Matches
renderer.cpp
Go to the documentation of this file.
1#include "./renderer.h"
2
3#include "resources/config.h"
4
5#include <QDebug>
6#include <QFile>
7#include <QFontDatabase>
8#include <QGuiApplication>
9#include <QHash>
10#include <QIcon>
11#include <QPaintDevice>
12#include <QPainter>
13
14#include <utility>
15
17namespace QtForkAwesome {
18
20
21struct IconOverride {
22 void setIcon(const QIcon &icon);
23 void addIconName(const QString &iconName);
24 const QIcon &locateIcon();
25
26private:
27 QStringList iconNames;
28 QIcon cachedIcon;
29};
30
31void IconOverride::setIcon(const QIcon &icon)
32{
33 iconNames.clear();
34 cachedIcon = icon;
35}
36
37void IconOverride::addIconName(const QString &iconName)
38{
39 iconNames.append(iconName);
40 if (!cachedIcon.isNull()) {
41 cachedIcon = QIcon();
42 }
43}
44
45const QIcon &IconOverride::locateIcon()
46{
47 if (!cachedIcon.isNull()) {
48 return cachedIcon;
49 }
50 for (const auto &iconName : std::as_const(iconNames)) {
51 cachedIcon = QIcon::fromTheme(iconName);
52 if (!cachedIcon.isNull()) {
53 return cachedIcon;
54 }
55 }
56 return cachedIcon;
57}
58
59struct Renderer::InternalData {
60 explicit InternalData(int id);
61 static constexpr int invalidId = -1;
62
63 int id;
64 QString fontFilePath;
65 QStringList fontFamilies;
66 QHash<QChar, IconOverride> overrides;
67 QPaintDevice *paintDevice;
68};
69
70Renderer::InternalData::InternalData(int id)
71 : id(id)
72 , fontFamilies(id != invalidId ? QFontDatabase::applicationFontFamilies(id) : QStringList())
73 , paintDevice(nullptr)
74{
75}
76
78
84
89Renderer::Renderer(const QString &fontFileName)
90 : m_d(std::make_unique<InternalData>(
91 QFontDatabase::addApplicationFont(fontFileName.isEmpty() ? QStringLiteral(":/" META_FONT_FILE_NAME) : fontFileName)))
92{
93}
94
98Renderer::Renderer(const QByteArray &fontData)
99 : m_d(std::make_unique<InternalData>(QFontDatabase::addApplicationFont(fontData)))
100{
101}
102
107{
108 if (QCoreApplication::instance() && m_d->id != InternalData::invalidId) {
109 QFontDatabase::removeApplicationFont(m_d->id);
110 }
111}
112
117const QString &Renderer::fontFilePath() const
118{
119 return m_d->fontFilePath;
120}
121
126{
127 if (!*this) {
128 const auto &path = m_d->fontFilePath;
129 if (!path.isEmpty() && !QFile::exists(path)) {
130 qWarning() << "ForkAwesome font file does not exist";
131 }
132 qWarning() << "Unable to load ForkAwesome font from " << (path.isEmpty() ? QStringLiteral("buffer") : path);
133 }
134}
135
139Renderer::operator bool() const
140{
141 return !m_d->fontFamilies.empty();
142}
143
145static void renderInternally(QChar character, QPainter *painter, QFont &&font, const QRect &rect, const QColor &color)
146{
147 font.setPixelSize(rect.height());
148 painter->save();
149 painter->setFont(font);
150 painter->setPen(color);
151 painter->drawText(rect, QString(character), QTextOption(Qt::AlignCenter));
152 painter->restore();
153}
155
159void QtForkAwesome::Renderer::render(QChar character, QPainter *painter, const QRect &rect, const QColor &color) const
160{
161 if (auto override = m_d->overrides.find(character); override != m_d->overrides.end()) {
162 if (const auto &overrideIcon = override->locateIcon(); !overrideIcon.isNull()) {
163 overrideIcon.paint(painter, rect, Qt::AlignCenter, QIcon::Normal, QIcon::On);
164 return;
165 }
166 }
167 if (*this) {
168 renderInternally(character, painter, QFont(m_d->fontFamilies.front()), rect, color);
169 }
170}
171
175QPixmap Renderer::pixmap(QChar icon, const QSize &size, const QColor &color, qreal scaleFactor) const
176{
177 if (auto override = m_d->overrides.find(icon); override != m_d->overrides.end()) {
178 if (const auto &overrideIcon = override->locateIcon(); !overrideIcon.isNull()) {
179 return overrideIcon.pixmap(size, QIcon::Normal, QIcon::On);
180 }
181 }
182
183 if (!static_cast<bool>(scaleFactor)) {
184 scaleFactor =
185#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
186 !QCoreApplication::testAttribute(Qt::AA_UseHighDpiPixmaps)
187 ? 1.0
188 :
189#endif
190 (m_d->paintDevice ? m_d->paintDevice->devicePixelRatioF() : qGuiApp->devicePixelRatio());
191 }
192
193 const auto scaledSize = QSize(size * scaleFactor);
194 auto pm = QPixmap(scaledSize);
195 pm.fill(QColor(Qt::transparent));
196 if (*this) {
197 auto painter = QPainter(&pm);
198 renderInternally(icon, &painter, QFont(m_d->fontFamilies.front()), QRect(QPoint(), scaledSize), color);
199 }
200 pm.setDevicePixelRatio(scaleFactor);
201 return pm;
202}
203
207QPixmap Renderer::pixmap(Icon icon, const QSize &size, const QColor &color, qreal scaleFactor) const
208{
209 return pixmap(QChar(static_cast<IconBaseType>(icon)), size, color, scaleFactor);
210}
211
220QPixmap QtForkAwesome::Renderer::pixmap(QChar icon, const QSize &size, const QColor &color) const
221{
222 return pixmap(icon, size, color, 0.0);
223}
224
233QPixmap Renderer::pixmap(Icon icon, const QSize &size, const QColor &color) const
234{
235 return pixmap(QChar(static_cast<IconBaseType>(icon)), size, color, 0.0);
236}
237
241void Renderer::addThemeOverride(QChar character, const QString &iconNameInTheme)
242{
243 m_d->overrides[character].addIconName(iconNameInTheme);
244}
245
249void Renderer::addOverride(QChar character, const QIcon &override)
250{
251 m_d->overrides[character].setIcon(override);
252}
253
258{
259 m_d->overrides.clear();
260}
261
268void Renderer::setAssociatedPaintDevice(QPaintDevice *paintDevice)
269{
270 m_d->paintDevice = paintDevice;
271}
272
277{
278 static auto globalRenderer = Renderer();
279 return globalRenderer;
280}
281
282} // namespace QtForkAwesome
Renderer(const QString &fontFileName=QString())
Constructs a new renderer with the given fontFileName.
Definition renderer.cpp:89
static Renderer & global()
Returns the global instance (which is so far only used by the icon engine plugin).
Definition renderer.cpp:276
const QString & fontFilePath() const
Returns the path of the font file.
Definition renderer.cpp:117
void clearOverrides()
Clears all overrides added via addThemeOverride() or addOverride().
Definition renderer.cpp:257
void addThemeOverride(QChar character, const QString &iconNameInTheme)
Uses the icon from the current icon theme obtained via QIcon::fromTheme() for character if it exists.
Definition renderer.cpp:241
void warnIfInvalid() const
Prints a warning using qWarning() if no font could be loaded.
Definition renderer.cpp:125
void addOverride(QChar character, const QIcon &override)
Uses the specified override icon for character if it is not null.
Definition renderer.cpp:249
QPixmap pixmap(QChar icon, const QSize &size, const QColor &color, qreal scaleFactor) const
Renders the specified character as pixmap of the specified size.
Definition renderer.cpp:175
void setAssociatedPaintDevice(QPaintDevice *paintDevice)
Sets the associated paintDevice.
Definition renderer.cpp:268
~Renderer()
Destructs the renderer.
Definition renderer.cpp:106
void render(QChar character, QPainter *painter, const QRect &rect, const QColor &color) const
Renders the specified icon using the specified painter.
Definition renderer.cpp:159
Contains classes provided by the QtForkAwesome library.
Definition renderer.h:20
Icon
The Icon enum specifies a ForkAwesome icon for calling QtForkAwesome::Renderer::render().
Definition icon.h:11
std::remove_reference_t< decltype(QChar().unicode())> IconBaseType
Definition iconfwd.h:10