d982428706cd23557302082b7b30d93af1af1ae3
[profile/ivi/qtbase.git] / tests / auto / gui / text / qglyphrun / tst_qglyphrun.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.  For licensing terms and
14 ** conditions see http://qt.digia.com/licensing.  For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights.  These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file.  Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include <QtTest/QtTest>
43
44 #include <qglyphrun.h>
45 #include <qpainter.h>
46 #include <qtextlayout.h>
47 #include <qfontdatabase.h>
48
49 // #define DEBUG_SAVE_IMAGE
50
51 class tst_QGlyphRun: public QObject
52 {
53     Q_OBJECT
54
55 #if !defined(QT_NO_RAWFONT)
56 private slots:
57     void initTestCase();
58     void init();
59     void cleanupTestCase();
60
61     void constructionAndDestruction();
62     void copyConstructor();
63     void assignment();
64     void equalsOperator_data();
65     void equalsOperator();
66     void textLayoutGlyphIndexes();
67     void drawExistingGlyphs();
68     void drawNonExistentGlyphs();
69     void drawMultiScriptText1();
70     void drawMultiScriptText2();
71     void drawStruckOutText();
72     void drawOverlinedText();
73     void drawUnderlinedText();
74     void drawRightToLeft();
75     void detach();
76     void setRawData();
77     void setRawDataAndGetAsVector();
78
79 private:
80     int m_testFontId;
81     QFont m_testFont;
82     bool m_testFont_ok;
83 #endif // QT_NO_RAWFONT
84
85 };
86
87 #if !defined(QT_NO_RAWFONT)
88
89 Q_DECLARE_METATYPE(QGlyphRun);
90
91 void tst_QGlyphRun::initTestCase()
92 {
93     m_testFont_ok = false;
94
95     m_testFontId = QFontDatabase::addApplicationFont(SRCDIR "test.ttf");
96     QVERIFY(m_testFontId >= 0);
97
98     m_testFont = QFont("QtsSpecialTestFont");
99
100     QCOMPARE(QFontInfo(m_testFont).family(), QString::fromLatin1("QtsSpecialTestFont"));
101
102     m_testFont_ok = true;
103 }
104
105 void tst_QGlyphRun::init()
106 {
107     if (!m_testFont_ok)
108         QSKIP("Test font is not working correctly");
109 }
110
111 void tst_QGlyphRun::cleanupTestCase()
112 {
113     QFontDatabase::removeApplicationFont(m_testFontId);
114 }
115
116 void tst_QGlyphRun::constructionAndDestruction()
117 {
118     QGlyphRun glyphIndexes;
119 }
120
121 static QGlyphRun make_dummy_indexes()
122 {
123     QGlyphRun glyphs;
124
125     QVector<quint32> glyphIndexes;
126     QVector<QPointF> positions;
127     QFont font;
128     font.setPointSize(18);
129
130     glyphIndexes.append(1);
131     glyphIndexes.append(2);
132     glyphIndexes.append(3);
133
134     positions.append(QPointF(1, 2));
135     positions.append(QPointF(3, 4));
136     positions.append(QPointF(5, 6));
137
138     glyphs.setRawFont(QRawFont::fromFont(font));
139     glyphs.setGlyphIndexes(glyphIndexes);
140     glyphs.setPositions(positions);
141
142     return glyphs;
143 }
144
145 void tst_QGlyphRun::copyConstructor()
146 {
147     QGlyphRun glyphs;
148
149     {
150         QVector<quint32> glyphIndexes;
151         QVector<QPointF> positions;
152         QFont font;
153         font.setPointSize(18);
154
155         glyphIndexes.append(1);
156         glyphIndexes.append(2);
157         glyphIndexes.append(3);
158
159         positions.append(QPointF(1, 2));
160         positions.append(QPointF(3, 4));
161         positions.append(QPointF(5, 6));
162
163         glyphs.setRawFont(QRawFont::fromFont(font));
164         glyphs.setGlyphIndexes(glyphIndexes);
165         glyphs.setPositions(positions);
166     }
167
168     QGlyphRun otherGlyphs(glyphs);
169     QCOMPARE(otherGlyphs.rawFont(), glyphs.rawFont());
170     QCOMPARE(glyphs.glyphIndexes(), otherGlyphs.glyphIndexes());
171     QCOMPARE(glyphs.positions(), otherGlyphs.positions());
172 }
173
174 void tst_QGlyphRun::assignment()
175 {
176     QGlyphRun glyphs(make_dummy_indexes());
177
178     QGlyphRun otherGlyphs = glyphs;
179     QCOMPARE(otherGlyphs.rawFont(), glyphs.rawFont());
180     QCOMPARE(glyphs.glyphIndexes(), otherGlyphs.glyphIndexes());
181     QCOMPARE(glyphs.positions(), otherGlyphs.positions());
182 }
183
184 void tst_QGlyphRun::equalsOperator_data()
185 {
186     QTest::addColumn<QGlyphRun>("one");
187     QTest::addColumn<QGlyphRun>("two");
188     QTest::addColumn<bool>("equals");
189
190     QGlyphRun one(make_dummy_indexes());
191     QGlyphRun two(make_dummy_indexes());
192
193     QTest::newRow("Identical") << one << two << true;
194
195     {
196         QGlyphRun busted(two);
197
198         QVector<QPointF> positions = busted.positions();
199         positions[2] += QPointF(1, 1);
200         busted.setPositions(positions);
201
202
203         QTest::newRow("Different positions") << one << busted << false;
204     }
205
206     {
207         QGlyphRun busted(two);
208
209         QFont font;
210         font.setPixelSize(busted.rawFont().pixelSize() * 2);
211         busted.setRawFont(QRawFont::fromFont(font));
212
213         QTest::newRow("Different fonts") << one << busted << false;
214     }
215
216     {
217         QGlyphRun busted(two);
218
219         QVector<quint32> glyphIndexes = busted.glyphIndexes();
220         glyphIndexes[2] += 1;
221         busted.setGlyphIndexes(glyphIndexes);
222
223         QTest::newRow("Different glyph indexes") << one << busted << false;
224     }
225
226 }
227
228 void tst_QGlyphRun::equalsOperator()
229 {
230     QFETCH(QGlyphRun, one);
231     QFETCH(QGlyphRun, two);
232     QFETCH(bool, equals);
233
234     QCOMPARE(one == two, equals);
235     QCOMPARE(one != two, !equals);
236 }
237
238
239 void tst_QGlyphRun::textLayoutGlyphIndexes()
240 {
241     QString s;
242     s.append(QLatin1Char('A'));
243     s.append(QChar(0xe000));
244
245     QTextLayout layout(s);
246     layout.setFont(m_testFont);
247     layout.setCacheEnabled(true);
248     layout.beginLayout();
249     layout.createLine();
250     layout.endLayout();
251
252     QList<QGlyphRun> listOfGlyphs = layout.glyphRuns();
253
254     QCOMPARE(listOfGlyphs.size(), 1);
255
256     QGlyphRun glyphs = listOfGlyphs.at(0);
257
258     QCOMPARE(glyphs.glyphIndexes().size(), 2);
259     QCOMPARE(glyphs.glyphIndexes().at(0), quint32(2));
260     QCOMPARE(glyphs.glyphIndexes().at(1), quint32(1));
261 }
262
263 void tst_QGlyphRun::drawExistingGlyphs()
264 {
265     QPixmap textLayoutDraw(1000, 1000);
266     QPixmap drawGlyphs(1000, 1000);
267
268     textLayoutDraw.fill(Qt::white);
269     drawGlyphs.fill(Qt::white);
270
271     QString s;
272     s.append(QLatin1Char('A'));
273     s.append(QChar(0xe000));
274
275     QTextLayout layout(s);
276     layout.setFont(m_testFont);
277     layout.setCacheEnabled(true);
278     layout.beginLayout();
279     layout.createLine();
280     layout.endLayout();
281
282     {
283         QPainter p(&textLayoutDraw);
284         layout.draw(&p, QPointF(50, 50));
285     }
286
287     QGlyphRun glyphs = layout.glyphRuns().size() > 0
288                                  ? layout.glyphRuns().at(0)
289                                  : QGlyphRun();
290
291     {
292         QPainter p(&drawGlyphs);
293         p.drawGlyphRun(QPointF(50, 50), glyphs);
294     }
295
296 #if defined(DEBUG_SAVE_IMAGE)
297     textLayoutDraw.save("drawExistingGlyphs_textLayoutDraw.png");
298     drawGlyphs.save("drawExistingGlyphs_drawGlyphIndexes.png");
299 #endif
300
301     QCOMPARE(textLayoutDraw, drawGlyphs);
302 }
303
304 void tst_QGlyphRun::setRawData()
305 {
306     QGlyphRun glyphRun;
307     glyphRun.setRawFont(QRawFont::fromFont(m_testFont));
308     glyphRun.setGlyphIndexes(QVector<quint32>() << 2 << 2 << 2);
309     glyphRun.setPositions(QVector<QPointF>() << QPointF(2, 3) << QPointF(20, 3) << QPointF(10, 20));
310
311     QPixmap baseline(100, 50);
312     baseline.fill(Qt::white);
313     {
314         QPainter p(&baseline);
315         p.drawGlyphRun(QPointF(3, 2), glyphRun);
316     }
317
318     QGlyphRun baselineCopied = glyphRun;
319
320     quint32 glyphIndexArray[3] = { 2, 2, 2 };
321     QPointF glyphPositionArray[3] = { QPointF(2, 3), QPointF(20, 3), QPointF(10, 20) };
322
323     glyphRun.setRawData(glyphIndexArray, glyphPositionArray, 3);
324
325     QPixmap rawDataGlyphs(100, 50);
326     rawDataGlyphs.fill(Qt::white);
327     {
328         QPainter p(&rawDataGlyphs);
329         p.drawGlyphRun(QPointF(3, 2), glyphRun);
330     }
331
332     quint32 otherGlyphIndexArray[1] = { 2 };
333     QPointF otherGlyphPositionArray[1] = { QPointF(2, 3) };
334
335     glyphRun.setRawData(otherGlyphIndexArray, otherGlyphPositionArray, 1);
336
337     QPixmap baselineCopiedPixmap(100, 50);
338     baselineCopiedPixmap.fill(Qt::white);
339     {
340         QPainter p(&baselineCopiedPixmap);
341         p.drawGlyphRun(QPointF(3, 2), baselineCopied);
342     }
343
344 #if defined(DEBUG_SAVE_IMAGE)
345     baseline.save("setRawData_baseline.png");
346     rawDataGlyphs.save("setRawData_rawDataGlyphs.png");
347     baselineCopiedPixmap.save("setRawData_baselineCopiedPixmap.png");
348 #endif
349
350     QCOMPARE(rawDataGlyphs, baseline);
351     QCOMPARE(baselineCopiedPixmap, baseline);
352 }
353
354 void tst_QGlyphRun::setRawDataAndGetAsVector()
355 {
356     QVector<quint32> glyphIndexArray;
357     glyphIndexArray << 3 << 2 << 1 << 4;
358
359     QVector<QPointF> glyphPositionArray;
360     glyphPositionArray << QPointF(1, 2) << QPointF(3, 4) << QPointF(5, 6) << QPointF(7, 8);
361
362     QGlyphRun glyphRun;
363     glyphRun.setRawData(glyphIndexArray.constData(), glyphPositionArray.constData(), 4);
364
365     QVector<quint32> glyphIndexes = glyphRun.glyphIndexes();
366     QVector<QPointF> glyphPositions = glyphRun.positions();
367
368     QCOMPARE(glyphIndexes.size(), 4);
369     QCOMPARE(glyphPositions.size(), 4);
370
371     QCOMPARE(glyphIndexes, glyphIndexArray);
372     QCOMPARE(glyphPositions, glyphPositionArray);
373
374     QGlyphRun otherGlyphRun;
375     otherGlyphRun.setGlyphIndexes(glyphIndexArray);
376     otherGlyphRun.setPositions(glyphPositionArray);
377
378     QCOMPARE(glyphRun, otherGlyphRun);
379 }
380
381 void tst_QGlyphRun::drawNonExistentGlyphs()
382 {
383     QVector<quint32> glyphIndexes;
384     glyphIndexes.append(3);
385
386     QVector<QPointF> glyphPositions;
387     glyphPositions.append(QPointF(0, 0));
388
389     QGlyphRun glyphs;
390     glyphs.setGlyphIndexes(glyphIndexes);
391     glyphs.setPositions(glyphPositions);
392     glyphs.setRawFont(QRawFont::fromFont(m_testFont));
393
394     QPixmap image(1000, 1000);
395     image.fill(Qt::white);
396
397     QPixmap imageBefore = image;
398     {
399         QPainter p(&image);
400         p.drawGlyphRun(QPointF(50, 50), glyphs);
401     }
402
403 #if defined(DEBUG_SAVE_IMAGE)
404     image.save("drawNonExistentGlyphs.png");
405 #endif
406
407     QCOMPARE(image, imageBefore); // Should be unchanged
408 }
409
410 void tst_QGlyphRun::drawMultiScriptText1()
411 {
412     QString text;
413     text += QChar(0x03D0); // Greek, beta
414
415     QTextLayout textLayout(text);
416     textLayout.setCacheEnabled(true);
417     textLayout.beginLayout();
418     textLayout.createLine();
419     textLayout.endLayout();
420
421     QPixmap textLayoutDraw(1000, 1000);
422     textLayoutDraw.fill(Qt::white);
423
424     QPixmap drawGlyphs(1000, 1000);
425     drawGlyphs.fill(Qt::white);
426
427     QList<QGlyphRun> glyphsList = textLayout.glyphRuns();
428     QCOMPARE(glyphsList.size(), 1);
429
430     {
431         QPainter p(&textLayoutDraw);
432         textLayout.draw(&p, QPointF(50, 50));
433     }
434
435     {
436         QPainter p(&drawGlyphs);
437         foreach (QGlyphRun glyphs, glyphsList)
438             p.drawGlyphRun(QPointF(50, 50), glyphs);
439     }
440
441 #if defined(DEBUG_SAVE_IMAGE)
442     textLayoutDraw.save("drawMultiScriptText1_textLayoutDraw.png");
443     drawGlyphs.save("drawMultiScriptText1_drawGlyphIndexes.png");
444 #endif
445
446     QCOMPARE(drawGlyphs, textLayoutDraw);
447 }
448
449
450 void tst_QGlyphRun::drawMultiScriptText2()
451 {
452     QString text;
453     text += QChar(0x0621); // Arabic, Hamza
454     text += QChar(0x03D0); // Greek, beta
455
456     QTextLayout textLayout(text);
457     textLayout.setCacheEnabled(true);
458     textLayout.beginLayout();
459     textLayout.createLine();
460     textLayout.endLayout();
461
462     QPixmap textLayoutDraw(1000, 1000);
463     textLayoutDraw.fill(Qt::white);
464
465     QPixmap drawGlyphs(1000, 1000);
466     drawGlyphs.fill(Qt::white);
467
468     QList<QGlyphRun> glyphsList = textLayout.glyphRuns();
469     QCOMPARE(glyphsList.size(), 2);
470
471     {
472         QPainter p(&textLayoutDraw);
473         textLayout.draw(&p, QPointF(50, 50));
474     }
475
476     {
477         QPainter p(&drawGlyphs);
478         foreach (QGlyphRun glyphs, glyphsList)
479             p.drawGlyphRun(QPointF(50, 50), glyphs);
480     }
481
482 #if defined(DEBUG_SAVE_IMAGE)
483     textLayoutDraw.save("drawMultiScriptText2_textLayoutDraw.png");
484     drawGlyphs.save("drawMultiScriptText2_drawGlyphIndexes.png");
485 #endif
486
487     QCOMPARE(drawGlyphs, textLayoutDraw);
488 }
489
490 void tst_QGlyphRun::detach()
491 {
492     QGlyphRun glyphs;
493
494     glyphs.setGlyphIndexes(QVector<quint32>() << 1 << 2 << 3);
495
496     QGlyphRun otherGlyphs;
497     otherGlyphs = glyphs;
498
499     QCOMPARE(otherGlyphs.glyphIndexes(), glyphs.glyphIndexes());
500
501     otherGlyphs.setGlyphIndexes(QVector<quint32>() << 4 << 5 << 6);
502
503     QCOMPARE(otherGlyphs.glyphIndexes(), QVector<quint32>() << 4 << 5 << 6);
504     QCOMPARE(glyphs.glyphIndexes(), QVector<quint32>() << 1 << 2 << 3);
505 }
506
507 void tst_QGlyphRun::drawStruckOutText()
508 {
509     QPixmap textLayoutDraw(1000, 1000);
510     QPixmap drawGlyphs(1000, 1000);
511
512     textLayoutDraw.fill(Qt::white);
513     drawGlyphs.fill(Qt::white);
514
515     QString s = QString::fromLatin1("Foobar");
516
517     QFont font;
518     font.setStrikeOut(true);
519
520     QTextLayout layout(s);
521     layout.setFont(font);
522     layout.setCacheEnabled(true);
523     layout.beginLayout();
524     layout.createLine();
525     layout.endLayout();
526
527     {
528         QPainter p(&textLayoutDraw);
529         layout.draw(&p, QPointF(50, 50));
530     }
531
532     QGlyphRun glyphs = layout.glyphRuns().size() > 0
533                                  ? layout.glyphRuns().at(0)
534                                  : QGlyphRun();
535
536     {
537         QPainter p(&drawGlyphs);
538         p.drawGlyphRun(QPointF(50, 50), glyphs);
539     }
540
541 #if defined(DEBUG_SAVE_IMAGE)
542     textLayoutDraw.save("drawStruckOutText_textLayoutDraw.png");
543     drawGlyphs.save("drawStruckOutText_drawGlyphIndexes.png");
544 #endif
545
546     QCOMPARE(textLayoutDraw, drawGlyphs);
547 }
548
549 void tst_QGlyphRun::drawOverlinedText()
550 {
551     QPixmap textLayoutDraw(1000, 1000);
552     QPixmap drawGlyphs(1000, 1000);
553
554     textLayoutDraw.fill(Qt::white);
555     drawGlyphs.fill(Qt::white);
556
557     QString s = QString::fromLatin1("Foobar");
558
559     QFont font;
560     font.setOverline(true);
561
562     QTextLayout layout(s);
563     layout.setFont(font);
564     layout.setCacheEnabled(true);
565     layout.beginLayout();
566     layout.createLine();
567     layout.endLayout();
568
569     {
570         QPainter p(&textLayoutDraw);
571         layout.draw(&p, QPointF(50, 50));
572     }
573
574     QGlyphRun glyphs = layout.glyphRuns().size() > 0
575                                  ? layout.glyphRuns().at(0)
576                                  : QGlyphRun();
577
578     {
579         QPainter p(&drawGlyphs);
580         p.drawGlyphRun(QPointF(50, 50), glyphs);
581     }
582
583 #if defined(DEBUG_SAVE_IMAGE)
584     textLayoutDraw.save("drawOverlineText_textLayoutDraw.png");
585     drawGlyphs.save("drawOverlineText_drawGlyphIndexes.png");
586 #endif
587
588     QCOMPARE(textLayoutDraw, drawGlyphs);
589 }
590
591 void tst_QGlyphRun::drawUnderlinedText()
592 {
593     QPixmap textLayoutDraw(1000, 1000);
594     QPixmap drawGlyphs(1000, 1000);
595
596     textLayoutDraw.fill(Qt::white);
597     drawGlyphs.fill(Qt::white);
598
599     QString s = QString::fromLatin1("Foobar");
600
601     QFont font;
602     font.setUnderline(true);
603
604     QTextLayout layout(s);
605     layout.setFont(font);
606     layout.setCacheEnabled(true);
607     layout.beginLayout();
608     layout.createLine();
609     layout.endLayout();
610
611     {
612         QPainter p(&textLayoutDraw);
613         layout.draw(&p, QPointF(50, 50));
614     }
615
616     QGlyphRun glyphs = layout.glyphRuns().size() > 0
617                                  ? layout.glyphRuns().at(0)
618                                  : QGlyphRun();
619
620     {
621         QPainter p(&drawGlyphs);
622         p.drawGlyphRun(QPointF(50, 50), glyphs);
623     }
624
625 #if defined(DEBUG_SAVE_IMAGE)
626     textLayoutDraw.save("drawUnderlineText_textLayoutDraw.png");
627     drawGlyphs.save("drawUnderlineText_drawGlyphIndexes.png");
628 #endif
629
630     QCOMPARE(textLayoutDraw, drawGlyphs);
631 }
632
633 void tst_QGlyphRun::drawRightToLeft()
634 {
635     QString s;
636     s.append(QChar(1575));
637     s.append(QChar(1578));
638
639     QPixmap textLayoutDraw(1000, 1000);
640     QPixmap drawGlyphs(1000, 1000);
641
642     textLayoutDraw.fill(Qt::white);
643     drawGlyphs.fill(Qt::white);
644
645     QFont font;
646     font.setUnderline(true);
647
648     QTextLayout layout(s);
649     layout.setFont(font);
650     layout.setCacheEnabled(true);
651     layout.beginLayout();
652     layout.createLine();
653     layout.endLayout();
654
655     {
656         QPainter p(&textLayoutDraw);
657         layout.draw(&p, QPointF(50, 50));
658     }
659
660     QGlyphRun glyphs = layout.glyphRuns().size() > 0
661                                  ? layout.glyphRuns().at(0)
662                                  : QGlyphRun();
663
664     {
665         QPainter p(&drawGlyphs);
666         p.drawGlyphRun(QPointF(50, 50), glyphs);
667     }
668
669 #if defined(DEBUG_SAVE_IMAGE)
670     textLayoutDraw.save("drawRightToLeft_textLayoutDraw.png");
671     drawGlyphs.save("drawRightToLeft_drawGlyphIndexes.png");
672 #endif
673
674     QCOMPARE(textLayoutDraw, drawGlyphs);
675
676 }
677
678 #endif // QT_NO_RAWFONT
679
680 QTEST_MAIN(tst_QGlyphRun)
681 #include "tst_qglyphrun.moc"
682