50bool QFontIconEngine::isNull()
52 const QString text = string();
53 if (!text.isEmpty()) {
54 const QChar c0 = text.at(0);
55 const QFontMetrics fontMetrics(m_iconFont);
56 if (c0.isHighSurrogate() && text.size() > 1)
57 return !fontMetrics.inFontUcs4(QChar::surrogateToUcs4(c0, text.at(1)));
58 return !fontMetrics.inFont(c0);
64QList<QSize> QFontIconEngine::availableSizes(QIcon::Mode, QIcon::State)
66 return {{16, 16}, {24, 24}, {48, 48}, {128, 128}};
69QSize QFontIconEngine::actualSize(
const QSize &size, QIcon::Mode mode, QIcon::State state)
72 return QIconEngine::actualSize(size, mode, state);
74 QFont renderFont(m_iconFont);
75 renderFont.setPixelSize(size.height());
77 if (
const glyph_t glyphIndex = glyph()) {
78 QFontEngine *engine = QFontPrivate::get(renderFont)->engineForScript(QChar::Script_Common);
80 const glyph_metrics_t gm = engine->boundingBox(glyphIndex);
81 const qreal glyph_x = gm.x.toReal();
82 const qreal glyph_y = gm.y.toReal();
83 const qreal glyph_width = (gm.x + gm.width).toReal() - glyph_x;
84 const qreal glyph_height = (gm.y + gm.height).toReal() - glyph_y;
86 if (glyph_width > .0 && glyph_height > .0)
87 result = {glyph_width, glyph_height};
88 }
else if (
const QString text = string(); !text.isEmpty()) {
89 const QFontMetricsF fm(renderFont);
90 result = {fm.horizontalAdvance(text), fm.tightBoundingRect(text).height()};
92 if (!result.isValid())
93 return QIconEngine::actualSize(size, mode, state);
95 return result.scaled(size, Qt::KeepAspectRatio).toSize();
98QPixmap QFontIconEngine::pixmap(
const QSize &size, QIcon::Mode mode, QIcon::State state)
100 return scaledPixmap(size, mode, state, 1.0);
103QPixmap QFontIconEngine::scaledPixmap(
const QSize &size, QIcon::Mode mode, QIcon::State state, qreal scale)
105 const quint64 cacheKey = calculateCacheKey(mode, state);
106 const QSize fittingSize = actualSize(size, mode, state);
107 if (cacheKey != m_pixmapCacheKey || m_pixmap.deviceIndependentSize() != fittingSize
108 || m_pixmap.devicePixelRatio() != scale) {
109 m_pixmap = QPixmap(fittingSize * scale);
110 m_pixmap.fill(Qt::transparent);
111 m_pixmap.setDevicePixelRatio(scale);
113 if (!m_pixmap.isNull()) {
114 QPainter painter(&m_pixmap);
115 paint(&painter, QRect(QPoint(), fittingSize), mode, state);
118 m_pixmapCacheKey = cacheKey;
124void QFontIconEngine::paint(QPainter *painter,
const QRect &rect, QIcon::Mode mode, QIcon::State state)
129 QFont renderFont(m_iconFont);
130 renderFont.setPixelSize(rect.height());
132 QColor color = Qt::black;
136 color = palette.color(QPalette::Active, QPalette::Text);
139 color = palette.color(QPalette::Active, QPalette::Text);
141 case QIcon::Disabled:
142 color = palette.color(QPalette::Disabled, QPalette::Text);
144 case QIcon::Selected:
145 color = palette.color(QPalette::Active, QPalette::HighlightedText);
149 if (glyph_t glyphIndex = glyph()) {
150 QFontEngine *engine = QFontPrivate::get(renderFont)->engineForScript(QChar::Script_Common);
152 const glyph_metrics_t gm = engine->boundingBox(glyphIndex);
153 const int glyph_x = qFloor(gm.x.toReal());
154 const int glyph_y = qFloor(gm.y.toReal());
155 const int glyph_width = qCeil((gm.x + gm.width).toReal()) - glyph_x;
156 const int glyph_height = qCeil((gm.y + gm.height).toReal()) - glyph_y;
158 if (glyph_width > 0 && glyph_height > 0) {
159 QFixedPoint pt(QFixed(-glyph_x), QFixed(-glyph_y));
161 path.setFillRule(Qt::WindingFill);
162 engine->addGlyphsToPath(&glyphIndex, &pt, 1, &path, {});
164 const QRectF pathBoundingRect = path.boundingRect();
166 const QPointF topLeft = rect.topLeft() - pathBoundingRect.topLeft()
167 + (QPointF(rect.width(), rect.height())
168 - QPointF(pathBoundingRect.width(), pathBoundingRect.height())) / 2;
169 painter->translate(topLeft);
171 painter->setRenderHint(QPainter::Antialiasing);
172 painter->setPen(Qt::NoPen);
173 painter->setBrush(color);
174 painter->drawPath(path);
176 }
else if (
const QString text = string(); !text.isEmpty()) {
177 painter->setFont(renderFont);
178 painter->setPen(color);
179 painter->drawText(rect, Qt::AlignCenter, text);
189glyph_t QFontIconEngine::glyph()
const
191 if (m_glyph == uninitializedGlyph) {
192 QFontEngine *engine = QFontPrivate::get(m_iconFont)->engineForScript(QChar::Script_Common);
194 m_glyph = engine->findGlyph(QLatin1StringView(m_iconName.toLatin1()));
198 QTextLayout layout(m_iconName, m_iconFont);
199 layout.beginLayout();
202 const auto glyphRuns = layout.glyphRuns();
203 if (glyphRuns.size() == 1) {
204 const auto glyphIndexes = glyphRuns.first().glyphIndexes();
205 if (glyphIndexes.size() == 1)
206 m_glyph = glyphIndexes.first();