/tests/auto/qglyphrun/tst_qglyphrun.cpp

https://bitbucket.org/ultra_iter/qt-vtl · C++ · 661 lines · 465 code · 155 blank · 41 comment · 2 complexity · 4ebb0c6907fe456ebc1743ded1b46462 MD5 · raw file

  1. /****************************************************************************
  2. **
  3. ** Copyright (C) 2012 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. ** GNU Lesser General Public License Usage
  11. ** This file may be used under the terms of the GNU Lesser General Public
  12. ** License version 2.1 as published by the Free Software Foundation and
  13. ** appearing in the file LICENSE.LGPL included in the packaging of this
  14. ** file. Please review the following information to ensure the GNU Lesser
  15. ** General Public License version 2.1 requirements will be met:
  16. ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  17. **
  18. ** In addition, as a special exception, Nokia gives you certain additional
  19. ** rights. These rights are described in the Nokia Qt LGPL Exception
  20. ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
  21. **
  22. ** GNU General Public License Usage
  23. ** Alternatively, this file may be used under the terms of the GNU General
  24. ** Public License version 3.0 as published by the Free Software Foundation
  25. ** and appearing in the file LICENSE.GPL included in the packaging of this
  26. ** file. Please review the following information to ensure the GNU General
  27. ** Public License version 3.0 requirements will be met:
  28. ** http://www.gnu.org/copyleft/gpl.html.
  29. **
  30. ** Other Usage
  31. ** Alternatively, this file may be used in accordance with the terms and
  32. ** conditions contained in a signed written agreement between you and Nokia.
  33. **
  34. **
  35. **
  36. **
  37. **
  38. ** $QT_END_LICENSE$
  39. **
  40. ****************************************************************************/
  41. #include <QtTest/QtTest>
  42. #include <qglyphrun.h>
  43. #include <qpainter.h>
  44. #include <qtextlayout.h>
  45. #include <qfontdatabase.h>
  46. // #define DEBUG_SAVE_IMAGE
  47. class tst_QGlyphRun: public QObject
  48. {
  49. Q_OBJECT
  50. #if !defined(QT_NO_RAWFONT)
  51. private slots:
  52. void initTestCase();
  53. void cleanupTestCase();
  54. void constructionAndDestruction();
  55. void copyConstructor();
  56. void assignment();
  57. void equalsOperator_data();
  58. void equalsOperator();
  59. void textLayoutGlyphIndexes();
  60. void drawExistingGlyphs();
  61. void drawNonExistentGlyphs();
  62. void drawMultiScriptText1();
  63. void drawMultiScriptText2();
  64. void drawStruckOutText();
  65. void drawOverlinedText();
  66. void drawUnderlinedText();
  67. void drawRightToLeft();
  68. void detach();
  69. void setRawData();
  70. void setRawDataAndGetAsVector();
  71. private:
  72. int m_testFontId;
  73. QFont m_testFont;
  74. #endif // QT_NO_RAWFONT
  75. };
  76. #if !defined(QT_NO_RAWFONT)
  77. Q_DECLARE_METATYPE(QGlyphRun);
  78. void tst_QGlyphRun::initTestCase()
  79. {
  80. m_testFontId = QFontDatabase::addApplicationFont(SRCDIR "test.ttf");
  81. QVERIFY(m_testFontId >= 0);
  82. m_testFont = QFont("QtsSpecialTestFont");
  83. QCOMPARE(QFontInfo(m_testFont).family(), QString::fromLatin1("QtsSpecialTestFont"));
  84. }
  85. void tst_QGlyphRun::cleanupTestCase()
  86. {
  87. QFontDatabase::removeApplicationFont(m_testFontId);
  88. }
  89. void tst_QGlyphRun::constructionAndDestruction()
  90. {
  91. QGlyphRun glyphIndexes;
  92. }
  93. static QGlyphRun make_dummy_indexes()
  94. {
  95. QGlyphRun glyphs;
  96. QVector<quint32> glyphIndexes;
  97. QVector<QPointF> positions;
  98. QFont font;
  99. font.setPointSize(18);
  100. glyphIndexes.append(1);
  101. glyphIndexes.append(2);
  102. glyphIndexes.append(3);
  103. positions.append(QPointF(1, 2));
  104. positions.append(QPointF(3, 4));
  105. positions.append(QPointF(5, 6));
  106. glyphs.setRawFont(QRawFont::fromFont(font));
  107. glyphs.setGlyphIndexes(glyphIndexes);
  108. glyphs.setPositions(positions);
  109. return glyphs;
  110. }
  111. void tst_QGlyphRun::copyConstructor()
  112. {
  113. QGlyphRun glyphs;
  114. {
  115. QVector<quint32> glyphIndexes;
  116. QVector<QPointF> positions;
  117. QFont font;
  118. font.setPointSize(18);
  119. glyphIndexes.append(1);
  120. glyphIndexes.append(2);
  121. glyphIndexes.append(3);
  122. positions.append(QPointF(1, 2));
  123. positions.append(QPointF(3, 4));
  124. positions.append(QPointF(5, 6));
  125. glyphs.setRawFont(QRawFont::fromFont(font));
  126. glyphs.setGlyphIndexes(glyphIndexes);
  127. glyphs.setPositions(positions);
  128. }
  129. QGlyphRun otherGlyphs(glyphs);
  130. QCOMPARE(otherGlyphs.rawFont(), glyphs.rawFont());
  131. QCOMPARE(glyphs.glyphIndexes(), otherGlyphs.glyphIndexes());
  132. QCOMPARE(glyphs.positions(), otherGlyphs.positions());
  133. }
  134. void tst_QGlyphRun::assignment()
  135. {
  136. QGlyphRun glyphs(make_dummy_indexes());
  137. QGlyphRun otherGlyphs = glyphs;
  138. QCOMPARE(otherGlyphs.rawFont(), glyphs.rawFont());
  139. QCOMPARE(glyphs.glyphIndexes(), otherGlyphs.glyphIndexes());
  140. QCOMPARE(glyphs.positions(), otherGlyphs.positions());
  141. }
  142. void tst_QGlyphRun::equalsOperator_data()
  143. {
  144. QTest::addColumn<QGlyphRun>("one");
  145. QTest::addColumn<QGlyphRun>("two");
  146. QTest::addColumn<bool>("equals");
  147. QGlyphRun one(make_dummy_indexes());
  148. QGlyphRun two(make_dummy_indexes());
  149. QTest::newRow("Identical") << one << two << true;
  150. {
  151. QGlyphRun busted(two);
  152. QVector<QPointF> positions = busted.positions();
  153. positions[2] += QPointF(1, 1);
  154. busted.setPositions(positions);
  155. QTest::newRow("Different positions") << one << busted << false;
  156. }
  157. {
  158. QGlyphRun busted(two);
  159. QFont font;
  160. font.setPixelSize(busted.rawFont().pixelSize() * 2);
  161. busted.setRawFont(QRawFont::fromFont(font));
  162. QTest::newRow("Different fonts") << one << busted << false;
  163. }
  164. {
  165. QGlyphRun busted(two);
  166. QVector<quint32> glyphIndexes = busted.glyphIndexes();
  167. glyphIndexes[2] += 1;
  168. busted.setGlyphIndexes(glyphIndexes);
  169. QTest::newRow("Different glyph indexes") << one << busted << false;
  170. }
  171. }
  172. void tst_QGlyphRun::equalsOperator()
  173. {
  174. QFETCH(QGlyphRun, one);
  175. QFETCH(QGlyphRun, two);
  176. QFETCH(bool, equals);
  177. QCOMPARE(one == two, equals);
  178. QCOMPARE(one != two, !equals);
  179. }
  180. void tst_QGlyphRun::textLayoutGlyphIndexes()
  181. {
  182. QString s;
  183. s.append(QLatin1Char('A'));
  184. s.append(QChar(0xe000));
  185. QTextLayout layout(s);
  186. layout.setFont(m_testFont);
  187. layout.beginLayout();
  188. layout.createLine();
  189. layout.endLayout();
  190. QList<QGlyphRun> listOfGlyphs = layout.glyphRuns();
  191. QCOMPARE(listOfGlyphs.size(), 1);
  192. QGlyphRun glyphs = listOfGlyphs.at(0);
  193. QCOMPARE(glyphs.glyphIndexes().size(), 2);
  194. QCOMPARE(glyphs.glyphIndexes().at(0), quint32(2));
  195. QCOMPARE(glyphs.glyphIndexes().at(1), quint32(1));
  196. }
  197. void tst_QGlyphRun::drawExistingGlyphs()
  198. {
  199. QPixmap textLayoutDraw(1000, 1000);
  200. QPixmap drawGlyphs(1000, 1000);
  201. textLayoutDraw.fill(Qt::white);
  202. drawGlyphs.fill(Qt::white);
  203. QString s;
  204. s.append(QLatin1Char('A'));
  205. s.append(QChar(0xe000));
  206. QTextLayout layout(s);
  207. layout.setFont(m_testFont);
  208. layout.beginLayout();
  209. layout.createLine();
  210. layout.endLayout();
  211. {
  212. QPainter p(&textLayoutDraw);
  213. layout.draw(&p, QPointF(50, 50));
  214. }
  215. QGlyphRun glyphs = layout.glyphRuns().size() > 0
  216. ? layout.glyphRuns().at(0)
  217. : QGlyphRun();
  218. {
  219. QPainter p(&drawGlyphs);
  220. p.drawGlyphRun(QPointF(50, 50), glyphs);
  221. }
  222. #if defined(DEBUG_SAVE_IMAGE)
  223. textLayoutDraw.save("drawExistingGlyphs_textLayoutDraw.png");
  224. drawGlyphs.save("drawExistingGlyphs_drawGlyphIndexes.png");
  225. #endif
  226. QCOMPARE(textLayoutDraw, drawGlyphs);
  227. }
  228. void tst_QGlyphRun::setRawData()
  229. {
  230. QGlyphRun glyphRun;
  231. glyphRun.setRawFont(QRawFont::fromFont(m_testFont));
  232. glyphRun.setGlyphIndexes(QVector<quint32>() << 2 << 2 << 2);
  233. glyphRun.setPositions(QVector<QPointF>() << QPointF(2, 3) << QPointF(20, 3) << QPointF(10, 20));
  234. QPixmap baseline(100, 50);
  235. baseline.fill(Qt::white);
  236. {
  237. QPainter p(&baseline);
  238. p.drawGlyphRun(QPointF(3, 2), glyphRun);
  239. }
  240. QGlyphRun baselineCopied = glyphRun;
  241. quint32 glyphIndexArray[3] = { 2, 2, 2 };
  242. QPointF glyphPositionArray[3] = { QPointF(2, 3), QPointF(20, 3), QPointF(10, 20) };
  243. glyphRun.setRawData(glyphIndexArray, glyphPositionArray, 3);
  244. QPixmap rawDataGlyphs(100, 50);
  245. rawDataGlyphs.fill(Qt::white);
  246. {
  247. QPainter p(&rawDataGlyphs);
  248. p.drawGlyphRun(QPointF(3, 2), glyphRun);
  249. }
  250. quint32 otherGlyphIndexArray[1] = { 2 };
  251. QPointF otherGlyphPositionArray[1] = { QPointF(2, 3) };
  252. glyphRun.setRawData(otherGlyphIndexArray, otherGlyphPositionArray, 1);
  253. QPixmap baselineCopiedPixmap(100, 50);
  254. baselineCopiedPixmap.fill(Qt::white);
  255. {
  256. QPainter p(&baselineCopiedPixmap);
  257. p.drawGlyphRun(QPointF(3, 2), baselineCopied);
  258. }
  259. #if defined(DEBUG_SAVE_IMAGE)
  260. baseline.save("setRawData_baseline.png");
  261. rawDataGlyphs.save("setRawData_rawDataGlyphs.png");
  262. baselineCopiedPixmap.save("setRawData_baselineCopiedPixmap.png");
  263. #endif
  264. QCOMPARE(rawDataGlyphs, baseline);
  265. QCOMPARE(baselineCopiedPixmap, baseline);
  266. }
  267. void tst_QGlyphRun::setRawDataAndGetAsVector()
  268. {
  269. QVector<quint32> glyphIndexArray;
  270. glyphIndexArray << 3 << 2 << 1 << 4;
  271. QVector<QPointF> glyphPositionArray;
  272. glyphPositionArray << QPointF(1, 2) << QPointF(3, 4) << QPointF(5, 6) << QPointF(7, 8);
  273. QGlyphRun glyphRun;
  274. glyphRun.setRawData(glyphIndexArray.constData(), glyphPositionArray.constData(), 4);
  275. QVector<quint32> glyphIndexes = glyphRun.glyphIndexes();
  276. QVector<QPointF> glyphPositions = glyphRun.positions();
  277. QCOMPARE(glyphIndexes.size(), 4);
  278. QCOMPARE(glyphPositions.size(), 4);
  279. QCOMPARE(glyphIndexes, glyphIndexArray);
  280. QCOMPARE(glyphPositions, glyphPositionArray);
  281. QGlyphRun otherGlyphRun;
  282. otherGlyphRun.setGlyphIndexes(glyphIndexArray);
  283. otherGlyphRun.setPositions(glyphPositionArray);
  284. QCOMPARE(glyphRun, otherGlyphRun);
  285. }
  286. void tst_QGlyphRun::drawNonExistentGlyphs()
  287. {
  288. QVector<quint32> glyphIndexes;
  289. glyphIndexes.append(3);
  290. QVector<QPointF> glyphPositions;
  291. glyphPositions.append(QPointF(0, 0));
  292. QGlyphRun glyphs;
  293. glyphs.setGlyphIndexes(glyphIndexes);
  294. glyphs.setPositions(glyphPositions);
  295. glyphs.setRawFont(QRawFont::fromFont(m_testFont));
  296. QPixmap image(1000, 1000);
  297. image.fill(Qt::white);
  298. QPixmap imageBefore = image;
  299. {
  300. QPainter p(&image);
  301. p.drawGlyphRun(QPointF(50, 50), glyphs);
  302. }
  303. #if defined(DEBUG_SAVE_IMAGE)
  304. image.save("drawNonExistentGlyphs.png");
  305. #endif
  306. QCOMPARE(image, imageBefore); // Should be unchanged
  307. }
  308. void tst_QGlyphRun::drawMultiScriptText1()
  309. {
  310. QString text;
  311. text += QChar(0x03D0); // Greek, beta
  312. QTextLayout textLayout(text);
  313. textLayout.beginLayout();
  314. textLayout.createLine();
  315. textLayout.endLayout();
  316. QPixmap textLayoutDraw(1000, 1000);
  317. textLayoutDraw.fill(Qt::white);
  318. QPixmap drawGlyphs(1000, 1000);
  319. drawGlyphs.fill(Qt::white);
  320. QList<QGlyphRun> glyphsList = textLayout.glyphRuns();
  321. QCOMPARE(glyphsList.size(), 1);
  322. {
  323. QPainter p(&textLayoutDraw);
  324. textLayout.draw(&p, QPointF(50, 50));
  325. }
  326. {
  327. QPainter p(&drawGlyphs);
  328. foreach (QGlyphRun glyphs, glyphsList)
  329. p.drawGlyphRun(QPointF(50, 50), glyphs);
  330. }
  331. #if defined(DEBUG_SAVE_IMAGE)
  332. textLayoutDraw.save("drawMultiScriptText1_textLayoutDraw.png");
  333. drawGlyphs.save("drawMultiScriptText1_drawGlyphIndexes.png");
  334. #endif
  335. QCOMPARE(drawGlyphs, textLayoutDraw);
  336. }
  337. void tst_QGlyphRun::drawMultiScriptText2()
  338. {
  339. QString text;
  340. text += QChar(0x0621); // Arabic, Hamza
  341. text += QChar(0x03D0); // Greek, beta
  342. QTextLayout textLayout(text);
  343. textLayout.beginLayout();
  344. textLayout.createLine();
  345. textLayout.endLayout();
  346. QPixmap textLayoutDraw(1000, 1000);
  347. textLayoutDraw.fill(Qt::white);
  348. QPixmap drawGlyphs(1000, 1000);
  349. drawGlyphs.fill(Qt::white);
  350. QList<QGlyphRun> glyphsList = textLayout.glyphRuns();
  351. QCOMPARE(glyphsList.size(), 2);
  352. {
  353. QPainter p(&textLayoutDraw);
  354. textLayout.draw(&p, QPointF(50, 50));
  355. }
  356. {
  357. QPainter p(&drawGlyphs);
  358. foreach (QGlyphRun glyphs, glyphsList)
  359. p.drawGlyphRun(QPointF(50, 50), glyphs);
  360. }
  361. #if defined(DEBUG_SAVE_IMAGE)
  362. textLayoutDraw.save("drawMultiScriptText2_textLayoutDraw.png");
  363. drawGlyphs.save("drawMultiScriptText2_drawGlyphIndexes.png");
  364. #endif
  365. QCOMPARE(drawGlyphs, textLayoutDraw);
  366. }
  367. void tst_QGlyphRun::detach()
  368. {
  369. QGlyphRun glyphs;
  370. glyphs.setGlyphIndexes(QVector<quint32>() << 1 << 2 << 3);
  371. QGlyphRun otherGlyphs;
  372. otherGlyphs = glyphs;
  373. QCOMPARE(otherGlyphs.glyphIndexes(), glyphs.glyphIndexes());
  374. otherGlyphs.setGlyphIndexes(QVector<quint32>() << 4 << 5 << 6);
  375. QCOMPARE(otherGlyphs.glyphIndexes(), QVector<quint32>() << 4 << 5 << 6);
  376. QCOMPARE(glyphs.glyphIndexes(), QVector<quint32>() << 1 << 2 << 3);
  377. }
  378. void tst_QGlyphRun::drawStruckOutText()
  379. {
  380. QPixmap textLayoutDraw(1000, 1000);
  381. QPixmap drawGlyphs(1000, 1000);
  382. textLayoutDraw.fill(Qt::white);
  383. drawGlyphs.fill(Qt::white);
  384. QString s = QString::fromLatin1("Foobar");
  385. QFont font;
  386. font.setStrikeOut(true);
  387. QTextLayout layout(s);
  388. layout.setFont(font);
  389. layout.beginLayout();
  390. layout.createLine();
  391. layout.endLayout();
  392. {
  393. QPainter p(&textLayoutDraw);
  394. layout.draw(&p, QPointF(50, 50));
  395. }
  396. QGlyphRun glyphs = layout.glyphRuns().size() > 0
  397. ? layout.glyphRuns().at(0)
  398. : QGlyphRun();
  399. {
  400. QPainter p(&drawGlyphs);
  401. p.drawGlyphRun(QPointF(50, 50), glyphs);
  402. }
  403. #if defined(DEBUG_SAVE_IMAGE)
  404. textLayoutDraw.save("drawStruckOutText_textLayoutDraw.png");
  405. drawGlyphs.save("drawStruckOutText_drawGlyphIndexes.png");
  406. #endif
  407. QCOMPARE(textLayoutDraw, drawGlyphs);
  408. }
  409. void tst_QGlyphRun::drawOverlinedText()
  410. {
  411. QPixmap textLayoutDraw(1000, 1000);
  412. QPixmap drawGlyphs(1000, 1000);
  413. textLayoutDraw.fill(Qt::white);
  414. drawGlyphs.fill(Qt::white);
  415. QString s = QString::fromLatin1("Foobar");
  416. QFont font;
  417. font.setOverline(true);
  418. QTextLayout layout(s);
  419. layout.setFont(font);
  420. layout.beginLayout();
  421. layout.createLine();
  422. layout.endLayout();
  423. {
  424. QPainter p(&textLayoutDraw);
  425. layout.draw(&p, QPointF(50, 50));
  426. }
  427. QGlyphRun glyphs = layout.glyphRuns().size() > 0
  428. ? layout.glyphRuns().at(0)
  429. : QGlyphRun();
  430. {
  431. QPainter p(&drawGlyphs);
  432. p.drawGlyphRun(QPointF(50, 50), glyphs);
  433. }
  434. #if defined(DEBUG_SAVE_IMAGE)
  435. textLayoutDraw.save("drawOverlineText_textLayoutDraw.png");
  436. drawGlyphs.save("drawOverlineText_drawGlyphIndexes.png");
  437. #endif
  438. QCOMPARE(textLayoutDraw, drawGlyphs);
  439. }
  440. void tst_QGlyphRun::drawUnderlinedText()
  441. {
  442. QPixmap textLayoutDraw(1000, 1000);
  443. QPixmap drawGlyphs(1000, 1000);
  444. textLayoutDraw.fill(Qt::white);
  445. drawGlyphs.fill(Qt::white);
  446. QString s = QString::fromLatin1("Foobar");
  447. QFont font;
  448. font.setUnderline(true);
  449. QTextLayout layout(s);
  450. layout.setFont(font);
  451. layout.beginLayout();
  452. layout.createLine();
  453. layout.endLayout();
  454. {
  455. QPainter p(&textLayoutDraw);
  456. layout.draw(&p, QPointF(50, 50));
  457. }
  458. QGlyphRun glyphs = layout.glyphRuns().size() > 0
  459. ? layout.glyphRuns().at(0)
  460. : QGlyphRun();
  461. {
  462. QPainter p(&drawGlyphs);
  463. p.drawGlyphRun(QPointF(50, 50), glyphs);
  464. }
  465. #if defined(DEBUG_SAVE_IMAGE)
  466. textLayoutDraw.save("drawUnderlineText_textLayoutDraw.png");
  467. drawGlyphs.save("drawUnderlineText_drawGlyphIndexes.png");
  468. #endif
  469. QCOMPARE(textLayoutDraw, drawGlyphs);
  470. }
  471. void tst_QGlyphRun::drawRightToLeft()
  472. {
  473. QString s;
  474. s.append(QChar(1575));
  475. s.append(QChar(1578));
  476. QPixmap textLayoutDraw(1000, 1000);
  477. QPixmap drawGlyphs(1000, 1000);
  478. textLayoutDraw.fill(Qt::white);
  479. drawGlyphs.fill(Qt::white);
  480. QFont font;
  481. font.setUnderline(true);
  482. QTextLayout layout(s);
  483. layout.setFont(font);
  484. layout.beginLayout();
  485. layout.createLine();
  486. layout.endLayout();
  487. {
  488. QPainter p(&textLayoutDraw);
  489. layout.draw(&p, QPointF(50, 50));
  490. }
  491. QGlyphRun glyphs = layout.glyphRuns().size() > 0
  492. ? layout.glyphRuns().at(0)
  493. : QGlyphRun();
  494. {
  495. QPainter p(&drawGlyphs);
  496. p.drawGlyphRun(QPointF(50, 50), glyphs);
  497. }
  498. #if defined(DEBUG_SAVE_IMAGE)
  499. textLayoutDraw.save("drawRightToLeft_textLayoutDraw.png");
  500. drawGlyphs.save("drawRightToLeft_drawGlyphIndexes.png");
  501. #endif
  502. QCOMPARE(textLayoutDraw, drawGlyphs);
  503. }
  504. #endif // QT_NO_RAWFONT
  505. QTEST_MAIN(tst_QGlyphRun)
  506. #include "tst_qglyphrun.moc"