|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the test suite of the Qt Toolkit. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 #include <QtGui> |
|
43 |
|
44 static const int lastMeasurementsCount = 50; |
|
45 |
|
46 class FontBlaster: public QWidget |
|
47 { |
|
48 Q_OBJECT |
|
49 |
|
50 public: |
|
51 FontBlaster(QWidget *parent = 0) |
|
52 : QWidget(parent) |
|
53 , m_currentMode(0) |
|
54 { |
|
55 setFocusPolicy(Qt::StrongFocus); |
|
56 } |
|
57 |
|
58 void paintEvent(QPaintEvent *event) |
|
59 { |
|
60 Q_UNUSED(event); |
|
61 QPainter p(this); |
|
62 |
|
63 if (!m_timer.isNull()) |
|
64 m_lastMeasurements.append(m_timer.elapsed()); |
|
65 m_timer.start(); |
|
66 |
|
67 p.save(); |
|
68 m_modes[m_currentMode].function(p, size()); |
|
69 p.restore(); |
|
70 |
|
71 const QFontMetrics fm = p.fontMetrics(); |
|
72 p.setOpacity(0.7); |
|
73 p.fillRect(0, 0, width(), fm.height(), Qt::gray); |
|
74 p.fillRect(0, height() - fm.height(), width(), height(), Qt::gray); |
|
75 p.setOpacity(1); |
|
76 p.setPen(palette().color(QPalette::Text)); |
|
77 p.drawText(2, fm.ascent(), m_modes[m_currentMode].name); |
|
78 |
|
79 if (m_lastMeasurements.count() == lastMeasurementsCount) { |
|
80 m_lastMeasurements.removeFirst(); |
|
81 int lastMsecsSum = 0; |
|
82 foreach(const int measurement, m_lastMeasurements) |
|
83 lastMsecsSum += measurement; |
|
84 |
|
85 p.drawText(2, height() - fm.descent(), |
|
86 QLatin1String("Fps: ") + |
|
87 QString::number(1000 / ((qreal)lastMsecsSum / lastMeasurementsCount), 'f', 1) |
|
88 ); |
|
89 } |
|
90 |
|
91 QTimer::singleShot(0, this, SLOT(repaint())); |
|
92 } |
|
93 |
|
94 /* |
|
95 Creating all kinds of size/weight/italic combinations, stress testing |
|
96 the glyph cache. |
|
97 Also: painting with different opacities, stress testing blitting. |
|
98 */ |
|
99 static void paintDifferentFontStyles(QPainter &p, const QSize &size) |
|
100 { |
|
101 static const QString text = QLatin1String("Qt rocks!!!"); |
|
102 static const int textsPerPaint = 30; |
|
103 for (int i = 0; i < textsPerPaint; i++) { |
|
104 const int fontSize = 4 + (qrand() % 5); |
|
105 const int fontWeight = (qrand() % 2) == 1 ? QFont::Normal : QFont::Bold; |
|
106 const bool fontItalic = (qrand() % 2) == 1; |
|
107 const QFont font("Default", fontSize, fontWeight, fontItalic); |
|
108 p.setFont(font); |
|
109 p.setPen(QColor::fromHsv(qrand() % 359, 155 + qrand() % 100, |
|
110 155 + qrand() % 100, 100 + qrand() % 155)); |
|
111 const QSize textSize(p.fontMetrics().boundingRect(text).size()); |
|
112 const QPoint position( |
|
113 -textSize.width() / 2 + (qrand() % size.width()), |
|
114 textSize.height() / 2 + (qrand() % size.height())); |
|
115 p.drawText(position, text); |
|
116 } |
|
117 } |
|
118 |
|
119 /* |
|
120 Drawing a multiline latin text, stress testing the text layout system. |
|
121 */ |
|
122 static void paintLongLatinText(QPainter &p, const QSize &size) |
|
123 { |
|
124 static const char* const pieces[] = { |
|
125 "lorem ipsum", |
|
126 "dolor sit amet", |
|
127 "consectetuer", |
|
128 "sed diam nonumy", |
|
129 "eos et accusam", |
|
130 "sea takimata sanctus" |
|
131 }; |
|
132 static const int piecesCount = (int)(sizeof pieces / sizeof pieces[0]); |
|
133 static const int piecesPerPaint = 30; |
|
134 |
|
135 QString text; |
|
136 for (int i = 0; i < piecesPerPaint; ++i) { |
|
137 QString piece = QLatin1String(pieces[qrand() % piecesCount]); |
|
138 if (i == 0 || qrand() % 2) { |
|
139 // Make this piece the beginning of a new sentence. |
|
140 piece[0] = piece[0].toUpper(); |
|
141 if (i > 0) |
|
142 piece.prepend(QLatin1String(". ")); |
|
143 } else { |
|
144 piece.prepend(QLatin1String(", ")); |
|
145 } |
|
146 text.append(piece); |
|
147 } |
|
148 text.append(QLatin1Char('.')); |
|
149 |
|
150 p.drawText(QRectF(QPointF(0, 0), QSizeF(size)), |
|
151 Qt::AlignTop | Qt::AlignAbsolute | Qt::TextWordWrap, text); |
|
152 } |
|
153 |
|
154 /* |
|
155 Drawing one text with several snippets of different writingSystems, stress |
|
156 testing the font merging in the font database. |
|
157 */ |
|
158 static void paintInternationalText(QPainter &p, const QSize &size) |
|
159 { |
|
160 static QStringList samples; |
|
161 if (samples.isEmpty()) { |
|
162 foreach (const QFontDatabase::WritingSystem system, QFontDatabase().writingSystems()) |
|
163 if (system != QFontDatabase::Ogham && system != QFontDatabase::Runic) |
|
164 samples.append(QFontDatabase::writingSystemSample(system)); |
|
165 } |
|
166 static const int systemsPerPaint = 65; |
|
167 QString text; |
|
168 for (int i = 0; i < systemsPerPaint; i++) { |
|
169 if (i > 0) |
|
170 text.append(QLatin1Char(' ')); |
|
171 text.append(samples.at(qrand() % samples.count())); |
|
172 } |
|
173 p.drawText(QRectF(QPointF(0, 0), QSizeF(size)), |
|
174 Qt::AlignTop | Qt::AlignAbsolute | Qt::TextWordWrap, text); |
|
175 } |
|
176 |
|
177 protected: |
|
178 void nextMode() |
|
179 { |
|
180 m_currentMode = (m_currentMode + 1) % m_modesCount; |
|
181 m_lastMeasurements.clear(); |
|
182 } |
|
183 |
|
184 void keyPressEvent(QKeyEvent *event) |
|
185 { |
|
186 Q_UNUSED(event); |
|
187 nextMode(); |
|
188 } |
|
189 |
|
190 void mousePressEvent(QMouseEvent *event) |
|
191 { |
|
192 Q_UNUSED(event); |
|
193 nextMode(); |
|
194 } |
|
195 |
|
196 private: |
|
197 static const struct mode { |
|
198 QString name; |
|
199 void (*function)(QPainter &, const QSize&); |
|
200 } m_modes[]; |
|
201 static const int m_modesCount; |
|
202 |
|
203 int m_currentMode; |
|
204 QList<int> m_lastMeasurements; |
|
205 QTime m_timer; |
|
206 }; |
|
207 |
|
208 const struct FontBlaster::mode FontBlaster::m_modes[] = { |
|
209 { QLatin1String("Qt rocks!!!"), FontBlaster::paintDifferentFontStyles }, |
|
210 { QLatin1String("Latin"), FontBlaster::paintLongLatinText }, |
|
211 { QLatin1String("International"), FontBlaster::paintInternationalText } |
|
212 }; |
|
213 |
|
214 const int FontBlaster::m_modesCount = |
|
215 (int)(sizeof m_modes / sizeof m_modes[0]); |
|
216 |
|
217 int main(int argc, char *argv[]) |
|
218 { |
|
219 QApplication a(argc, argv); |
|
220 |
|
221 FontBlaster dlg; |
|
222 #ifdef Q_OS_SYMBIAN |
|
223 dlg.showFullScreen(); |
|
224 #else |
|
225 dlg.show(); |
|
226 #endif |
|
227 |
|
228 return a.exec(); |
|
229 } |
|
230 |
|
231 #include "main.moc" |