diff options
Diffstat (limited to 'tests/auto/gui')
-rw-r--r-- | tests/auto/gui/image/qimage/tst_qimage.cpp | 21 | ||||
-rw-r--r-- | tests/auto/gui/kernel/qevent/tst_qevent.cpp | 30 | ||||
-rw-r--r-- | tests/auto/gui/kernel/qwindow/tst_qwindow.cpp | 54 | ||||
-rw-r--r-- | tests/auto/gui/qopengl/tst_qopengl.cpp | 88 | ||||
-rw-r--r-- | tests/auto/gui/text/qfont/tst_qfont.cpp | 34 | ||||
-rw-r--r-- | tests/auto/gui/text/qfontdatabase/FreeMono.ttf | bin | 267400 -> 0 bytes | |||
-rw-r--r-- | tests/auto/gui/text/qfontdatabase/LED_REAL.TTF | bin | 0 -> 4708 bytes | |||
-rw-r--r-- | tests/auto/gui/text/qfontdatabase/LED_REAL_readme.txt | 34 | ||||
-rw-r--r-- | tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp | 2 | ||||
-rw-r--r-- | tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp | 287 |
10 files changed, 364 insertions, 186 deletions
diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index 01a56883bf..95a9b142ec 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -168,6 +168,8 @@ private slots: void convertOverUnPreMul(); + void scaled_QTBUG35972(); + void cleanupFunctions(); }; @@ -2439,6 +2441,25 @@ void tst_QImage::convertOverUnPreMul() } } +void tst_QImage::scaled_QTBUG35972() +{ + QImage src(532,519,QImage::Format_ARGB32_Premultiplied); + src.fill(QColor(Qt::white)); + QImage dest(1000,1000,QImage::Format_ARGB32_Premultiplied); + dest.fill(QColor(Qt::white)); + QPainter painter1(&dest); + const QTransform trf(1.25, 0, + 0, 1.25, + /*dx */ 15.900000000000034, /* dy */ 72.749999999999986); + painter1.setTransform(trf); + painter1.drawImage(QRectF(-2.6, -2.6, 425.6, 415.20000000000005), src, QRectF(0,0,532,519)); + + const quint32 *pixels = reinterpret_cast<const quint32 *>(dest.constBits()); + int size = dest.width()*dest.height(); + for (int i = 0; i < size; ++i) + QCOMPARE(pixels[i], 0xffffffff); +} + static void cleanupFunction(void* info) { bool *called = static_cast<bool*>(info); diff --git a/tests/auto/gui/kernel/qevent/tst_qevent.cpp b/tests/auto/gui/kernel/qevent/tst_qevent.cpp index 3865eb00da..73f9486752 100644 --- a/tests/auto/gui/kernel/qevent/tst_qevent.cpp +++ b/tests/auto/gui/kernel/qevent/tst_qevent.cpp @@ -55,9 +55,14 @@ public: private slots: void registerEventType_data(); void registerEventType(); + void exhaustEventTypeRegistration(); // keep behind registerEventType() test + +private: + bool registerEventTypeSucceeded; // track success of registerEventType for use by exhaustEventTypeRegistration() }; tst_QEvent::tst_QEvent() + : registerEventTypeSucceeded(true) { } tst_QEvent::~tst_QEvent() @@ -72,17 +77,40 @@ void tst_QEvent::registerEventType_data() QTest::newRow("default") << -1 << int(QEvent::MaxUser); // hint not valid QTest::newRow("User-1") << int(QEvent::User - 1) << int(QEvent::MaxUser - 1); + // hint not valid II + QTest::newRow("MaxUser+1") << int(QEvent::MaxUser + 1) << int(QEvent::MaxUser - 2); // hint valid, but already taken - QTest::newRow("MaxUser-1") << int(QEvent::MaxUser - 1) << int(QEvent::MaxUser - 2); + QTest::newRow("MaxUser-1") << int(QEvent::MaxUser - 1) << int(QEvent::MaxUser - 3); // hint valid, but not taken QTest::newRow("User + 1000") << int(QEvent::User + 1000) << int(QEvent::User + 1000); } void tst_QEvent::registerEventType() { + const bool oldRegisterEventTypeSucceeded = registerEventTypeSucceeded; + registerEventTypeSucceeded = false; QFETCH(int, hint); QFETCH(int, expected); QCOMPARE(QEvent::registerEventType(hint), expected); + registerEventTypeSucceeded = oldRegisterEventTypeSucceeded; +} + +void tst_QEvent::exhaustEventTypeRegistration() +{ + if (!registerEventTypeSucceeded) + QSKIP("requires the previous test (registerEventType) to have finished successfully"); + + int i = QEvent::User; + int result; + while ((result = QEvent::registerEventType(i)) == i) + ++i; + QCOMPARE(i, int(QEvent::User + 1000)); + QCOMPARE(result, int(QEvent::MaxUser - 4)); + i = QEvent::User + 1001; + while ((result = QEvent::registerEventType(i)) == i) + ++i; + QCOMPARE(result, -1); + QCOMPARE(i, int(QEvent::MaxUser - 4)); } QTEST_MAIN(tst_QEvent) diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp index da142c80a6..eefa85a745 100644 --- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp +++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp @@ -49,6 +49,10 @@ #include <QEvent> #include <QStyleHints> +#if defined(Q_OS_QNX) +#include <QOpenGLContext> +#endif + // For QSignalSpy slot connections. Q_DECLARE_METATYPE(Qt::ScreenOrientation) Q_DECLARE_METATYPE(QWindow::Visibility) @@ -122,6 +126,9 @@ public: { reset(); setFlags(flags); +#if defined(Q_OS_QNX) + setSurfaceType(QSurface::OpenGLSurface); +#endif } void reset() @@ -187,7 +194,12 @@ void tst_QWindow::resizeEventAfterResize() // Make sure we get a resizeEvent after calling resize window.resize(400, 100); +#if defined(Q_OS_BLACKBERRY) // "window" is the "root" window and will always be shown fullscreen + // so we only expect one resize event + QTRY_COMPARE(window.received(QEvent::Resize), 1); +#else QTRY_COMPARE(window.received(QEvent::Resize), 2); +#endif } void tst_QWindow::positioning_data() @@ -244,13 +256,24 @@ void tst_QWindow::positioning() window.setWindowState(Qt::WindowFullScreen); QCoreApplication::processEvents(); +#if defined(Q_OS_BLACKBERRY) // "window" is the "root" window and will always be shown fullscreen + // so we only expect one resize event + Q_UNUSED(resizecount); + QTRY_COMPARE(window.received(QEvent::Resize), 1); +#else QTRY_COMPARE(window.received(QEvent::Resize), 2); +#endif QTest::qWait(2000); window.setWindowState(Qt::WindowNoState); QCoreApplication::processEvents(); +#if defined(Q_OS_BLACKBERRY) // "window" is the "root" window and will always be shown fullscreen + // so we only expect one resize event + QTRY_COMPARE(window.received(QEvent::Resize), 1); +#else QTRY_COMPARE(window.received(QEvent::Resize), resizecount); +#endif QTRY_COMPARE(originalPos, window.position()); QTRY_COMPARE(originalFramePos, window.framePosition()); @@ -309,6 +332,13 @@ void tst_QWindow::isActive() QCoreApplication::processEvents(); QTRY_VERIFY(window.isExposed()); +#if defined(Q_OS_QNX) // We either need to create a eglSurface or a create a backing store + // and then post the window in order for screen to show the window + QOpenGLContext context; + context.create(); + context.makeCurrent(&window); + context.swapBuffers(&window); +#endif QTRY_COMPARE(window.received(QEvent::Resize), 1); QTRY_VERIFY(QGuiApplication::focusWindow() == &window); QVERIFY(window.isActive()); @@ -511,7 +541,7 @@ void tst_QWindow::testInputEvents() // Now with null pointer as window. local param should not be utilized: // handleMouseEvent() with tlw == 0 means the event is in global coords only. window.mousePressButton = window.mouseReleaseButton = 0; - QPointF nonWindowGlobal(500, 500); // not inside the window + QPointF nonWindowGlobal(2000, 500); // not inside the window QWindowSystemInterface::handleMouseEvent(0, nonWindowGlobal, nonWindowGlobal, Qt::LeftButton); QWindowSystemInterface::handleMouseEvent(0, nonWindowGlobal, nonWindowGlobal, Qt::NoButton); QCoreApplication::processEvents(); @@ -913,10 +943,21 @@ void tst_QWindow::activateAndClose() { for (int i = 0; i < 10; ++i) { QWindow window; +#if defined(Q_OS_QNX) + window.setSurfaceType(QSurface::OpenGLSurface); +#endif // qWaitForWindowActive will block for the duration of // of the timeout if the window is at 0,0 window.setGeometry(QGuiApplication::primaryScreen()->availableGeometry().adjusted(1, 1, -1, -1)); window.showNormal(); +#if defined(Q_OS_QNX) // We either need to create a eglSurface or a create a backing store + // and then post the window in order for screen to show the window + QTest::qWaitForWindowExposed(&window); + QOpenGLContext context; + context.create(); + context.makeCurrent(&window); + context.swapBuffers(&window); +#endif window.requestActivate(); QVERIFY(QTest::qWaitForWindowActive(&window)); QCOMPARE(qGuiApp->focusWindow(), &window); @@ -1252,15 +1293,26 @@ void tst_QWindow::initialSize() Window w; w.setWidth(200); w.show(); +#if defined(Q_OS_BLACKBERRY) // "window" is the "root" window and will always be shown fullscreen + // so we only expect one resize event + QTRY_COMPARE(w.width(), qGuiApp->primaryScreen()->availableGeometry().width()); +#else QTRY_COMPARE(w.width(), 200); +#endif QTRY_VERIFY(w.height() > 0); } { Window w; w.resize(200, 42); w.show(); +#if defined(Q_OS_BLACKBERRY) // "window" is the "root" window and will always be shown fullscreen + // so we only expect one resize event + QTRY_COMPARE(w.width(), qGuiApp->primaryScreen()->availableGeometry().width()); + QTRY_COMPARE(w.height(), qGuiApp->primaryScreen()->availableGeometry().height()); +#else QTRY_COMPARE(w.width(), 200); QTRY_COMPARE(w.height(), 42); +#endif } } diff --git a/tests/auto/gui/qopengl/tst_qopengl.cpp b/tests/auto/gui/qopengl/tst_qopengl.cpp index 4018c00a38..63fe8b9693 100644 --- a/tests/auto/gui/qopengl/tst_qopengl.cpp +++ b/tests/auto/gui/qopengl/tst_qopengl.cpp @@ -157,7 +157,22 @@ static QSurface *createSurface(int surfaceClass) window->create(); return window; } else if (surfaceClass == int(QSurface::Offscreen)) { + // Create a window and get the format from that. For example, if an EGL + // implementation provides 565 and 888 configs for PBUFFER_BIT but only + // 888 for WINDOW_BIT, we may end up with a pbuffer surface that is + // incompatible with the context since it could choose the 565 while the + // window and the context uses a config with 888. + static QSurfaceFormat format; + if (format.redBufferSize() == -1) { + QWindow *window = new QWindow; + window->setSurfaceType(QWindow::OpenGLSurface); + window->setGeometry(0, 0, 10, 10); + window->create(); + format = window->format(); + delete window; + } QOffscreenSurface *offscreenSurface = new QOffscreenSurface; + offscreenSurface->setFormat(format); offscreenSurface->create(); return offscreenSurface; } @@ -392,6 +407,10 @@ void qt_opengl_check_test_pattern(const QImage& img) // As we're doing more than trivial painting, we can't just compare to // an image rendered with raster. Instead, we sample at well-defined // test-points: + QVERIFY(!img.isNull()); + QVERIFY2(img.width() > 217, QByteArray::number(img.width())); + QVERIFY2(img.height() > 90, QByteArray::number(img.height())); + QFUZZY_COMPARE_PIXELS(img.pixel(39, 64), QColor(Qt::red).rgb()); QFUZZY_COMPARE_PIXELS(img.pixel(89, 64), QColor(Qt::red).rgb()); QFUZZY_COMPARE_PIXELS(img.pixel(64, 39), QColor(Qt::blue).rgb()); @@ -415,7 +434,7 @@ void tst_QOpenGL::fboSimpleRendering() QOpenGLContext ctx; QVERIFY(ctx.create()); - ctx.makeCurrent(surface.data()); + QVERIFY(ctx.makeCurrent(surface.data())); if (!QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()) QSKIP("QOpenGLFramebufferObject not supported on this platform"); @@ -424,21 +443,21 @@ void tst_QOpenGL::fboSimpleRendering() QOpenGLFramebufferObjectFormat fboFormat; fboFormat.setAttachment(QOpenGLFramebufferObject::NoAttachment); - QOpenGLFramebufferObject *fbo = new QOpenGLFramebufferObject(200, 100, fboFormat); + const QSize size(200, 100); + QScopedPointer<QOpenGLFramebufferObject> fbo(new QOpenGLFramebufferObject(size, fboFormat)); - fbo->bind(); + QVERIFY(fbo->bind()); glClearColor(1.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); glFinish(); - QImage fb = fbo->toImage().convertToFormat(QImage::Format_RGB32); - QImage reference(fb.size(), QImage::Format_RGB32); + const QImage fb = fbo->toImage().convertToFormat(QImage::Format_RGB32); + QCOMPARE(fb.size(), size); + QImage reference(size, QImage::Format_RGB32); reference.fill(0xffff0000); QFUZZY_COMPARE_IMAGES(fb, reference); - - delete fbo; } void tst_QOpenGL::fboTextureOwnership_data() @@ -511,7 +530,7 @@ void tst_QOpenGL::fboRendering() QOpenGLContext ctx; QVERIFY(ctx.create()); - ctx.makeCurrent(surface.data()); + QVERIFY(ctx.makeCurrent(surface.data())); if (!QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()) QSKIP("QOpenGLFramebufferObject not supported on this platform"); @@ -521,12 +540,13 @@ void tst_QOpenGL::fboRendering() fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); // Uncomplicate things by using NPOT: - QOpenGLFramebufferObject fbo(256, 128, fboFormat); + const QSize size(256, 128); + QOpenGLFramebufferObject fbo(size, fboFormat); if (fbo.attachment() != QOpenGLFramebufferObject::CombinedDepthStencil) QSKIP("FBOs missing combined depth~stencil support"); - fbo.bind(); + QVERIFY(fbo.bind()); QPainter fboPainter; QOpenGLPaintDevice device(fbo.width(), fbo.height()); @@ -537,7 +557,8 @@ void tst_QOpenGL::fboRendering() fboPainter.end(); - QImage fb = fbo.toImage().convertToFormat(QImage::Format_RGB32); + const QImage fb = fbo.toImage().convertToFormat(QImage::Format_RGB32); + QCOMPARE(fb.size(), size); qt_opengl_check_test_pattern(fb); } @@ -588,9 +609,11 @@ void tst_QOpenGL::openGLPaintDevice() QSurfaceFormat format = ctx.format(); if (format.majorVersion() < 2) QSKIP("This test requires at least OpenGL 2.0"); - ctx.makeCurrent(surface.data()); + QVERIFY(ctx.makeCurrent(surface.data())); - QImage image(128, 128, QImage::Format_RGB32); + const QSize size(128, 128); + + QImage image(size, QImage::Format_RGB32); QPainter p(&image); p.fillRect(0, 0, image.width() / 2, image.height() / 2, Qt::red); p.fillRect(image.width() / 2, 0, image.width() / 2, image.height() / 2, Qt::green); @@ -598,32 +621,38 @@ void tst_QOpenGL::openGLPaintDevice() p.fillRect(0, image.height() / 2, image.width() / 2, image.height() / 2, Qt::white); p.end(); - QOpenGLFramebufferObject fbo(128, 128); - fbo.bind(); + QOpenGLFramebufferObject fbo(size); + QVERIFY(fbo.bind()); - QOpenGLPaintDevice device(128, 128); - p.begin(&device); + QOpenGLPaintDevice device(size); + QVERIFY(p.begin(&device)); p.fillRect(0, 0, image.width() / 2, image.height() / 2, Qt::red); p.fillRect(image.width() / 2, 0, image.width() / 2, image.height() / 2, Qt::green); p.fillRect(image.width() / 2, image.height() / 2, image.width() / 2, image.height() / 2, Qt::blue); p.fillRect(0, image.height() / 2, image.width() / 2, image.height() / 2, Qt::white); p.end(); - QCOMPARE(image, fbo.toImage().convertToFormat(QImage::Format_RGB32)); + QImage actual = fbo.toImage().convertToFormat(QImage::Format_RGB32); + QCOMPARE(image.size(), actual.size()); + QCOMPARE(image, actual); - p.begin(&device); + QVERIFY(p.begin(&device)); p.fillRect(0, 0, image.width(), image.height(), Qt::black); p.drawImage(0, 0, image); p.end(); - QCOMPARE(image, fbo.toImage().convertToFormat(QImage::Format_RGB32)); + actual = fbo.toImage().convertToFormat(QImage::Format_RGB32); + QCOMPARE(image.size(), actual.size()); + QCOMPARE(image, actual); - p.begin(&device); + QVERIFY(p.begin(&device)); p.fillRect(0, 0, image.width(), image.height(), Qt::black); p.fillRect(0, 0, image.width(), image.height(), QBrush(image)); p.end(); - QCOMPARE(image, fbo.toImage().convertToFormat(QImage::Format_RGB32)); + actual = fbo.toImage().convertToFormat(QImage::Format_RGB32); + QCOMPARE(image.size(), actual.size()); + QCOMPARE(image, actual); } void tst_QOpenGL::aboutToBeDestroyed() @@ -689,9 +718,11 @@ void tst_QOpenGL::QTBUG15621_triangulatingStrokerDivZero() QSKIP("QTBUG-22617"); #endif + const QSize size(128, 128); + QWindow window; window.setSurfaceType(QWindow::OpenGLSurface); - window.setGeometry(0, 0, 128, 128); + window.setGeometry(QRect(QPoint(0, 0), size)); window.create(); QOpenGLContext ctx; @@ -701,10 +732,10 @@ void tst_QOpenGL::QTBUG15621_triangulatingStrokerDivZero() if (!QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()) QSKIP("QOpenGLFramebufferObject not supported on this platform"); - QOpenGLFramebufferObject fbo(128, 128); - fbo.bind(); + QOpenGLFramebufferObject fbo(size); + QVERIFY(fbo.bind()); - QOpenGLPaintDevice device(128, 128); + QOpenGLPaintDevice device(size); // QTBUG-15621 is only a problem when qreal is double, but do the test anyway. qreal delta = sizeof(qreal) == sizeof(float) ? 1e-4 : 1e-8; @@ -731,10 +762,11 @@ void tst_QOpenGL::QTBUG15621_triangulatingStrokerDivZero() QPen pen(Qt::red, 28, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin); QPainter p(&device); - p.fillRect(QRect(0, 0, 128, 128), Qt::blue); + p.fillRect(QRect(QPoint(0, 0), size), Qt::blue); p.strokePath(path, pen); p.end(); - QImage image = fbo.toImage().convertToFormat(QImage::Format_RGB32); + const QImage image = fbo.toImage().convertToFormat(QImage::Format_RGB32); + QCOMPARE(image.size(), size); const QRgb red = 0xffff0000; const QRgb blue = 0xff0000ff; diff --git a/tests/auto/gui/text/qfont/tst_qfont.cpp b/tests/auto/gui/text/qfont/tst_qfont.cpp index 8406e843cf..6f75a1f8bb 100644 --- a/tests/auto/gui/text/qfont/tst_qfont.cpp +++ b/tests/auto/gui/text/qfont/tst_qfont.cpp @@ -74,7 +74,6 @@ private slots: void resetFont(); #endif void isCopyOf(); - void setFontRaw(); void italicOblique(); void insertAndRemoveSubstitutions(); void serialize_data(); @@ -418,15 +417,6 @@ void tst_QFont::compare() QVERIFY(font == font2); QVERIFY(!(font < font2)); } - -#if defined(Q_WS_X11) - { - QFont font1, font2; - font1.setRawName("-Adobe-Helvetica-medium-r-normal--12-120-75-75-p-67-iso8859-1"); - font2.setRawName("-Adobe-Helvetica-medium-r-normal--24-240-75-75-p-130-iso8859-1"); - QVERIFY(font1 != font2); - } -#endif } void tst_QFont::resolve() @@ -520,30 +510,6 @@ void tst_QFont::isCopyOf() QVERIFY(!font3.isCopyOf(font)); } -void tst_QFont::setFontRaw() -{ -#ifndef Q_WS_X11 - QSKIP("Only tested on X11"); -#else - QFont f; - f.setRawName("-*-fixed-bold-r-normal--0-0-*-*-*-0-iso8859-1"); -// qDebug("font family: %s", f.family().utf8()); - QFontDatabase fdb; - QStringList families = fdb.families(); - bool found = false; - for (int i = 0; i < families.size(); ++i) { - QString str = families.at(i); - if (str.contains('[')) - str = str.left(str.indexOf('[')-1); - if (str.toLower() == "fixed") - found = true; - } - if (!found) - QSKIP("Fixed font not available."); - QCOMPARE(QFontInfo(f).family().left(5).toLower(), QString("fixed")); -#endif -} - void tst_QFont::insertAndRemoveSubstitutions() { QFont::removeSubstitution("BogusFontFamily"); diff --git a/tests/auto/gui/text/qfontdatabase/FreeMono.ttf b/tests/auto/gui/text/qfontdatabase/FreeMono.ttf Binary files differdeleted file mode 100644 index d7ce52ddc7..0000000000 --- a/tests/auto/gui/text/qfontdatabase/FreeMono.ttf +++ /dev/null diff --git a/tests/auto/gui/text/qfontdatabase/LED_REAL.TTF b/tests/auto/gui/text/qfontdatabase/LED_REAL.TTF Binary files differnew file mode 100644 index 0000000000..f87ea95e0e --- /dev/null +++ b/tests/auto/gui/text/qfontdatabase/LED_REAL.TTF diff --git a/tests/auto/gui/text/qfontdatabase/LED_REAL_readme.txt b/tests/auto/gui/text/qfontdatabase/LED_REAL_readme.txt new file mode 100644 index 0000000000..06a5b40313 --- /dev/null +++ b/tests/auto/gui/text/qfontdatabase/LED_REAL_readme.txt @@ -0,0 +1,34 @@ +Font: LED Real (led_real.ttf) +Created By: Matthew Welch +E-Mail: daffy-duck@worldnet.att.net +Web Address: http://home.att.net/~daffy-duck + (PGP public key available here) + +LED Real, like all of my fonts, is free. You can use it for most +personal or business uses you'd like, and I ask for no money. I +would, however, like to hear from you. If you use my fonts for +something please send me a postcard or e-mail letting me know how +you used it. Send me a copy if you can or let me know where I can +find your work. + +You may use this font for graphical or printed work, but you may not +sell it or include it in a collection of fonts (on CD or otherwise) +being sold. You can redistribute this font as long as you charge +nothing to receive it. If you redistribute it include this text file +with it as is (without modifications). + +If you use this font for commercial purposes please credit me in +at least some little way. + +About the font: + +Unlike most LED/LCD style fonts mine could be recreated with an +actual LED. I created this font working from memories of the good +old Speak and Spell display. Since I don't have an actual Speak +and Spell to work from I had to just do as well as I could in its +spirit. Be warned that some characters look just like others. The +( and the <, for instance. Also C and [. Most of these will be +pretty clear in context. To see all the sections of the LED "lit +up" at once use character 127 (hold down alt and type 0127 on the +numeric keypad). This font is, of course, monospaced. + diff --git a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp index fa5c81a2f0..28db0ba291 100644 --- a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp +++ b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp @@ -83,7 +83,7 @@ private: }; tst_QFontDatabase::tst_QFontDatabase() - : m_testFont(QFINDTESTDATA("FreeMono.ttf")) + : m_testFont(QFINDTESTDATA("LED_REAL.TTF")) { } diff --git a/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp b/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp index 74802c3217..c4db669695 100644 --- a/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp +++ b/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp @@ -86,12 +86,13 @@ private slots: void greek_data(); void greek(); - void controlInSyllable_qtbug14204(); - void combiningMarks_qtbug15675(); - void mirroredChars_data(); void mirroredChars(); + void controlInSyllable_qtbug14204(); + void combiningMarks_qtbug15675_data(); + void combiningMarks_qtbug15675(); + void thaiIsolatedSaraAm(); void thaiWithZWJ(); void thaiMultipleVowels(); @@ -1051,87 +1052,18 @@ void tst_QTextScriptEngine::greek() doShapingTests(); } -void tst_QTextScriptEngine::controlInSyllable_qtbug14204() -{ -#if 0 && defined(Q_OS_UNIX) - // ### the test is incorrect -> disable for now - QString s; - s.append(QChar(0x0915)); - s.append(QChar(0x094d)); - s.append(QChar(0x200d)); - s.append(QChar(0x0915)); - - QTextLayout layout(s); - QTextEngine *e = layout.engine(); - e->itemize(); - e->shape(0); - - QCOMPARE(e->layoutData->items[0].num_glyphs, ushort(2)); - QVERIFY(e->layoutData->glyphLayout.advances[1].toInt() != 0); -#endif -} - -void tst_QTextScriptEngine::combiningMarks_qtbug15675() -{ -#if defined(Q_OS_MAC) - QString s; - s.append(QChar(0x0061)); - s.append(QChar(0x0062)); - s.append(QChar(0x0300)); - s.append(QChar(0x0063)); - - QFont font("Monaco"); - QTextLayout layout(s, font); - QTextEngine *e = layout.engine(); - e->itemize(); - e->shape(0); - - QCOMPARE(e->layoutData->items[0].num_glyphs, ushort(4)); - QCOMPARE(e->layoutData->glyphLayout.advances[2].toInt(), 0); -#else - QFontDatabase db; - - if (!db.families().contains("DejaVu Sans Mono")) - QSKIP("Required font (DejaVu Sans Mono) doesn't exist, skip test."); - - QString s; - s.append(QChar(0x0062)); - s.append(QChar(0x0332)); - s.append(QChar(0x0063)); - - QTextLayout layout(s, QFont("DejaVu Sans Mono")); - QTextEngine *e = layout.engine(); - e->itemize(); - e->shape(0); - - QCOMPARE(e->layoutData->items[0].num_glyphs, ushort(3)); - QCOMPARE(e->layoutData->glyphLayout.advances[1].toInt(), 0); -#endif -} - void tst_QTextScriptEngine::mirroredChars_data() { - QTest::addColumn<int>("hintingPreference"); + QTest::addColumn<QString>("s"); - QTest::newRow("Default hinting") << int(QFont::PreferDefaultHinting); - QTest::newRow("No hinting") << int(QFont::PreferNoHinting); - QTest::newRow("Vertical hinting") << int(QFont::PreferVerticalHinting); - QTest::newRow("Full hinting") << int(QFont::PreferFullHinting); + QTest::newRow("()") << QStringLiteral("()"); + QTest::newRow("[]") << QStringLiteral("[]"); + QTest::newRow("{}") << QStringLiteral("{}"); } void tst_QTextScriptEngine::mirroredChars() { -#if defined(Q_OS_MAC) - QSKIP("Not supported on Mac"); -#endif - QFETCH(int, hintingPreference); - - QFont font; - font.setHintingPreference(QFont::HintingPreference(hintingPreference)); - - QString s; - s.append(QLatin1Char('(')); - s.append(QLatin1Char(')')); + QFETCH(QString, s); glyph_t leftParenthesis; glyph_t rightParenthesis; @@ -1144,10 +1076,12 @@ void tst_QTextScriptEngine::mirroredChars() QTextEngine *e = layout.engine(); e->itemize(); + QCOMPARE(e->layoutData->items.size(), 1); + e->shape(0); QCOMPARE(e->layoutData->items[0].num_glyphs, ushort(2)); - const QGlyphLayout &glyphLayout = e->layoutData->glyphLayout; + const QGlyphLayout glyphLayout = e->shapedGlyphs(&e->layoutData->items[0]); leftParenthesis = glyphLayout.glyphs[0]; rightParenthesis = glyphLayout.glyphs[1]; } @@ -1158,61 +1092,170 @@ void tst_QTextScriptEngine::mirroredChars() QTextEngine *e = layout.engine(); e->itemize(); + QCOMPARE(e->layoutData->items.size(), 1); + e->shape(0); QCOMPARE(e->layoutData->items[0].num_glyphs, ushort(2)); - const QGlyphLayout &glyphLayout = e->layoutData->glyphLayout; + const QGlyphLayout glyphLayout = e->shapedGlyphs(&e->layoutData->items[0]); QCOMPARE(glyphLayout.glyphs[0], rightParenthesis); QCOMPARE(glyphLayout.glyphs[1], leftParenthesis); } } +void tst_QTextScriptEngine::controlInSyllable_qtbug14204() +{ + QFontDatabase db; + if (!db.families().contains(QStringLiteral("Aparajita"))) + QSKIP("couldn't find 'Aparajita' font"); + + QFont font(QStringLiteral("Aparajita")); + font.setStyleStrategy(QFont::NoFontMerging); + + QString s; + s.append(QChar(0x0915)); + s.append(QChar(0x094d)); + s.append(QChar(0x200d)); + s.append(QChar(0x0915)); + + QTextLayout layout(s, font); + QTextEngine *e = layout.engine(); + e->itemize(); + QCOMPARE(e->layoutData->items.size(), 1); + + QFontEngine *fe = e->fontEngine(e->layoutData->items[0]); + if (fe->type() == QFontEngine::Box) + QSKIP("OpenType support missing for script"); + QCOMPARE(fe->fontDef.family, font.family()); + + e->shape(0); + QCOMPARE(e->layoutData->items[0].num_glyphs, ushort(2)); + + const ushort *log_clusters = e->logClusters(&e->layoutData->items[0]); + QCOMPARE(log_clusters[0], ushort(0)); + QCOMPARE(log_clusters[1], ushort(0)); + QCOMPARE(log_clusters[2], ushort(0)); + QCOMPARE(log_clusters[3], ushort(0)); +} + +void tst_QTextScriptEngine::combiningMarks_qtbug15675_data() +{ + QTest::addColumn<QFont>("font"); + QTest::addColumn<QString>("string"); + + bool hasTests = false; + + QStringList families; + families << QStringLiteral("Monaco"); + families << QStringLiteral("DejaVu Sans Mono"); + + foreach (const QString &family, families) { + QFont font(family); + font.setStyleStrategy(QFont::NoFontMerging); + if (QFontInfo(font).family() != family) + continue; + + hasTests = true; + + QString s(QStringLiteral("ab cd")); + for (ushort uc = 0x0300; uc < 0x0370; ++uc) { + s[2] = QChar(uc); + QByteArray testName = family.toLatin1() + ": ab<U+" + QByteArray::number(uc, 16).rightJustified(4, '0') + ">cd"; + QTest::newRow(testName.constData()) << font << s; + } + } + + if (!hasTests) + QSKIP("Couldn't find required fonts, skip test."); +} + +void tst_QTextScriptEngine::combiningMarks_qtbug15675() +{ + QFETCH(QFont, font); + QFETCH(QString, string); + + QTextLayout layout(string, font); + QTextEngine *e = layout.engine(); + e->itemize(); + QCOMPARE(e->layoutData->items.size(), 1); + + QFontEngine *fe = e->fontEngine(e->layoutData->items[0]); + if (fe->type() == QFontEngine::Box) + QSKIP("OpenType support missing for script"); + QCOMPARE(fe->fontDef.family, font.family()); + + e->shape(0); + const int diff = e->layoutData->items[0].num_glyphs - string.size(); + QVERIFY(diff >= -1 && diff <= 1); // could compose or decompose exactly one character + + const ushort *log_clusters = e->logClusters(&e->layoutData->items[0]); + QCOMPARE(log_clusters[0], ushort(0)); + QCOMPARE(log_clusters[1], ushort(1)); + QCOMPARE(log_clusters[2], ushort(1)); + QCOMPARE(log_clusters[3], ushort(3 + diff)); + QCOMPARE(log_clusters[4], ushort(4 + diff)); + + const QGlyphLayout glyphLayout = e->shapedGlyphs(&e->layoutData->items[0]); + for (int i = 0; i < glyphLayout.numGlyphs; ++i) { + if ((diff >= 0 && i == 2) || (diff > 0 && i == 2 + diff)) + QCOMPARE(glyphLayout.advances[i].toInt(), 0); + else + QVERIFY(glyphLayout.advances[i].toInt() != 0); + } +} + void tst_QTextScriptEngine::thaiIsolatedSaraAm() { - if (QFontDatabase().families(QFontDatabase::Any).contains("Waree")) { - QString s; - s.append(QChar(0x0e33)); + QFontDatabase db; + if (!db.families().contains("Waree")) + QSKIP("couldn't find 'Waree' font"); - QTextLayout layout(s, QFont("Waree")); - layout.setCacheEnabled(true); - layout.beginLayout(); - layout.createLine(); - layout.endLayout(); + QFont font(QStringLiteral("Waree")); + font.setStyleStrategy(QFont::NoFontMerging); - QTextEngine *e = layout.engine(); - e->itemize(); - e->shape(0); - QCOMPARE(e->layoutData->items[0].num_glyphs, ushort(3)); + QString s; + s.append(QChar(0x0e33)); - unsigned short *logClusters = e->logClusters(&e->layoutData->items[0]); - QCOMPARE(logClusters[0], ushort(0)); - } else - QSKIP("Cannot find Waree."); + QTextLayout layout(s, font); + QTextEngine *e = layout.engine(); + e->itemize(); + QCOMPARE(e->layoutData->items.size(), 1); + + QFontEngine *fe = e->fontEngine(e->layoutData->items[0]); + if (fe->type() == QFontEngine::Box) + QSKIP("OpenType support missing for script"); + QCOMPARE(fe->fontDef.family, font.family()); + + e->shape(0); + QVERIFY(e->layoutData->items[0].num_glyphs > 0); + + const ushort *log_clusters = e->logClusters(&e->layoutData->items[0]); + QCOMPARE(log_clusters[0], ushort(0)); } void tst_QTextScriptEngine::thaiWithZWJ() { -#ifdef Q_OS_WIN - QSKIP("This test currently fails on Windows - QTBUG-24565"); -#endif + QFontDatabase db; + if (!db.families().contains("Waree")) + QSKIP("couldn't find 'Waree' font"); + + QFont font(QStringLiteral("Waree")); + font.setStyleStrategy(QFont::NoFontMerging); + QString s(QString::fromUtf8("\xe0\xb8\xa3\xe2\x80\x8d\xe0\xb8\xa3\xe2\x80" "\x8c\x2e\xe0\xb8\xa3\x2e\xe2\x80\x9c\xe0\xb8" "\xa3\xe2\x80\xa6\xe0\xb8\xa3\xe2\x80\x9d\xe0" "\xb8\xa3\xa0\xe0\xb8\xa3\xe6\x9c\xac\xe0\xb8\xa3") + QChar(0x0363)/*superscript 'a', for testing Inherited class*/); - QTextLayout layout(s); - layout.setCacheEnabled(true); - layout.beginLayout(); - layout.createLine(); - layout.endLayout(); + QTextLayout layout(s, font); QTextEngine *e = layout.engine(); - e->width(0, s.length()); //force itemize and shape - - // A thai implementation could either remove the ZWJ and ZWNJ characters, or hide them. - // The current implementation hides them, so we test for that. - // But make sure that we don't hide anything else + e->itemize(); QCOMPARE(e->layoutData->items.size(), 11); + + for (int item = 0; item < e->layoutData->items.size(); ++item) + e->shape(item); + QCOMPARE(e->layoutData->items[0].num_glyphs, ushort(7)); // Thai: The ZWJ and ZWNJ characters are inherited, so should be part of the thai script QCOMPARE(e->layoutData->items[1].num_glyphs, ushort(1)); // Common: The smart quotes cannot be handled by thai, so should be a separate item QCOMPARE(e->layoutData->items[2].num_glyphs, ushort(1)); // Thai: Thai character @@ -1231,15 +1274,18 @@ void tst_QTextScriptEngine::thaiWithZWJ() QCOMPARE(logClusters[i], ushort(i)); for (int i = 0; i < 10; i++) QCOMPARE(logClusters[i+7], ushort(0)); -#ifdef Q_OS_MAC - QEXPECT_FAIL("", "QTBUG-23064", Abort); -#endif QCOMPARE(logClusters[17], ushort(1)); - // The only characters that we should be hiding are the ZWJ and ZWNJ characters in position 1 - // and 3. - for (int i = 0; i < 18; i++) - QCOMPARE((bool)e->layoutData->glyphLayout.attributes[i].dontPrint, (i == 1 || i == 3)); + // A thai implementation could either remove the ZWJ and ZWNJ characters, or hide them. + // The current implementation hides them, so we test for that. + // The only characters that we should be hiding are the ZWJ and ZWNJ characters in position 1 and 3. + const QGlyphLayout glyphLayout = e->layoutData->glyphLayout; + for (int i = 0; i < 18; i++) { + if (i == 1 || i == 3) + QCOMPARE(glyphLayout.advances[i].toInt(), 0); + else + QVERIFY(glyphLayout.advances[i].toInt() != 0); + } } void tst_QTextScriptEngine::thaiMultipleVowels() @@ -1253,14 +1299,13 @@ void tst_QTextScriptEngine::thaiMultipleVowels() for (int i = 0; i < 10; i++) s += s; //Repeat the string to make it more likely to crash if we have a buffer overflow - QTextLayout layout(s); - layout.setCacheEnabled(true); - layout.beginLayout(); - layout.createLine(); - layout.endLayout(); + QTextLayout layout(s); QTextEngine *e = layout.engine(); - e->width(0, s.length()); //force itemize and shape + e->itemize(); + + for (int item = 0; item < e->layoutData->items.size(); ++item) + e->shape(item); // If we haven't crashed at this point, then the test has passed. } |