/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3 as published by the Free Software ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include #include #include #include #include #include static const int lastMeasurementsCount = 50; class FontBlaster: public QWidget { Q_OBJECT public: FontBlaster(QWidget *parent = 0) : QWidget(parent) , m_currentMode(0) { setFocusPolicy(Qt::StrongFocus); } void paintEvent(QPaintEvent *event) { Q_UNUSED(event); QPainter p(this); if (!m_timer.isNull()) m_lastMeasurements.append(m_timer.elapsed()); m_timer.start(); p.save(); m_modes[m_currentMode].function(p, size()); p.restore(); const QFontMetrics fm = p.fontMetrics(); p.setOpacity(0.7); p.fillRect(0, 0, width(), fm.height(), Qt::gray); p.fillRect(0, height() - fm.height(), width(), height(), Qt::gray); p.setOpacity(1); p.setPen(palette().color(QPalette::Text)); p.drawText(2, fm.ascent(), m_modes[m_currentMode].name); if (m_lastMeasurements.count() == lastMeasurementsCount) { m_lastMeasurements.removeFirst(); int lastMsecsSum = 0; foreach(const int measurement, m_lastMeasurements) lastMsecsSum += measurement; p.drawText(2, height() - fm.descent(), QLatin1String("Fps: ") + QString::number(1000 / ((qreal)lastMsecsSum / lastMeasurementsCount), 'f', 1) ); } QTimer::singleShot(0, this, SLOT(repaint())); } /* Creating all kinds of size/weight/italic combinations, stress testing the glyph cache. Also: painting with different opacities, stress testing blitting. */ static void paintDifferentFontStyles(QPainter &p, const QSize &size) { static const QString text = QLatin1String("Qt rocks!!!"); static const int textsPerPaint = 30; for (int i = 0; i < textsPerPaint; i++) { const int fontSize = 4 + QRandomGenerator::global()->bounded(5); const int fontWeight = QRandomGenerator::global()->bounded(2) == 1 ? QFont::Normal : QFont::Bold; const bool fontItalic = QRandomGenerator::global()->bounded(2) == 1; const QFont font("Default", fontSize, fontWeight, fontItalic); p.setFont(font); p.setPen(QColor::fromHsv(QRandomGenerator::global()->bounded(359), 155 + QRandomGenerator::global()->bounded(100), 155 + QRandomGenerator::global()->bounded(100), 100 + QRandomGenerator::global()->bounded(155))); const QSize textSize(p.fontMetrics().boundingRect(text).size()); const QPoint position( -textSize.width() / 2 + QRandomGenerator::global()->bounded(size.width()), textSize.height() / 2 + QRandomGenerator::global()->bounded(size.height())); p.drawText(position, text); } } /* Drawing a multiline latin text, stress testing the text layout system. */ static void paintLongLatinText(QPainter &p, const QSize &size) { static const char* const pieces[] = { "lorem ipsum", "dolor sit amet", "consectetuer", "sed diam nonumy", "eos et accusam", "sea takimata sanctus" }; static const int piecesCount = (int)(sizeof pieces / sizeof pieces[0]); static const int piecesPerPaint = 30; QString text; for (int i = 0; i < piecesPerPaint; ++i) { QString piece = QLatin1String(pieces[QRandomGenerator::global()->bounded(piecesCount)]); if (i == 0 || QRandomGenerator::global()->bounded(2)) { // Make this piece the beginning of a new sentence. piece[0] = piece[0].toUpper(); if (i > 0) piece.prepend(QLatin1String(". ")); } else { piece.prepend(QLatin1String(", ")); } text.append(piece); } text.append(QLatin1Char('.')); p.drawText(QRectF(QPointF(0, 0), QSizeF(size)), Qt::AlignTop | Qt::AlignAbsolute | Qt::TextWordWrap, text); } /* Drawing one text with several snippets of different writingSystems, stress testing the font merging in the font database. */ static void paintInternationalText(QPainter &p, const QSize &size) { static QStringList samples; if (samples.isEmpty()) { foreach (const QFontDatabase::WritingSystem system, QFontDatabase().writingSystems()) if (system != QFontDatabase::Ogham && system != QFontDatabase::Runic) samples.append(QFontDatabase::writingSystemSample(system)); } static const int systemsPerPaint = 65; QString text; for (int i = 0; i < systemsPerPaint; i++) { if (i > 0) text.append(QLatin1Char(' ')); text.append(samples.at(QRandomGenerator::global()->bounded(samples.count()))); } p.drawText(QRectF(QPointF(0, 0), QSizeF(size)), Qt::AlignTop | Qt::AlignAbsolute | Qt::TextWordWrap, text); } protected: void nextMode() { m_currentMode = (m_currentMode + 1) % m_modesCount; m_lastMeasurements.clear(); } void keyPressEvent(QKeyEvent *event) { Q_UNUSED(event); nextMode(); } void mousePressEvent(QMouseEvent *event) { Q_UNUSED(event); nextMode(); } private: static const struct mode { QString name; void (*function)(QPainter &, const QSize&); } m_modes[]; static const int m_modesCount; int m_currentMode; QList m_lastMeasurements; QTime m_timer; }; const struct FontBlaster::mode FontBlaster::m_modes[] = { { QLatin1String("Qt rocks!!!"), FontBlaster::paintDifferentFontStyles }, { QLatin1String("Latin"), FontBlaster::paintLongLatinText }, { QLatin1String("International"), FontBlaster::paintInternationalText } }; const int FontBlaster::m_modesCount = (int)(sizeof m_modes / sizeof m_modes[0]); int main(int argc, char *argv[]) { QApplication a(argc, argv); FontBlaster dlg; dlg.show(); return a.exec(); } #include "main.moc"