Qt ForkAwesome 0.2.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 <QFontDatabase>
6#include <QGuiApplication>
7#include <QHash>
8#include <QIcon>
9#include <QPaintDevice>
10#include <QPainter>
11
13namespace QtForkAwesome {
14
16
17struct IconOverride {
18 void setIcon(const QIcon &icon);
19 void addIconName(const QString &iconName);
20 const QIcon &locateIcon();
21
22private:
23 QStringList iconNames;
24 QIcon cachedIcon;
25};
26
27void IconOverride::setIcon(const QIcon &icon)
28{
29 iconNames.clear();
30 cachedIcon = icon;
31}
32
33void IconOverride::addIconName(const QString &iconName)
34{
35 iconNames.append(iconName);
36 if (!cachedIcon.isNull()) {
37 cachedIcon = QIcon();
38 }
39}
40
41const QIcon &IconOverride::locateIcon()
42{
43 if (!cachedIcon.isNull()) {
44 return cachedIcon;
45 }
46 for (const auto &iconName : iconNames) {
47 cachedIcon = QIcon::fromTheme(iconName);
48 if (!cachedIcon.isNull()) {
49 return cachedIcon;
50 }
51 }
52 return cachedIcon;
53}
54
55struct Renderer::InternalData {
56 explicit InternalData(int id);
57 static constexpr int invalidId = -1;
58
59 int id;
60 QStringList fontFamilies;
61 QHash<QChar, IconOverride> overrides;
62 QPaintDevice *paintDevice;
63};
64
65Renderer::InternalData::InternalData(int id)
66 : id(id)
67 , fontFamilies(id != invalidId ? QFontDatabase::applicationFontFamilies(id) : QStringList())
68 , paintDevice(nullptr)
69{
70}
71
73
84Renderer::Renderer(const QString &fontFileName)
85 : m_d(std::make_unique<InternalData>(
86 QFontDatabase::addApplicationFont(fontFileName.isEmpty() ? QStringLiteral(":/" META_FONT_FILE_NAME) : fontFileName)))
87{
88}
89
93Renderer::Renderer(const QByteArray &fontData)
94 : m_d(std::make_unique<InternalData>(QFontDatabase::addApplicationFont(fontData)))
95{
96}
97
102{
103 if (QCoreApplication::instance() && m_d->id != InternalData::invalidId) {
104 QFontDatabase::removeApplicationFont(m_d->id);
105 }
106}
107
111Renderer::operator bool() const
112{
113 return !m_d->fontFamilies.empty();
114}
115
117static void renderInternally(QChar character, QPainter *painter, QFont &&font, const QRect &rect, const QColor &color)
118{
119 font.setPixelSize(rect.height());
120 painter->save();
121 painter->setFont(font);
122 painter->setPen(color);
123 painter->drawText(rect, QString(character), QTextOption(Qt::AlignCenter));
124 painter->restore();
125}
127
131void QtForkAwesome::Renderer::render(QChar character, QPainter *painter, const QRect &rect, const QColor &color) const
132{
133 if (auto override = m_d->overrides.find(character); override != m_d->overrides.end()) {
134 if (const auto &overrideIcon = override->locateIcon(); !overrideIcon.isNull()) {
135 painter->drawPixmap(rect, overrideIcon.pixmap(rect.size(), QIcon::Normal, QIcon::On));
136 return;
137 }
138 }
139 if (*this) {
140 renderInternally(character, painter, QFont(m_d->fontFamilies.front()), rect, color);
141 }
142}
143
147QPixmap Renderer::pixmap(QChar icon, const QSize &size, const QColor &color, qreal scaleFactor) const
148{
149 if (auto override = m_d->overrides.find(icon); override != m_d->overrides.end()) {
150 if (const auto &overrideIcon = override->locateIcon(); !overrideIcon.isNull()) {
151 return overrideIcon.pixmap(size, QIcon::Normal, QIcon::On);
152 }
153 }
154
155 if (!scaleFactor) {
156 scaleFactor =
157#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
158 !QCoreApplication::testAttribute(Qt::AA_UseHighDpiPixmaps)
159 ? 1.0
160 :
161#endif
162 (m_d->paintDevice ? m_d->paintDevice->devicePixelRatioF() : qGuiApp->devicePixelRatio());
163 }
164
165 const auto scaledSize = QSize(size * scaleFactor);
166 auto pm = QPixmap(scaledSize);
167 pm.fill(QColor(Qt::transparent));
168 if (*this) {
169 auto painter = QPainter(&pm);
170 renderInternally(icon, &painter, QFont(m_d->fontFamilies.front()), QRect(QPoint(), scaledSize), color);
171 }
172 pm.setDevicePixelRatio(scaleFactor);
173 return pm;
174}
175
179QPixmap Renderer::pixmap(Icon icon, const QSize &size, const QColor &color, qreal scaleFactor) const
180{
181 return pixmap(QChar(static_cast<IconBaseType>(icon)), size, color, scaleFactor);
182}
183
192QPixmap QtForkAwesome::Renderer::pixmap(QChar icon, const QSize &size, const QColor &color) const
193{
194 return pixmap(icon, size, color, 0.0);
195}
196
205QPixmap Renderer::pixmap(Icon icon, const QSize &size, const QColor &color) const
206{
207 return pixmap(QChar(static_cast<IconBaseType>(icon)), size, color, 0.0);
208}
209
213void Renderer::addThemeOverride(QChar character, const QString &iconNameInTheme)
214{
215 m_d->overrides[character].addIconName(iconNameInTheme);
216}
217
221void Renderer::addOverride(QChar character, const QIcon &override)
222{
223 m_d->overrides[character].setIcon(override);
224}
225
230{
231 m_d->overrides.clear();
232}
233
240void Renderer::setAssociatedPaintDevice(QPaintDevice *paintDevice)
241{
242 m_d->paintDevice = paintDevice;
243}
244
249{
250 static auto globalRenderer = Renderer();
251 return globalRenderer;
252}
253
254} // namespace QtForkAwesome
Allows rendering a QtForkAwesome::Icon (or an arbitrary QChar using an arbitrary font file).
Definition renderer.h:22
Renderer(const QString &fontFileName=QString())
Constructs a new renderer with the given fontFileName.
Definition renderer.cpp:84
static Renderer & global()
Returns the global instance (which is so far only used by the icon engine plugin).
Definition renderer.cpp:248
void clearOverrides()
Clears all overrides added via addThemeOverride() or addOverride().
Definition renderer.cpp:229
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:213
void addOverride(QChar character, const QIcon &override)
Uses the specified override icon for character if it is not null.
Definition renderer.cpp:221
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:147
void setAssociatedPaintDevice(QPaintDevice *paintDevice)
Sets the associated paintDevice.
Definition renderer.cpp:240
~Renderer()
Destructs the renderer.
Definition renderer.cpp:101
void render(QChar character, QPainter *painter, const QRect &rect, const QColor &color) const
Renders the specified icon using the specified painter.
Definition renderer.cpp:131
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