|
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 <QDebug> |
|
43 #include <QTextDocument> |
|
44 #include <QTextDocumentWriter> |
|
45 #include <QTextLayout> |
|
46 #include <QTextCursor> |
|
47 #include <private/qtextcontrol_p.h> |
|
48 #include <qmath.h> |
|
49 #include <QFile> |
|
50 #include <QPainter> |
|
51 #include <QBuffer> |
|
52 #include <qtest.h> |
|
53 |
|
54 #ifdef Q_OS_SYMBIAN |
|
55 // In Symbian OS test data is located in applications private dir |
|
56 // Application private dir is default serach path for files, so SRCDIR can be set to empty |
|
57 #define SRCDIR "" |
|
58 #endif |
|
59 |
|
60 Q_DECLARE_METATYPE(QTextDocument*) |
|
61 |
|
62 class tst_QText: public QObject |
|
63 { |
|
64 Q_OBJECT |
|
65 public: |
|
66 tst_QText() { |
|
67 m_lorem = QString::fromLatin1("Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi."); |
|
68 m_shortLorem = QString::fromLatin1("Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); |
|
69 } |
|
70 |
|
71 private slots: |
|
72 void loadHtml_data(); |
|
73 void loadHtml(); |
|
74 |
|
75 void shaping_data(); |
|
76 void shaping(); |
|
77 |
|
78 void odfWriting_empty(); |
|
79 void odfWriting_text(); |
|
80 void odfWriting_images(); |
|
81 |
|
82 void constructControl(); |
|
83 void constructDocument(); |
|
84 |
|
85 void layout(); |
|
86 void paintLayoutToPixmap(); |
|
87 void paintLayoutToPixmap_painterFill(); |
|
88 |
|
89 void document(); |
|
90 void paintDocToPixmap(); |
|
91 void paintDocToPixmap_painterFill(); |
|
92 |
|
93 void control(); |
|
94 void paintControlToPixmap(); |
|
95 void paintControlToPixmap_painterFill(); |
|
96 |
|
97 private: |
|
98 QSize setupTextLayout(QTextLayout *layout); |
|
99 |
|
100 QString m_lorem; |
|
101 QString m_shortLorem; |
|
102 }; |
|
103 |
|
104 void tst_QText::loadHtml_data() |
|
105 { |
|
106 QTest::addColumn<QString>("source"); |
|
107 QTest::newRow("empty") << QString(); |
|
108 QTest::newRow("simple") << QString::fromLatin1("<html><b>Foo</b></html>"); |
|
109 QTest::newRow("simple2") << QString::fromLatin1("<b>Foo</b>"); |
|
110 |
|
111 QString parag = QString::fromLatin1("<p>%1</p>").arg(m_lorem); |
|
112 QString header = QString::fromLatin1("<html><head><title>test</title></head><body>"); |
|
113 QTest::newRow("long") << QString::fromLatin1("<html><head><title>test</title></head><body>") + parag + parag + parag |
|
114 + parag + parag + parag + parag + parag + parag + parag + parag + parag + parag + parag + parag + parag + parag |
|
115 + QString::fromLatin1("</html>"); |
|
116 QTest::newRow("table") << header + QLatin1String("<table border=\"1\"1><tr><td>xx</td></tr><tr><td colspan=\"2\">") |
|
117 + parag + QLatin1String("</td></tr></table></html"); |
|
118 QTest::newRow("crappy") << header + QLatin1String("<table border=\"1\"1><tr><td>xx</td></tr><tr><td colspan=\"2\">") |
|
119 + parag; |
|
120 } |
|
121 |
|
122 void tst_QText::loadHtml() |
|
123 { |
|
124 QFETCH(QString, source); |
|
125 QTextDocument doc; |
|
126 QBENCHMARK { |
|
127 doc.setHtml(source); |
|
128 } |
|
129 } |
|
130 |
|
131 void tst_QText::shaping_data() |
|
132 { |
|
133 QTest::addColumn<QString>("parag"); |
|
134 QTest::newRow("empty") << QString(); |
|
135 QTest::newRow("lorem") << m_lorem; |
|
136 QTest::newRow("short") << QString::fromLatin1("Lorem ipsum dolor sit amet"); |
|
137 |
|
138 #if !defined(Q_OS_SYMBIAN) |
|
139 QFile file(QString::fromLatin1(SRCDIR) + QLatin1String("/bidi.txt")); |
|
140 #else |
|
141 QFile file( SRCDIR "bidi.txt" ); |
|
142 #endif |
|
143 QVERIFY(file.open(QFile::ReadOnly)); |
|
144 QByteArray data = file.readAll(); |
|
145 QVERIFY(data.count() > 1000); |
|
146 QStringList list = QString::fromUtf8(data.data()).split(QLatin1Char('\n'), QString::SkipEmptyParts); |
|
147 QVERIFY(list.count() %2 == 0); // even amount as we have title and then content. |
|
148 for (int i=0; i < list.count(); i+=2) { |
|
149 QTest::newRow(list.at(i).toLatin1()) << list.at(i+1); |
|
150 } |
|
151 } |
|
152 |
|
153 void tst_QText::shaping() |
|
154 { |
|
155 QFETCH(QString, parag); |
|
156 |
|
157 QTextLayout lay(parag); |
|
158 lay.setCacheEnabled(false); |
|
159 |
|
160 // do one run to make sure any fonts are loaded. |
|
161 lay.beginLayout(); |
|
162 lay.createLine(); |
|
163 lay.endLayout(); |
|
164 |
|
165 QBENCHMARK { |
|
166 lay.beginLayout(); |
|
167 lay.createLine(); |
|
168 lay.endLayout(); |
|
169 } |
|
170 } |
|
171 |
|
172 void tst_QText::odfWriting_empty() |
|
173 { |
|
174 QVERIFY(QTextDocumentWriter::supportedDocumentFormats().contains("ODF")); // odf compiled in |
|
175 QTextDocument *doc = new QTextDocument(); |
|
176 // write it |
|
177 QBENCHMARK { |
|
178 QBuffer buffer; |
|
179 buffer.open(QIODevice::WriteOnly); |
|
180 QTextDocumentWriter writer(&buffer, "ODF"); |
|
181 writer.write(doc); |
|
182 } |
|
183 delete doc; |
|
184 } |
|
185 |
|
186 void tst_QText::odfWriting_text() |
|
187 { |
|
188 QTextDocument *doc = new QTextDocument(); |
|
189 QTextCursor cursor(doc); |
|
190 QTextBlockFormat bf; |
|
191 bf.setIndent(2); |
|
192 cursor.insertBlock(bf); |
|
193 cursor.insertText(m_lorem); |
|
194 bf.setTopMargin(10); |
|
195 cursor.insertBlock(bf); |
|
196 cursor.insertText(m_lorem); |
|
197 bf.setRightMargin(30); |
|
198 cursor.insertBlock(bf); |
|
199 cursor.insertText(m_lorem); |
|
200 |
|
201 // write it |
|
202 QBENCHMARK { |
|
203 QBuffer buffer; |
|
204 buffer.open(QIODevice::WriteOnly); |
|
205 QTextDocumentWriter writer(&buffer, "ODF"); |
|
206 writer.write(doc); |
|
207 } |
|
208 delete doc; |
|
209 } |
|
210 |
|
211 void tst_QText::odfWriting_images() |
|
212 { |
|
213 QTextDocument *doc = new QTextDocument(); |
|
214 QTextCursor cursor(doc); |
|
215 cursor.insertText(m_lorem); |
|
216 QImage image(400, 200, QImage::Format_ARGB32_Premultiplied); |
|
217 cursor.insertImage(image); |
|
218 cursor.insertText(m_lorem); |
|
219 |
|
220 // write it |
|
221 QBENCHMARK { |
|
222 QBuffer buffer; |
|
223 buffer.open(QIODevice::WriteOnly); |
|
224 QTextDocumentWriter writer(&buffer, "ODF"); |
|
225 writer.write(doc); |
|
226 } |
|
227 delete doc; |
|
228 } |
|
229 |
|
230 QSize tst_QText::setupTextLayout(QTextLayout *layout) |
|
231 { |
|
232 bool wrap = true; |
|
233 int wrapWidth = 300; |
|
234 layout->setCacheEnabled(true); |
|
235 |
|
236 int height = 0; |
|
237 qreal widthUsed = 0; |
|
238 qreal lineWidth = 0; |
|
239 |
|
240 //set manual width |
|
241 if (wrap) |
|
242 lineWidth = wrapWidth; |
|
243 |
|
244 layout->beginLayout(); |
|
245 |
|
246 while (1) { |
|
247 QTextLine line = layout->createLine(); |
|
248 if (!line.isValid()) |
|
249 break; |
|
250 |
|
251 if (wrap) |
|
252 line.setLineWidth(lineWidth); |
|
253 } |
|
254 layout->endLayout(); |
|
255 |
|
256 for (int i = 0; i < layout->lineCount(); ++i) { |
|
257 QTextLine line = layout->lineAt(i); |
|
258 widthUsed = qMax(widthUsed, line.naturalTextWidth()); |
|
259 line.setPosition(QPointF(0, height)); |
|
260 height += int(line.height()); |
|
261 } |
|
262 return QSize(qCeil(widthUsed), height); |
|
263 } |
|
264 |
|
265 void tst_QText::constructControl() |
|
266 { |
|
267 QTextControl *control = new QTextControl; |
|
268 delete control; |
|
269 |
|
270 QBENCHMARK { |
|
271 QTextControl *control = new QTextControl; |
|
272 delete control; |
|
273 } |
|
274 } |
|
275 |
|
276 void tst_QText::constructDocument() |
|
277 { |
|
278 QTextDocument *doc = new QTextDocument; |
|
279 delete doc; |
|
280 |
|
281 QBENCHMARK { |
|
282 QTextDocument *doc = new QTextDocument; |
|
283 delete doc; |
|
284 } |
|
285 } |
|
286 |
|
287 void tst_QText::layout() |
|
288 { |
|
289 QTextLayout layout(m_shortLorem); |
|
290 setupTextLayout(&layout); |
|
291 |
|
292 QBENCHMARK { |
|
293 QTextLayout layout(m_shortLorem); |
|
294 setupTextLayout(&layout); |
|
295 } |
|
296 } |
|
297 |
|
298 void tst_QText::paintLayoutToPixmap() |
|
299 { |
|
300 QTextLayout layout(m_shortLorem); |
|
301 QSize size = setupTextLayout(&layout); |
|
302 |
|
303 QBENCHMARK { |
|
304 QPixmap img(size); |
|
305 img.fill(Qt::transparent); |
|
306 QPainter p(&img); |
|
307 layout.draw(&p, QPointF(0, 0)); |
|
308 } |
|
309 } |
|
310 |
|
311 void tst_QText::paintLayoutToPixmap_painterFill() |
|
312 { |
|
313 QTextLayout layout(m_shortLorem); |
|
314 QSize size = setupTextLayout(&layout); |
|
315 |
|
316 QBENCHMARK { |
|
317 QPixmap img(size); |
|
318 QPainter p(&img); |
|
319 p.setCompositionMode(QPainter::CompositionMode_Source); |
|
320 p.fillRect(0, 0, img.width(), img.height(), Qt::transparent); |
|
321 p.setCompositionMode(QPainter::CompositionMode_SourceOver); |
|
322 layout.draw(&p, QPointF(0, 0)); |
|
323 } |
|
324 } |
|
325 |
|
326 void tst_QText::document() |
|
327 { |
|
328 QTextDocument *doc = new QTextDocument; |
|
329 |
|
330 QBENCHMARK { |
|
331 QTextDocument *doc = new QTextDocument; |
|
332 doc->setHtml(m_shortLorem); |
|
333 } |
|
334 } |
|
335 |
|
336 void tst_QText::paintDocToPixmap() |
|
337 { |
|
338 QTextDocument *doc = new QTextDocument; |
|
339 doc->setHtml(m_shortLorem); |
|
340 doc->setTextWidth(300); |
|
341 QSize size = doc->size().toSize(); |
|
342 |
|
343 QBENCHMARK { |
|
344 QPixmap img(size); |
|
345 img.fill(Qt::transparent); |
|
346 QPainter p(&img); |
|
347 doc->drawContents(&p); |
|
348 } |
|
349 } |
|
350 |
|
351 void tst_QText::paintDocToPixmap_painterFill() |
|
352 { |
|
353 QTextDocument *doc = new QTextDocument; |
|
354 doc->setHtml(m_shortLorem); |
|
355 doc->setTextWidth(300); |
|
356 QSize size = doc->size().toSize(); |
|
357 |
|
358 QBENCHMARK { |
|
359 QPixmap img(size); |
|
360 QPainter p(&img); |
|
361 p.setCompositionMode(QPainter::CompositionMode_Source); |
|
362 p.fillRect(0, 0, img.width(), img.height(), Qt::transparent); |
|
363 p.setCompositionMode(QPainter::CompositionMode_SourceOver); |
|
364 doc->drawContents(&p); |
|
365 } |
|
366 } |
|
367 |
|
368 void tst_QText::control() |
|
369 { |
|
370 QTextControl *control = new QTextControl(m_shortLorem); |
|
371 |
|
372 QBENCHMARK { |
|
373 QTextControl *control = new QTextControl; |
|
374 QTextDocument *doc = control->document(); |
|
375 doc->setHtml(m_shortLorem); |
|
376 } |
|
377 } |
|
378 |
|
379 void tst_QText::paintControlToPixmap() |
|
380 { |
|
381 QTextControl *control = new QTextControl; |
|
382 QTextDocument *doc = control->document(); |
|
383 doc->setHtml(m_shortLorem); |
|
384 doc->setTextWidth(300); |
|
385 QSize size = doc->size().toSize(); |
|
386 |
|
387 QBENCHMARK { |
|
388 QPixmap img(size); |
|
389 img.fill(Qt::transparent); |
|
390 QPainter p(&img); |
|
391 control->drawContents(&p, QRectF(QPointF(0, 0), QSizeF(size))); |
|
392 } |
|
393 } |
|
394 |
|
395 void tst_QText::paintControlToPixmap_painterFill() |
|
396 { |
|
397 QTextControl *control = new QTextControl; |
|
398 QTextDocument *doc = control->document(); |
|
399 doc->setHtml(m_shortLorem); |
|
400 doc->setTextWidth(300); |
|
401 QSize size = doc->size().toSize(); |
|
402 |
|
403 QBENCHMARK { |
|
404 QPixmap img(size); |
|
405 QPainter p(&img); |
|
406 p.setCompositionMode(QPainter::CompositionMode_Source); |
|
407 p.fillRect(0, 0, img.width(), img.height(), Qt::transparent); |
|
408 p.setCompositionMode(QPainter::CompositionMode_SourceOver); |
|
409 control->drawContents(&p, QRectF(QPointF(0, 0), QSizeF(size))); |
|
410 } |
|
411 } |
|
412 |
|
413 QTEST_MAIN(tst_QText) |
|
414 |
|
415 #include "main.moc" |