Merge branch 'master' of scm.dev.nokia.troll.no:qt/qtbase-staging
authorGunnar Sletta <gunnar.sletta@nokia.com>
Wed, 4 May 2011 09:38:42 +0000 (11:38 +0200)
committerGunnar Sletta <gunnar.sletta@nokia.com>
Wed, 4 May 2011 09:38:42 +0000 (11:38 +0200)
104 files changed:
configure
mkspecs/features/qt.prf
src/corelib/animation/qabstractanimation.cpp
src/corelib/animation/qabstractanimation.h
src/corelib/animation/qabstractanimation_p.h
src/corelib/global/qglobal.h
src/corelib/io/qprocess_unix.cpp
src/corelib/kernel/qcoreapplication.cpp
src/corelib/kernel/qcoreapplication.h
src/corelib/kernel/qcoreapplication_p.h
src/gui/kernel/qapplication_win.cpp
src/gui/kernel/qcocoaview_mac.mm
src/gui/kernel/qdesktopwidget_qpa.cpp
src/gui/kernel/qdesktopwidget_qpa_p.h
src/gui/kernel/qplatformintegration_qpa.cpp
src/gui/kernel/qplatformwindow_qpa.cpp
src/gui/kernel/qsessionmanager_qpa.cpp
src/gui/painting/qdrawhelper.cpp
src/gui/painting/qpaintengine_mac.cpp
src/gui/painting/qpainter.cpp
src/gui/painting/qtextureglyphcache.cpp
src/gui/text/qfont.h
src/gui/text/qfontengine_coretext.mm
src/gui/text/qfontengine_coretext_p.h
src/gui/text/qfontengine_ft.cpp
src/gui/text/qfontengine_ft_p.h
src/gui/text/qfontengine_mac.mm
src/gui/text/qfontengine_mac_p.h
src/gui/text/qfontengine_p.h
src/gui/text/qfontengine_win.cpp
src/gui/text/qfontengine_win_p.h
src/gui/text/qfontengine_x11.cpp
src/gui/text/qfontengine_x11_p.h
src/gui/text/qfontenginedirectwrite.cpp
src/gui/text/qfontenginedirectwrite_p.h
src/gui/text/qglyphs.cpp
src/gui/text/qplatformfontdatabase_qpa.cpp
src/gui/text/qplatformfontdatabase_qpa.h
src/gui/text/qrawfont.cpp
src/gui/text/qrawfont.h
src/gui/text/qrawfont_ft.cpp
src/gui/text/qrawfont_mac.cpp
src/gui/text/qrawfont_p.h
src/gui/text/qrawfont_qpa.cpp [new file with mode: 0644]
src/gui/text/qrawfont_win.cpp
src/gui/text/qstatictext.cpp
src/gui/text/qtextcursor.cpp
src/gui/text/qtextcursor.h
src/gui/text/qtextdocument.cpp
src/gui/text/qtextdocument.h
src/gui/text/qtextdocument_p.cpp
src/gui/text/qtextdocument_p.h
src/gui/text/qtextdocumentlayout.cpp
src/gui/text/qtextengine.cpp
src/gui/text/qtextengine_mac.cpp
src/gui/text/qtextengine_p.h
src/gui/text/qtextformat.h
src/gui/text/qtextlayout.cpp
src/gui/text/qtextlayout.h
src/gui/text/text.pri
src/gui/widgets/qlinecontrol.cpp
src/gui/widgets/qlinecontrol_p.h
src/gui/widgets/qlineedit.cpp
src/gui/widgets/qlineedit.h
src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
src/opengl/gl2paintengineex/qtriangulator.cpp
src/opengl/gl2paintengineex/qtriangulator_p.h
src/opengl/qgl.cpp
src/opengl/qgl.h
src/opengl/qgl_p.h
src/opengl/qglextensions_p.h
src/opengl/qglfunctions.cpp
src/opengl/qglfunctions.h
src/opengl/qglpaintdevice_p.h
src/plugins/platforms/uikit/quikiteventloop.mm
src/plugins/platforms/uikit/quikitintegration.mm
src/plugins/platforms/uikit/quikitscreen.mm
src/plugins/platforms/uikit/quikitwindow.h
src/plugins/platforms/uikit/quikitwindow.mm
src/plugins/platforms/uikit/quikitwindowsurface.mm
src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp
src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h
src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp
src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h
src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri
src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp
src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp
src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-client-protocol.h
src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-protocol.c
src/plugins/platforms/wayland/qwaylandbuffer.h
src/plugins/platforms/wayland/qwaylanddisplay.cpp
src/plugins/platforms/wayland/qwaylandinputdevice.cpp
src/plugins/platforms/wayland/qwaylandintegration.cpp
src/plugins/platforms/wayland/qwaylandintegration.h
src/plugins/platforms/wayland/qwaylandnativeinterface.cpp [new file with mode: 0644]
src/plugins/platforms/wayland/qwaylandnativeinterface.h [new file with mode: 0644]
src/plugins/platforms/wayland/qwaylandwindow.cpp
src/plugins/platforms/wayland/qwaylandwindow.h
src/plugins/platforms/wayland/wayland.pro
tests/auto/qcomplextext/tst_qcomplextext.cpp
tests/auto/qlineedit/tst_qlineedit.cpp
tests/auto/qpixmap/tst_qpixmap.cpp
tests/auto/qrawfont/tst_qrawfont.cpp
tests/auto/qtextedit/tst_qtextedit.cpp

index 293f642..e6956fb 100755 (executable)
--- a/configure
+++ b/configure
@@ -804,6 +804,7 @@ CFG_MAC_XARCH=auto
 CFG_MAC_CARBON=no
 CFG_MAC_COCOA=yes
 COMMANDLINE_MAC_CARBON=no
+CFG_MAC_HARFBUZZ=no
 CFG_SXE=no
 CFG_PREFIX_INSTALL=yes
 CFG_SDK=
@@ -1041,7 +1042,7 @@ while [ "$#" -gt 0 ]; do
         VAL=no
         ;;
     #Qt style yes options
-    -incremental|-qvfb|-profile|-shared|-static|-sm|-xinerama|-xshape|-xsync|-xinput|-egl|-reduce-exports|-pch|-separate-debug-info|-stl|-freetype|-xcursor|-xfixes|-xrandr|-xrender|-mitshm|-fontconfig|-xkb|-nis|-qdbus|-dbus|-dbus-linked|-glib|-gstreamer|-gtkstyle|-cups|-iconv|-largefile|-h|-help|-v|-verbose|-debug|-release|-fast|-accessibility|-confirm-license|-gnumake|-framework|-qt3support|-debug-and-release|-exceptions|-cocoa|-carbon|-universal|-prefix-install|-silent|-armfpa|-optimized-qmake|-dwarf2|-reduce-relocations|-sse|-openssl|-openssl-linked|-ptmalloc|-xmlpatterns|-phonon|-phonon-backend|-multimedia|-audio-backend|-svg|-declarative|-declarative-debug|-javascript-jit|-script|-scripttools|-rpath|-force-pkg-config|-s60|-usedeffiles|-icu)
+    -incremental|-qvfb|-profile|-shared|-static|-sm|-xinerama|-xshape|-xsync|-xinput|-egl|-reduce-exports|-pch|-separate-debug-info|-stl|-freetype|-xcursor|-xfixes|-xrandr|-xrender|-mitshm|-fontconfig|-xkb|-nis|-qdbus|-dbus|-dbus-linked|-glib|-gstreamer|-gtkstyle|-cups|-iconv|-largefile|-h|-help|-v|-verbose|-debug|-release|-fast|-accessibility|-confirm-license|-gnumake|-framework|-qt3support|-debug-and-release|-exceptions|-cocoa|-carbon|-universal|-harfbuzz|-prefix-install|-silent|-armfpa|-optimized-qmake|-dwarf2|-reduce-relocations|-sse|-openssl|-openssl-linked|-ptmalloc|-xmlpatterns|-phonon|-phonon-backend|-multimedia|-audio-backend|-svg|-declarative|-declarative-debug|-javascript-jit|-script|-scripttools|-rpath|-force-pkg-config|-s60|-usedeffiles|-icu)
         VAR=`echo $1 | sed "s,^-\(.*\),\1,"`
         VAL=yes
         ;;
@@ -1499,6 +1500,13 @@ while [ "$#" -gt 0 ]; do
             UNKNOWN_OPT=yes
         fi
         ;;
+    harfbuzz)
+        if [ "$PLATFORM_MAC" = "yes" ] && [ "$CFG_MAC_CARBON" != "yes" ] && [ "$VAL" = "yes" ]; then
+            CFG_MAC_HARFBUZZ="$VAL"
+        else
+            UNKNOWN_OPT=yes
+        fi
+        ;;
 
     framework)
         if [ "$PLATFORM_MAC" = "yes" ] || [ "$PLATFORM_QPA" = "yes" ]; then
@@ -4257,6 +4265,11 @@ Qt/Mac only:
     -sdk <sdk> ......... Build Qt using Apple provided SDK <sdk>. This option requires gcc 4.
                          To use a different SDK with gcc 3.3, set the SDKROOT environment variable.
 
+    -harfbuzz .......... Use HarfBuzz to do text layout instead of Core Text when possible.
+                         It is only available to Cocoa builds.
+ *  -no-harfbuzz ....... Disable HarfBuzz on Mac. It can still be enabled by setting
+                         QT_ENABLE_HARFBUZZ environment variable.
+
 EOF
 fi
 
@@ -7251,6 +7264,7 @@ fi
 [ "$CFG_NAS" = "system" ] && QT_CONFIG="$QT_CONFIG nas"
 [ "$CFG_OPENSSL" = "yes" ] && QT_CONFIG="$QT_CONFIG openssl"
 [ "$CFG_OPENSSL" = "linked" ] && QT_CONFIG="$QT_CONFIG openssl-linked"
+[ "$CFG_MAC_HARFBUZZ" = "yes" ] && QT_CONFIG="$QT_CONFIG harfbuzz"
 
 if [ "$PLATFORM_X11" = "yes" ]; then
     [ "$CFG_SM" = "yes" ] && QT_CONFIG="$QT_CONFIG x11sm"
index 61e1d57..c611096 100644 (file)
@@ -1,5 +1,7 @@
 CONFIG *= moc thread
 
+contains(QT, declarative): QT += opengl
+
 #handle defines
 win32 {
    qt_static:DEFINES += QT_NODLL
@@ -129,6 +131,7 @@ QMAKE_LIBDIR += $$QMAKE_LIBDIR_QT
 
 # Topological ordering of modules based on their QT.<module>.depends variable
 QT = $$resolve_depends($$QT, "QT.")
+
 QT_DEPENDS=
 
 unset(using_privates)
index 602cf8a..7d74de8 100644 (file)
@@ -201,16 +201,17 @@ void QUnifiedTimer::ensureTimerUpdate()
 {
     QUnifiedTimer *inst = QUnifiedTimer::instance(false);
     if (inst && inst->isPauseTimerActive)
-        inst->updateAnimationsTime();
+        inst->updateAnimationsTime(-1);
 }
 
-void QUnifiedTimer::updateAnimationsTime()
+void QUnifiedTimer::updateAnimationsTime(qint64 timeStep)
 {
     //setCurrentTime can get this called again while we're the for loop. At least with pauseAnimations
     if(insideTick)
         return;
 
-    qint64 totalElapsed = time.elapsed();
+    qint64 totalElapsed = timeStep >= 0 ? timeStep : time.elapsed();
+
     // ignore consistentTiming in case the pause timer is active
     int delta = (consistentTiming && !isPauseTimerActive) ?
                         timingInterval : totalElapsed - lastTick;
@@ -260,7 +261,8 @@ void QUnifiedTimer::restartAnimationTimer()
     } else if (!driver->isRunning() || isPauseTimerActive) {
         driver->start();
         isPauseTimerActive = false;
-    }
+    } else if (runningLeafAnimations == 0)
+        driver->stop();
 }
 
 void QUnifiedTimer::setTimingInterval(int interval)
@@ -302,7 +304,7 @@ void QUnifiedTimer::timerEvent(QTimerEvent *event)
 
     if (event->timerId() == animationTimer.timerId()) {
         // update current time on all top level animations
-        updateAnimationsTime();
+        updateAnimationsTime(-1);
         restartAnimationTimer();
     }
 }
@@ -389,19 +391,49 @@ int QUnifiedTimer::closestPauseAnimationTimeToFinish()
     return closestTimeToFinish;
 }
 
+
 void QUnifiedTimer::installAnimationDriver(QAnimationDriver *d)
 {
-    if (driver->isRunning()) {
-        qWarning("QUnifiedTimer: Cannot change animation driver while animations are running");
+    if (driver != &defaultDriver) {
+        qWarning("QUnifiedTimer: animation driver already installed...");
         return;
     }
 
-    if (driver && driver != &defaultDriver)
-        delete driver;
+    if (driver->isRunning()) {
+        driver->stop();
+        d->start();
+    }
 
     driver = d;
+
+}
+
+
+void QUnifiedTimer::uninstallAnimationDriver(QAnimationDriver *d)
+{
+    if (driver != d) {
+        qWarning("QUnifiedTimer: trying to uninstall a driver that is not installed...");
+        return;
+    }
+
+    driver = &defaultDriver;
+
+    if (d->isRunning()) {
+        d->stop();
+        driver->start();
+    }
+}
+
+/*!
+    Returns true if \a d is the currently installed animation driver
+    and is not the default animation driver (which can never be uninstalled).
+*/
+bool QUnifiedTimer::canUninstallAnimationDriver(QAnimationDriver *d)
+{
+    return d == driver && driver != &defaultDriver;
 }
 
+
 /*!
    \class QAnimationDriver
 
@@ -424,35 +456,69 @@ QAnimationDriver::QAnimationDriver(QAnimationDriverPrivate &dd, QObject *parent)
 {
 }
 
+QAnimationDriver::~QAnimationDriver()
+{
+    QUnifiedTimer *timer = QUnifiedTimer::instance(true);
+    if (timer->canUninstallAnimationDriver(this))
+        uninstall();
+}
+
+
 
 /*!
-    Advances the animation based on the current time. This function should
-    be continuously called by the driver while the animation is running.
+    Advances the animation based to the specified \a timeStep. This function should
+    be continuously called by the driver subclasses while the animation is running.
 
-    \internal
+    If \a timeStep is positive, it will be used as the current time in the
+    calculations; otherwise, the current clock time will be used.
  */
-void QAnimationDriver::advance()
+
+void QAnimationDriver::advanceAnimation(qint64 timeStep)
 {
     QUnifiedTimer *instance = QUnifiedTimer::instance();
 
     // update current time on all top level animations
-    instance->updateAnimationsTime();
+    instance->updateAnimationsTime(timeStep);
     instance->restartAnimationTimer();
 }
 
 
+
+/*!
+    Advances the animation. This function should be continously called
+    by the driver while the animation is running.
+ */
+
+void QAnimationDriver::advance()
+{
+    advanceAnimation(-1);
+}
+
+
+
 /*!
     Installs this animation driver. The animation driver is thread local and
     will only apply for the thread its installed in.
-
-    \internal
  */
+
 void QAnimationDriver::install()
 {
     QUnifiedTimer *timer = QUnifiedTimer::instance(true);
     timer->installAnimationDriver(this);
 }
 
+
+
+/*!
+    Uninstalls this animation driver.
+ */
+
+void QAnimationDriver::uninstall()
+{
+    QUnifiedTimer *timer = QUnifiedTimer::instance(true);
+    timer->uninstallAnimationDriver(this);
+}
+
 bool QAnimationDriver::isRunning() const
 {
     return d_func()->running;
@@ -463,7 +529,7 @@ void QAnimationDriver::start()
 {
     Q_D(QAnimationDriver);
     if (!d->running) {
-        started();
+        emit started();
         d->running = true;
     }
 }
@@ -473,16 +539,28 @@ void QAnimationDriver::stop()
 {
     Q_D(QAnimationDriver);
     if (d->running) {
-        stopped();
+        emit stopped();
         d->running = false;
     }
 }
 
+
+/*!
+    \fn qint64 QAnimationDriver::elapsed() const
+
+    Returns the number of milliseconds since the animations was started.
+ */
+
+qint64 QAnimationDriver::elapsed() const
+{
+    return QUnifiedTimer::instance()->time.elapsed();
+}
+
 /*!
     \fn QAnimationDriver::started()
 
-    This function is called by the animation framework to notify the driver
-    that it should start running.
+    This signal is emitted by the animation framework to notify the driver
+    that continous animation has started.
 
     \internal
  */
@@ -490,8 +568,8 @@ void QAnimationDriver::stop()
 /*!
     \fn QAnimationDriver::stopped()
 
-    This function is called by the animation framework to notify the driver
-    that it should stop running.
+    This signal is emitted by the animation framework to notify the driver
+    that continous animation has stopped.
 
     \internal
  */
index 0900870..9128206 100644 (file)
@@ -141,23 +141,31 @@ class Q_CORE_EXPORT QAnimationDriver : public QObject
 
 public:
     QAnimationDriver(QObject *parent = 0);
+    ~QAnimationDriver();
+
+    virtual void advance();
 
-    void advance();
     void install();
+    void uninstall();
 
     bool isRunning() const;
 
+    qint64 elapsed() const;
+
+Q_SIGNALS:
+    void started();
+    void stopped();
+
 protected:
-    virtual void started() {};
-    virtual void stopped() {};
+    void advanceAnimation(qint64 timeStep = -1);
+    virtual void start();
+    virtual void stop();
 
     QAnimationDriver(QAnimationDriverPrivate &dd, QObject *parent = 0);
 
 private:
     friend class QUnifiedTimer;
 
-    void start();
-    void stop();
 };
 
 
index ba92960..de26987 100644 (file)
@@ -180,15 +180,21 @@ public:
     static void updateAnimationTimer();
 
     void installAnimationDriver(QAnimationDriver *driver);
+    void uninstallAnimationDriver(QAnimationDriver *driver);
+    bool canUninstallAnimationDriver(QAnimationDriver *driver);
 
     void restartAnimationTimer();
-    void updateAnimationsTime();
+    void updateAnimationsTime(qint64 timeStep);
+
+    //useful for profiling/debugging
+    int runningAnimationCount() { return animations.count(); }
 
 protected:
     void timerEvent(QTimerEvent *);
 
 private:
     friend class QDefaultAnimationDriver;
+    friend class QAnimationDriver;
 
     QAnimationDriver *driver;
     QDefaultAnimationDriver defaultDriver;
index 9434eb2..49f5f98 100644 (file)
@@ -2755,7 +2755,8 @@ QT_LICENSED_MODULE(DBus)
 
 #if !(defined(Q_WS_WIN) && !defined(Q_WS_WINCE)) \
     && !(defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)) \
-    && !(defined(Q_WS_X11) && !defined(QT_NO_FREETYPE))
+    && !(defined(Q_WS_X11) && !defined(QT_NO_FREETYPE)) \
+    && !(defined(Q_WS_QPA))
 #  define QT_NO_RAWFONT
 #endif
 
index 3af9b46..f53742b 100644 (file)
@@ -171,17 +171,27 @@ private:
 
 Q_GLOBAL_STATIC(QMutex, processManagerGlobalMutex)
 
-static QProcessManager *processManager() {
+static QProcessManager *processManagerInstance = 0;
+
+static QProcessManager *processManager()
+{
     // The constructor of QProcessManager should be called only once
     // so we cannot use Q_GLOBAL_STATIC directly for QProcessManager
     QMutex *mutex = processManagerGlobalMutex();
     QMutexLocker locker(mutex);
-    static QProcessManager processManager;
-    return &processManager;
+
+    if (!processManagerInstance)
+        QProcessPrivate::initializeProcessManager();
+
+    Q_ASSERT(processManagerInstance);
+    return processManagerInstance;
 }
 
 QProcessManager::QProcessManager()
 {
+    // can only be called from main thread
+    Q_ASSERT(!qApp || qApp->thread() == QThread::currentThread());
+
 #if defined (QPROCESS_DEBUG)
     qDebug() << "QProcessManager::QProcessManager()";
 #endif
@@ -197,6 +207,8 @@ QProcessManager::QProcessManager()
     action.sa_handler = qt_sa_sigchld_handler;
     action.sa_flags = SA_NOCLDSTOP;
     ::sigaction(SIGCHLD, &action, &qt_sa_old_sigchld_handler);
+
+    processManagerInstance = this;
 }
 
 QProcessManager::~QProcessManager()
@@ -221,6 +233,8 @@ QProcessManager::~QProcessManager()
     if (currentAction.sa_handler == qt_sa_sigchld_handler) {
         ::sigaction(SIGCHLD, &qt_sa_old_sigchld_handler, 0);
     }
+
+    processManagerInstance = 0;
 }
 
 void QProcessManager::run()
@@ -1287,7 +1301,15 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a
 
 void QProcessPrivate::initializeProcessManager()
 {
-    (void) processManager();
+    if (qApp && qApp->thread() != QThread::currentThread()) {
+        // The process manager must be initialized in the main thread
+        // Note: The call below will re-enter this function, but in the right thread,
+        // so the else statement below will be executed.
+        QMetaObject::invokeMethod(qApp, "_q_initializeProcessManager", Qt::BlockingQueuedConnection);
+    } else {
+        static QProcessManager processManager;
+        Q_UNUSED(processManager);
+    }
 }
 
 QT_END_NAMESPACE
index be86c58..e0841cb 100644 (file)
@@ -392,6 +392,16 @@ void QCoreApplicationPrivate::createEventDispatcher()
 #endif
 }
 
+void QCoreApplicationPrivate::_q_initializeProcessManager()
+{
+#ifndef QT_NO_PROCESS
+#  ifdef Q_OS_UNIX
+    QProcessPrivate::initializeProcessManager();
+#  endif
+#endif
+}
+
+
 QThread *QCoreApplicationPrivate::theMainThread = 0;
 QThread *QCoreApplicationPrivate::mainThread()
 {
@@ -656,12 +666,6 @@ void QCoreApplication::init()
     }
 #endif
 
-#if defined(Q_OS_UNIX) && !(defined(QT_NO_PROCESS))
-    // Make sure the process manager thread object is created in the main
-    // thread.
-    QProcessPrivate::initializeProcessManager();
-#endif
-
 #ifdef QT_EVAL
     extern void qt_core_eval_init(uint);
     qt_core_eval_init(d->application_type);
@@ -2728,3 +2732,5 @@ int QCoreApplication::loopLevel()
 */
 
 QT_END_NAMESPACE
+
+#include "moc_qcoreapplication.cpp"
index 3957158..024c509 100644 (file)
@@ -205,6 +205,7 @@ protected:
     QCoreApplication(QCoreApplicationPrivate &p);
 
 private:
+    Q_PRIVATE_SLOT(d_func(), void _q_initializeProcessManager())
     static bool sendSpontaneousEvent(QObject *receiver, QEvent *event);
     bool notifyInternal(QObject *receiver, QEvent *event);
 
index add2a35..fdceab4 100644 (file)
@@ -85,6 +85,8 @@ public:
     bool sendThroughObjectEventFilters(QObject *, QEvent *);
     bool notify_helper(QObject *, QEvent *);
 
+    void _q_initializeProcessManager();
+
     virtual QString appName() const;
     virtual void createEventDispatcher();
     static void removePostedEvent(QEvent *);
index 0a03397..72a05af 100644 (file)
@@ -237,6 +237,7 @@ static void resolveAygLibs()
 #  define FE_FONTSMOOTHINGCLEARTYPE 0x0002
 #endif
 
+Q_GUI_EXPORT qreal qt_fontsmoothing_gamma;
 Q_GUI_EXPORT bool qt_cleartype_enabled;
 Q_GUI_EXPORT bool qt_win_owndc_required; // CS_OWNDC is required if we use the GL graphicssystem as default
 
@@ -653,8 +654,18 @@ static void qt_win_read_cleartype_settings()
     if (SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &result, 0))
         qt_cleartype_enabled = (result == FE_FONTSMOOTHINGCLEARTYPE);
 #endif
-}
 
+    int winSmooth;
+    if (SystemParametersInfo(0x200C /* SPI_GETFONTSMOOTHINGCONTRAST */, 0, &winSmooth, 0)) {
+        qt_fontsmoothing_gamma = winSmooth / qreal(1000.0);
+    } else {
+        qt_fontsmoothing_gamma = 1.0;
+    }
+
+    // Safeguard ourselves against corrupt registry values...
+    if (qt_fontsmoothing_gamma > 5 || qt_fontsmoothing_gamma < 1)
+        qt_fontsmoothing_gamma = qreal(1.4);
+}
 
 static void qt_set_windows_resources()
 {
index b5e5d18..e885d15 100644 (file)
@@ -334,7 +334,6 @@ static int qCocoaViewCount = 0;
         //
         // Qt will then forward the update to the children.
         if (qwidget->isWindow()) {
-            qwidget->update(qwidget->rect());
             qwidgetprivate->syncBackingStore(qwidget->rect());
         }
     }
index cff05f5..6257a8b 100644 (file)
@@ -51,6 +51,8 @@ QT_USE_NAMESPACE
 
 void QDesktopWidgetPrivate::updateScreenList()
 {
+    Q_Q(QDesktopWidget);
+
     QList<QPlatformScreen *> screenList = QApplicationPrivate::platformIntegration()->screens();
     int targetLength = screenList.length();
     int currentLength = screens.length();
@@ -72,19 +74,15 @@ void QDesktopWidgetPrivate::updateScreenList()
     }
 
     QRegion virtualGeometry;
-    bool doVirtualGeometry = QApplicationPrivate::platformIntegration()->isVirtualDesktop();
 
     // update the geometry of each screen widget
     for (int i = 0; i < screens.length(); i++) {
         QRect screenGeometry = screenList.at(i)->geometry();
         screens.at(i)->setGeometry(screenGeometry);
-        if (doVirtualGeometry)
-            virtualGeometry += screenGeometry;
+        virtualGeometry += screenGeometry;
     }
 
-    virtualScreen.setGeometry(virtualGeometry.boundingRect());
-    Q_Q(QDesktopWidget);
-    q->setGeometry(virtualScreen.geometry());
+    q->setGeometry(virtualGeometry.boundingRect());
 }
 
 QDesktopWidget::QDesktopWidget()
@@ -118,8 +116,6 @@ int QDesktopWidget::numScreens() const
 QWidget *QDesktopWidget::screen(int screen)
 {
     Q_D(QDesktopWidget);
-    if (QApplicationPrivate::platformIntegration()->isVirtualDesktop())
-        return &d->virtualScreen;
     if (screen < 0 || screen >= d->screens.length())
         return d->screens.at(0);
     return d->screens.at(screen);
index abee8a1..d6ed686 100644 (file)
@@ -76,7 +76,6 @@ public:
     void updateScreenList();
 
     QList<QDesktopScreenWidget *> screens;
-    QDesktopScreenWidget virtualScreen;
 };
 
 #endif // QDESKTOPWIDGET_QPA_P_H
index d559c53..8ff12eb 100644 (file)
@@ -214,6 +214,7 @@ QPlatformNativeInterface * QPlatformIntegration::nativeInterface() const
 
 bool QPlatformIntegration::hasCapability(Capability cap) const
 {
+    Q_UNUSED(cap);
     return false;
 }
 
index 19bf7a9..f3654b6 100644 (file)
@@ -150,7 +150,7 @@ void QPlatformWindow::setParent(const QPlatformWindow *parent)
 /*!
   Reimplement to set the window title to \a title
 */
-void QPlatformWindow::setWindowTitle(const QString &title) {}
+void QPlatformWindow::setWindowTitle(const QString &) {}
 
 /*!
   Reimplement to be able to let Qt rais windows to the top of the desktop
index ef532d7..68685b4 100644 (file)
@@ -42,6 +42,8 @@
 #include <qsessionmanager.h>
 
 #include <private/qobject_p.h>
+#include <qapplication.h>
+
 #ifndef QT_NO_SESSIONMANAGER
 
 QT_BEGIN_NAMESPACE
index 5e75e4a..3553b60 100644 (file)
@@ -7198,14 +7198,8 @@ void qt_build_pow_tables() {
 #endif
 
 #ifdef Q_WS_WIN
-    int winSmooth;
-    if (SystemParametersInfo(0x200C /* SPI_GETFONTSMOOTHINGCONTRAST */, 0, &winSmooth, 0))
-        smoothing = winSmooth / qreal(1000.0);
-
-    // Safeguard ourselves against corrupt registry values...
-    if (smoothing > 5 || smoothing < 1)
-        smoothing = qreal(1.4);
-
+    extern qreal qt_fontsmoothing_gamma; // qapplication_win.cpp
+    smoothing = qt_fontsmoothing_gamma;
 #endif
 
 #ifdef Q_WS_X11
index 8aab7c7..c6d061d 100644 (file)
@@ -100,7 +100,9 @@ QMacCGContext::QMacCGContext(QPainter *p)
 
     int devType = p->device()->devType();
     if (pe->type() == QPaintEngine::Raster
-            && (devType == QInternal::Widget || devType == QInternal::Pixmap)) {
+            && (devType == QInternal::Widget ||
+                devType == QInternal::Pixmap ||
+                devType == QInternal::Image)) {
 
         extern CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice);
         CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(pe->paintDevice());
index 9fafba5..b7686fa 100644 (file)
@@ -156,7 +156,8 @@ static bool qt_paintengine_supports_transformations(QPaintEngine::Type type)
 {
     return type == QPaintEngine::OpenGL2
             || type == QPaintEngine::OpenVG
-            || type == QPaintEngine::OpenGL;
+            || type == QPaintEngine::OpenGL
+            || type == QPaintEngine::CoreGraphics;
 }
 
 #ifndef QT_NO_DEBUG
@@ -5809,7 +5810,7 @@ void QPainter::drawGlyphs(const QPointF &position, const QGlyphs &glyphs)
     bool paintEngineSupportsTransformations =
             d->extended != 0
             ? qt_paintengine_supports_transformations(d->extended->type())
-            : false;
+            : qt_paintengine_supports_transformations(d->engine->type());
     for (int i=0; i<count; ++i) {
         QPointF processedPosition = position + glyphPositions.at(i);
         if (!paintEngineSupportsTransformations)
index 53f025f..e9e56a2 100644 (file)
@@ -296,7 +296,7 @@ void QTextureGlyphCache::fillInPendingGlyphs()
 QImage QTextureGlyphCache::textureMapForGlyph(glyph_t g, QFixed subPixelPosition) const
 {
 #if defined(Q_WS_X11)
-    if (m_transform.type() > QTransform::TxTranslate) {
+    if (m_transform.type() > QTransform::TxTranslate && m_current_fontengine->type() == QFontEngine::Freetype) {
         QFontEngineFT::GlyphFormat format = QFontEngineFT::Format_None;
         QImage::Format imageFormat = QImage::Format_Invalid;
         switch (m_type) {
index 8dbc746..0c7b6f8 100644 (file)
@@ -239,7 +239,7 @@ public:
     bool isCopyOf(const QFont &) const;
 #ifdef Q_COMPILER_RVALUE_REFS
     inline QFont &operator=(QFont &&other)
-    { qSwap(d, other.d); return *this; }
+    { qSwap(d, other.d); qSwap(resolve_mask, other.resolve_mask);  return *this; }
 #endif
 
 #ifdef Q_WS_WIN
index 20b3730..d4df218 100644 (file)
@@ -162,8 +162,10 @@ uint QCoreTextFontEngineMulti::fontIndexForFont(CTFontRef font) const
     return engines.count() - 1;
 }
 
-bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags,
-                  unsigned short *logClusters, const HB_CharAttributes *) const
+bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs,
+                                            int *nglyphs, QTextEngine::ShaperFlags flags,
+                                            unsigned short *logClusters, const HB_CharAttributes *,
+                                            QScriptItem *si) const
 {
     QCFType<CFStringRef> cfstring = CFStringCreateWithCharactersNoCopy(0,
                                                                reinterpret_cast<const UniChar *>(str),
@@ -180,6 +182,8 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay
                                                               &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
         typeSetter = CTTypesetterCreateWithAttributedStringAndOptions(attributedString, options);
     } else
+#else
+    Q_UNUSED(flags);
 #endif
         typeSetter = CTTypesetterCreateWithAttributedString(attributedString);
 
@@ -219,6 +223,25 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay
 
         Q_ASSERT((CTRunGetStatus(run) & kCTRunStatusRightToLeft) == rtl);
         CFRange stringRange = CTRunGetStringRange(run);
+        int prepend = 0;
+#if MAC_OS_X_VERSION_MAX_ALLOWED == MAC_OS_X_VERSION_10_5
+        UniChar beginGlyph = CFStringGetCharacterAtIndex(cfstring, stringRange.location);
+        QChar dir = QChar::direction(beginGlyph);
+        bool beginWithOverride = dir == QChar::DirLRO || dir == QChar::DirRLO || dir == QChar::DirLRE || dir == QChar::DirRLE;
+        if (beginWithOverride) {
+            logClusters[stringRange.location] = 0;
+            outGlyphs[0] = 0xFFFF;
+            outAdvances_x[0] = 0;
+            outAdvances_y[0] = 0;
+            outAttributes[0].clusterStart = true;
+            outAttributes[0].dontPrint = true;
+            outGlyphs++;
+            outAdvances_x++;
+            outAdvances_y++;
+            outAttributes++;
+            prepend = 1;
+        }
+#endif
         UniChar endGlyph = CFStringGetCharacterAtIndex(cfstring, stringRange.location + stringRange.length - 1);
         bool endWithPDF = QChar::direction(endGlyph) == QChar::DirPDF;
         if (endWithPDF)
@@ -233,7 +256,12 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay
             if (!runAttribs)
                 runAttribs = attributeDict;
             CTFontRef runFont = static_cast<CTFontRef>(CFDictionaryGetValue(runAttribs, NSFontAttributeName));
-            const uint fontIndex = (fontIndexForFont(runFont) << 24);
+            uint fontIndex = fontIndexForFont(runFont);
+            const QFontEngine *engine = engineAt(fontIndex);
+            fontIndex <<= 24;
+            si->ascent = qMax(engine->ascent(), si->ascent);
+            si->descent = qMax(engine->descent(), si->descent);
+            si->leading = qMax(engine->leading(), si->leading);
             //NSLog(@"Run Font Name = %@", CTFontCopyFamilyName(runFont));
             if (endWithPDF)
                 glyphCount--;
@@ -271,9 +299,9 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay
 
                 CFIndex k = 0;
                 CFIndex i = 0;
-                for (i = stringRange.location;
+                for (i = stringRange.location + prepend;
                      (i < stringRange.location + stringRange.length) && (k < glyphCount); ++i) {
-                    if (tmpIndices[k * rtlSign + rtlOffset] == i || i == stringRange.location) {
+                    if (tmpIndices[k * rtlSign + rtlOffset] == i || i == stringRange.location + prepend) {
                         logClusters[i] = k + firstGlyphIndex;
                         outAttributes[k].clusterStart = true;
                         ++k;
@@ -308,7 +336,7 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay
                     : QFixed::fromReal(lastGlyphAdvance.width);
 
             if (endWithPDF) {
-                logClusters[stringRange.location + stringRange.length - 1] = glyphCount;
+                logClusters[stringRange.location + stringRange.length - 1] = glyphCount + prepend;
                 outGlyphs[glyphCount] = 0xFFFF;
                 outAdvances_x[glyphCount] = 0;
                 outAdvances_y[glyphCount] = 0;
@@ -837,6 +865,15 @@ QFixed QCoreTextFontEngine::emSquareSize() const
     return QFixed::QFixed(int(CTFontGetUnitsPerEm(ctfont)));
 }
 
+QFontEngine *QCoreTextFontEngine::cloneWithSize(qreal pixelSize) const
+{
+    QFontDef newFontDef = fontDef;
+    newFontDef.pixelSize = pixelSize;
+    newFontDef.pointSize = pixelSize * 72.0 / qt_defaultDpi();
+
+    return new QCoreTextFontEngine(cgFont, fontDef);
+}
+
 QT_END_NAMESPACE
 
 #endif// !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
index 1503c3f..bb80a9b 100644 (file)
@@ -91,6 +91,8 @@ public:
     virtual qreal minLeftBearing() const;
     virtual QFixed emSquareSize() const;
 
+    virtual QFontEngine *cloneWithSize(qreal pixelSize) const;
+
 private:
     friend class QRawFontPrivate;
 
@@ -118,7 +120,8 @@ public:
                               QTextEngine::ShaperFlags flags) const;
     bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs,
                       QTextEngine::ShaperFlags flags,
-                      unsigned short *logClusters, const HB_CharAttributes *charAttributes) const;
+                      unsigned short *logClusters, const HB_CharAttributes *charAttributes,
+                      QScriptItem *si) const;
 
     virtual const char *name() const { return "CoreText"; }
 protected:
index 8f2da9b..58bcca8 100644 (file)
@@ -2069,6 +2069,41 @@ HB_Error QFontEngineFT::getPointInOutline(HB_Glyph glyph, int flags, hb_uint32 p
     return result;
 }
 
+bool QFontEngineFT::initFromFontEngine(const QFontEngineFT *fe)
+{
+    if (!init(fe->faceId(), fe->antialias, fe->defaultFormat, fe->freetype))
+        return false;
+
+    // Increase the reference of this QFreetypeFace since one more QFontEngineFT
+    // will be using it
+    freetype->ref.ref();
+
+    default_load_flags = fe->default_load_flags;
+    default_hint_style = fe->default_hint_style;
+    antialias = fe->antialias;
+    transform = fe->transform;
+    embolden = fe->embolden;
+    subpixelType = fe->subpixelType;
+    lcdFilterType = fe->lcdFilterType;
+    canUploadGlyphsToServer = fe->canUploadGlyphsToServer;
+    embeddedbitmap = fe->embeddedbitmap;
+
+    return true;
+}
+
+QFontEngine *QFontEngineFT::cloneWithSize(qreal pixelSize) const
+{
+    QFontDef fontDef;
+    fontDef.pixelSize = pixelSize;
+    QFontEngineFT *fe = new QFontEngineFT(fontDef);
+    if (!fe->initFromFontEngine(this)) {
+        delete fe;
+        return 0;
+    } else {
+        return fe;
+    }
+}
+
 QT_END_NAMESPACE
 
 #endif // QT_NO_FREETYPE
index 887efed..2c335f3 100644 (file)
@@ -122,7 +122,7 @@ struct QFreetypeFace
     static void addBitmapToPath(FT_GlyphSlot slot, const QFixedPoint &point, QPainterPath *path, bool = false);
 
 private:
-    friend class QFontEngineFTRawFont;
+    friend class QFontEngineFT;
     friend class QScopedPointerDeleter<QFreetypeFace>;
     QFreetypeFace() : _lock(QMutex::Recursive) {}
     ~QFreetypeFace() {}
@@ -311,14 +311,12 @@ private:
 
     virtual HB_Error getPointInOutline(HB_Glyph glyph, int flags, hb_uint32 point, HB_Fixed *xpos, HB_Fixed *ypos, hb_uint32 *nPoints);
 
-    enum HintStyle {
-        HintNone,
-        HintLight,
-        HintMedium,
-        HintFull
-    };
 
-    void setDefaultHintStyle(HintStyle style);
+    virtual void setDefaultHintStyle(HintStyle style);
+
+    virtual QFontEngine *cloneWithSize(qreal pixelSize) const;
+    bool initFromFontEngine(const QFontEngineFT *fontEngine);
+
     HintStyle defaultHintStyle() const { return default_hint_style; }
 protected:
 
index 673a7c8..9f094ad 100644 (file)
@@ -377,7 +377,7 @@ bool QFontEngineMacMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *
 }
 
 bool QFontEngineMacMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags,
-                                       unsigned short *logClusters, const HB_CharAttributes *charAttributes) const
+                                       unsigned short *logClusters, const HB_CharAttributes *charAttributes, QScriptItem *) const
 {
     if (*nglyphs < len) {
         *nglyphs = len;
index 385fa83..292ea98 100644 (file)
@@ -131,7 +131,7 @@ public:
 
     virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const;
     bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags,
-                      unsigned short *logClusters, const HB_CharAttributes *charAttributes) const;
+                      unsigned short *logClusters, const HB_CharAttributes *charAttributes, QScriptItem *) const;
 
     virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const;
     virtual void doKerning(QGlyphLayout *, QTextEngine::ShaperFlags) const;
index 5b39fd3..b74371c 100644 (file)
@@ -235,6 +235,8 @@ public:
 
     virtual int glyphCount() const;
 
+    virtual QFontEngine *cloneWithSize(qreal /*pixelSize*/) const { return 0; }
+
     HB_Font harfbuzzFont() const;
     HB_Face harfbuzzFace() const;
 
@@ -248,6 +250,14 @@ public:
 
     static QByteArray convertToPostscriptFontFamilyName(const QByteArray &fontFamily);
 
+    enum HintStyle {
+        HintNone,
+        HintLight,
+        HintMedium,
+        HintFull
+    };
+    virtual void setDefaultHintStyle(HintStyle) { }
+
     QAtomicInt ref;
     QFontDef fontDef;
     uint cache_cost; // amount of mem used in kb by the font
index 82d9da0..54d7ec2 100644 (file)
@@ -1284,6 +1284,23 @@ QImage QFontEngineWin::alphaRGBMapForGlyph(glyph_t glyph, QFixed, int margin, co
     return rgbMask;
 }
 
+// From qfontdatabase_win.cpp
+extern QFontEngine *qt_load_font_engine_win(const QFontDef &request);
+QFontEngine *QFontEngineWin::cloneWithSize(qreal pixelSize) const
+{
+    QFontDef request = fontDef;
+    QString actualFontName = request.family;
+    if (!uniqueFamilyName.isEmpty())
+        request.family = uniqueFamilyName;
+    request.pixelSize = pixelSize;
+
+    QFontEngine *fontEngine = qt_load_font_engine_win(request);
+    if (fontEngine != NULL)
+        fontEngine->fontDef.family = actualFontName;
+
+    return fontEngine;
+}
+
 // -------------------------------------- Multi font engine
 
 QFontEngineMultiWin::QFontEngineMultiWin(QFontEngine *first, const QStringList &fallbacks)
index 28d8000..114149d 100644 (file)
@@ -106,6 +106,8 @@ public:
     virtual QImage alphaMapForGlyph(glyph_t, const QTransform &xform);
     virtual QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform);
 
+    virtual QFontEngine *cloneWithSize(qreal pixelSize) const;
+
 #ifndef Q_CC_MINGW
     virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0);
 #endif
@@ -118,6 +120,7 @@ public:
 #endif
 
     QString     _name;
+    QString     uniqueFamilyName;
     HFONT       hfont;
     LOGFONT     logfont;
     uint        stockFont  : 1;
index 9f3f8d3..4260b85 100644 (file)
@@ -1196,6 +1196,20 @@ bool QFontEngineX11FT::uploadGlyphToServer(QGlyphSet *set, uint glyphid, Glyph *
 #endif
 }
 
+QFontEngine *QFontEngineX11FT::cloneWithSize(qreal pixelSize) const
+{
+    QFontDef fontDef;
+    fontDef.pixelSize = pixelSize;
+    QFontEngineX11FT *fe = new QFontEngineX11FT(fontDef);
+    if (!fe->initFromFontEngine(this)) {
+        delete fe;
+        return 0;
+    } else {
+        fe->xglyph_format = xglyph_format;
+        return fe;
+    }
+}
+
 #endif // QT_NO_FONTCONFIG
 
 QT_END_NAMESPACE
index ad68fac..d7eb39d 100644 (file)
@@ -161,6 +161,8 @@ public:
     explicit QFontEngineX11FT(FcPattern *pattern, const QFontDef &fd, int screen);
     ~QFontEngineX11FT();
 
+    QFontEngine *cloneWithSize(qreal pixelSize) const;
+
 #ifndef QT_NO_XRENDER
     int xglyph_format;
 #endif
index f0a3644..aab00c0 100644 (file)
@@ -630,6 +630,17 @@ QFontEngine::Type QFontEngineDirectWrite::type() const
     return QFontEngine::DirectWrite;
 }
 
+QFontEngine *QFontEngineDirectWrite::cloneWithSize(qreal pixelSize) const
+{
+    QFontEngine *fontEngine = new QFontEngineDirectWrite(m_directWriteFactory, m_directWriteFontFace,
+                                                         pixelSize);
+
+    fontEngine->fontDef = fontDef;
+    fontEngine->fontDef.pixelSize = pixelSize;
+
+    return fontEngine;
+}
+
 QT_END_NAMESPACE
 
 #endif // QT_NO_DIRECTWRITE
index c440a6c..53a4b0a 100644 (file)
@@ -101,6 +101,8 @@ public:
     QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, int margin,
                                const QTransform &xform);
 
+    QFontEngine *cloneWithSize(qreal pixelSize) const;
+
     bool canRender(const QChar *string, int len);
     Type type() const;
 
index b8a418d..cfea6ec 100644 (file)
@@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE
 
 /*!
     \class QGlyphs
-    \brief the QGlyphs class provides direct access to the internal glyphs in a font
+    \brief The QGlyphs class provides direct access to the internal glyphs in a font.
     \since 4.8
 
     \ingroup text
@@ -76,8 +76,8 @@ QT_BEGIN_NAMESPACE
     QTextLayout::glyphs() or QTextFragment::glyphs() can be used to convert unicode encoded text
     into a list of QGlyphs objects, and QPainter::drawGlyphs() can be used to draw the glyphs.
 
-    \note Please note that QRawFont is considered local to the thread in which it is constructed,
-    which in turn means that a new QRawFont will have to be created and set on the QGlyphs if it is
+    \note Please note that QRawFont is considered local to the thread in which it is constructed.
+    This in turn means that a new QRawFont will have to be created and set on the QGlyphs if it is
     moved to a different thread. If the QGlyphs contains a reference to a QRawFont from a different
     thread than the current, it will not be possible to draw the glyphs using a QPainter, as the
     QRawFont is considered invalid and inaccessible in this case.
index 6fa25e7..82ec279 100644 (file)
@@ -218,6 +218,16 @@ QFontEngine *QPlatformFontDatabase::fontEngine(const QFontDef &fontDef, QUnicode
     return engine;
 }
 
+QFontEngine *QPlatformFontDatabase::fontEngine(const QByteArray &fontData, qreal pixelSize,
+                                               QFont::HintingPreference hintingPreference)
+{
+    Q_UNUSED(fontData);
+    Q_UNUSED(pixelSize);
+    Q_UNUSED(hintingPreference);
+    qWarning("This plugin does not support font engines created directly from font data");
+    return 0;
+}
+
 /*!
 
 */
index e0e4f04..046311f 100644 (file)
@@ -92,6 +92,8 @@ public:
     virtual QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName);
     virtual void releaseHandle(void *handle);
 
+    virtual QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference);
+
     virtual QString fontDir() const;
 
     //callback
index 4a715c2..1bce909 100644 (file)
@@ -308,10 +308,10 @@ qreal QRawFont::descent() const
 
    \sa setPixelSize()
 */
-int QRawFont::pixelSize() const
+qreal QRawFont::pixelSize() const
 {
     if (!isValid())
-        return -1;
+        return 0.0;
 
     return d->fontEngine->fontDef.pixelSize;
 }
@@ -577,10 +577,21 @@ QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writ
 /*!
    Sets the pixel size with which this font should be rendered to \a pixelSize.
 */
-void QRawFont::setPixelSize(int pixelSize)
+void QRawFont::setPixelSize(qreal pixelSize)
 {
+    if (d->fontEngine == 0)
+        return;
+
     detach();
-    d->platformSetPixelSize(pixelSize);
+    QFontEngine *oldFontEngine = d->fontEngine;
+
+    d->fontEngine = d->fontEngine->cloneWithSize(pixelSize);
+    if (d->fontEngine != 0)
+        d->fontEngine->ref.ref();
+
+    oldFontEngine->ref.deref();
+    if (oldFontEngine->cache_count == 0 && oldFontEngine->ref == 0)
+        delete oldFontEngine;
 }
 
 /*!
index 96dc838..56aeefc 100644 (file)
@@ -96,8 +96,8 @@ public:
                             const QTransform &transform = QTransform()) const;
     QPainterPath pathForGlyph(quint32 glyphIndex) const;
 
-    void setPixelSize(int pixelSize);
-    int pixelSize() const;
+    void setPixelSize(qreal pixelSize);
+    qreal pixelSize() const;
 
     QFont::HintingPreference hintingPreference() const;
 
index eefbd92..23d47eb 100644 (file)
@@ -90,32 +90,6 @@ public:
 
         return init(faceId, true, Format_None, fontData);
     }
-
-    bool initFromFontEngine(QFontEngine *oldFontEngine)
-    {
-        QFontEngineFT *fe = static_cast<QFontEngineFT *>(oldFontEngine);
-
-        // Increase the reference of this QFreetypeFace since one more QFontEngineFT
-        // will be using it
-        fe->freetype->ref.ref();
-        if (!init(fe->faceId(), fe->antialias, fe->defaultFormat, fe->freetype))
-            return false;
-
-        default_load_flags = fe->default_load_flags;
-        default_hint_style = fe->default_hint_style;
-        antialias = fe->antialias;
-        transform = fe->transform;
-        embolden = fe->embolden;
-        subpixelType = fe->subpixelType;
-        lcdFilterType = fe->lcdFilterType;
-        canUploadGlyphsToServer = fe->canUploadGlyphsToServer;
-        embeddedbitmap = fe->embeddedbitmap;
-
-#if defined(Q_WS_X11)
-        xglyph_format = static_cast<QFontEngineX11FT *>(fe)->xglyph_format;
-#endif
-        return true;
-    }
 };
 
 
@@ -159,31 +133,6 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, int pixel
     fontEngine->ref.ref();
 }
 
-void QRawFontPrivate::platformSetPixelSize(int pixelSize)
-{
-    if (fontEngine == NULL)
-        return;
-
-    QFontEngine *oldFontEngine = fontEngine;
-
-    QFontDef fontDef;
-    fontDef.pixelSize = pixelSize;
-    QFontEngineFTRawFont *fe = new QFontEngineFTRawFont(fontDef);
-    if (!fe->initFromFontEngine(oldFontEngine)) {
-        delete fe;
-        return;
-    }
-
-    fontEngine = fe;
-    fontEngine->fontDef = oldFontEngine->fontDef;
-    fontEngine->fontDef.pixelSize = pixelSize;
-    fontEngine->ref.ref();
-    Q_ASSERT(fontEngine != oldFontEngine);
-    oldFontEngine->ref.deref();
-    if (oldFontEngine->cache_count == 0 && oldFontEngine->ref == 0)
-        delete oldFontEngine;
-}
-
 QT_END_NAMESPACE
 
 #endif // QT_NO_RAWFONT
index 56005c6..1ed4185 100644 (file)
@@ -78,28 +78,6 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData,
     }
 }
 
-void QRawFontPrivate::platformSetPixelSize(int pixelSize)
-{
-    if (fontEngine == NULL)
-        return;
-
-    QFontEngine *oldFontEngine = fontEngine;
-
-    QFontDef fontDef = oldFontEngine->fontDef;
-    fontDef.pixelSize = pixelSize;
-    fontDef.pointSize = pixelSize * 72.0 / qt_defaultDpi();
-
-    QCoreTextFontEngine *ctFontEngine = static_cast<QCoreTextFontEngine *>(oldFontEngine);
-    Q_ASSERT(ctFontEngine->cgFont);
-
-    fontEngine = new QCoreTextFontEngine(ctFontEngine->cgFont, fontDef);
-    fontEngine->ref.ref();
-    Q_ASSERT(fontEngine != oldFontEngine);
-    oldFontEngine->ref.deref();
-    if (oldFontEngine->cache_count == 0 && oldFontEngine->ref == 0)
-        delete oldFontEngine;
-}
-
 QT_END_NAMESPACE
 
 #endif // QT_NO_RAWFONT
index f9a9ab5..6c84be2 100644 (file)
@@ -62,7 +62,7 @@
 QT_BEGIN_NAMESPACE
 
 namespace { class CustomFontFileLoader; }
-class Q_AUTOTEST_EXPORT QRawFontPrivate
+class Q_GUI_EXPORT QRawFontPrivate
 {
 public:
     QRawFontPrivate()
@@ -83,7 +83,6 @@ public:
         , fontHandle(NULL)
         , ptrAddFontMemResourceEx(other.ptrAddFontMemResourceEx)
         , ptrRemoveFontMemResourceEx(other.ptrRemoveFontMemResourceEx)
-        , uniqueFamilyName(other.uniqueFamilyName)
 #endif
     {
         fontEngine = other.fontEngine;
@@ -102,7 +101,6 @@ public:
     void platformLoadFromData(const QByteArray &fontData,
                               int pixelSize,
                               QFont::HintingPreference hintingPreference);
-    void platformSetPixelSize(int pixelSize);
 
     static QRawFontPrivate *get(const QRawFont &font) { return font.d.data(); }
 
@@ -120,8 +118,6 @@ public:
     PtrAddFontMemResourceEx ptrAddFontMemResourceEx;
     PtrRemoveFontMemResourceEx ptrRemoveFontMemResourceEx;
 
-    QString uniqueFamilyName;
-
 #endif // Q_WS_WIN
 };
 
diff --git a/src/gui/text/qrawfont_qpa.cpp b/src/gui/text/qrawfont_qpa.cpp
new file mode 100644 (file)
index 0000000..103619c
--- /dev/null
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qglobal.h>
+
+#if !defined(QT_NO_RAWFONT)
+
+#include "qrawfont_p.h"
+#include <QtGui/qplatformfontdatabase_qpa.h>
+#include <private/qapplication_p.h>
+
+QT_BEGIN_NAMESPACE
+
+void QRawFontPrivate::platformCleanUp()
+{
+}
+
+void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, int pixelSize,
+                                           QFont::HintingPreference hintingPreference)
+{
+    Q_ASSERT(fontEngine == 0);
+
+    QPlatformFontDatabase *pfdb = QApplicationPrivate::platformIntegration()->fontDatabase();
+    fontEngine = pfdb->fontEngine(fontData, pixelSize, hintingPreference);
+    if (fontEngine != 0)
+        fontEngine->ref.ref();
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_RAWFONT
index fb5c6f4..d8acf57 100644 (file)
@@ -559,7 +559,7 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &_fontData,
         GUID guid;
         CoCreateGuid(&guid);
 
-        uniqueFamilyName = QString::fromLatin1("f")
+        QString uniqueFamilyName = QString::fromLatin1("f")
                 + QString::number(guid.Data1, 36) + QLatin1Char('-')
                 + QString::number(guid.Data2, 36) + QLatin1Char('-')
                 + QString::number(guid.Data3, 36) + QLatin1Char('-')
@@ -613,6 +613,7 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &_fontData,
                 Q_ASSERT(fontEngine->cache_count == 0 && fontEngine->ref == 0);
 
                 // Override the generated font name
+                static_cast<QFontEngineWin *>(fontEngine)->uniqueFamilyName = uniqueFamilyName;
                 fontEngine->fontDef.family = actualFontName;
                 fontEngine->ref.ref();
             }
@@ -701,50 +702,6 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &_fontData,
     }
 }
 
-void QRawFontPrivate::platformSetPixelSize(int pixelSize)
-{
-    if (fontEngine == NULL)
-        return;
-
-    QFontEngine *oldFontEngine = fontEngine;
-
-#if !defined(QT_NO_DIRECTWRITE)
-    if (fontEngine->type() == QFontEngine::Win)
-#endif
-
-    {
-        QFontDef request = fontEngine->fontDef;
-        QString actualFontName = request.family;
-        if (!uniqueFamilyName.isEmpty())
-            request.family = uniqueFamilyName;
-        request.pixelSize = pixelSize;
-
-        fontEngine = qt_load_font_engine_win(request);
-        if (fontEngine != NULL) {
-            fontEngine->fontDef.family = actualFontName;
-            fontEngine->ref.ref();
-        }
-    }
-
-#if !defined(QT_NO_DIRECTWRITE)
-    else {
-        QFontEngineDirectWrite *dWriteFE = static_cast<QFontEngineDirectWrite *>(fontEngine);
-        fontEngine = new QFontEngineDirectWrite(dWriteFE->m_directWriteFactory,
-                                                dWriteFE->m_directWriteFontFace,
-                                                pixelSize);
-
-        fontEngine->fontDef = dWriteFE->fontDef;
-        fontEngine->fontDef.pixelSize = pixelSize;
-        fontEngine->ref.ref();
-    }
-#endif
-
-    Q_ASSERT(fontEngine != oldFontEngine);
-    oldFontEngine->ref.deref();
-    if (oldFontEngine->cache_count == 0 && oldFontEngine->ref == 0)
-        delete oldFontEngine;
-}
-
 QT_END_NAMESPACE
 
 #endif // QT_NO_RAWFONT
index 1cfb4b6..5bee497 100644 (file)
@@ -714,17 +714,13 @@ QStaticTextItem::~QStaticTextItem()
 {
     if (m_userData != 0 && !m_userData->ref.deref())
         delete m_userData;
-    if (!m_fontEngine->ref.deref())
-        delete m_fontEngine;
+    m_fontEngine->ref.deref();
 }
 
 void QStaticTextItem::setFontEngine(QFontEngine *fe)
 {
-    if (m_fontEngine != 0) {
-        if (!m_fontEngine->ref.deref())
-            delete m_fontEngine;
-    }
-
+    if (m_fontEngine != 0)
+        m_fontEngine->ref.deref();
     m_fontEngine = fe;
     if (m_fontEngine != 0)
         m_fontEngine->ref.ref();
index 6ddfdb0..4f6857a 100644 (file)
@@ -362,20 +362,23 @@ bool QTextCursorPrivate::movePosition(QTextCursor::MoveOperation op, QTextCursor
     currentCharFormat = -1;
     bool adjustX = true;
     QTextBlock blockIt = block();
+    bool visualMovement = priv->defaultCursorMoveStyle == QTextCursor::Visual;
 
     if (!blockIt.isValid())
         return false;
 
-    if (op >= QTextCursor::Left && op <= QTextCursor::WordRight
-        && blockIt.textDirection() == Qt::RightToLeft) {
-        if (op == QTextCursor::Left)
-            op = QTextCursor::NextCharacter;
-        else if (op == QTextCursor::Right)
-            op = QTextCursor::PreviousCharacter;
-        else if (op == QTextCursor::WordLeft)
+    if (blockIt.textDirection() == Qt::RightToLeft) {
+        if (op == QTextCursor::WordLeft)
             op = QTextCursor::NextWord;
         else if (op == QTextCursor::WordRight)
             op = QTextCursor::PreviousWord;
+
+        if (!visualMovement) {
+            if (op == QTextCursor::Left)
+                op = QTextCursor::NextCharacter;
+            else if (op == QTextCursor::Right)
+                op = QTextCursor::PreviousCharacter;
+        }
     }
 
     const QTextLayout *layout = blockLayout(blockIt);
@@ -418,9 +421,12 @@ bool QTextCursorPrivate::movePosition(QTextCursor::MoveOperation op, QTextCursor
         break;
     }
     case QTextCursor::PreviousCharacter:
-    case QTextCursor::Left:
         newPosition = priv->previousCursorPosition(position, QTextLayout::SkipCharacters);
         break;
+    case QTextCursor::Left:
+        newPosition = visualMovement ? priv->leftCursorPosition(position)
+                                     : priv->previousCursorPosition(position, QTextLayout::SkipCharacters);
+        break;
     case QTextCursor::StartOfWord: {
         if (relativePos == 0)
             break;
@@ -529,9 +535,12 @@ bool QTextCursorPrivate::movePosition(QTextCursor::MoveOperation op, QTextCursor
         break;
     }
     case QTextCursor::NextCharacter:
-    case QTextCursor::Right:
         newPosition = priv->nextCursorPosition(position, QTextLayout::SkipCharacters);
         break;
+    case QTextCursor::Right:
+        newPosition = visualMovement ? priv->rightCursorPosition(position)
+                                     : priv->nextCursorPosition(position, QTextLayout::SkipCharacters);
+        break;
     case QTextCursor::NextWord:
     case QTextCursor::WordRight:
         newPosition = priv->nextCursorPosition(position, QTextLayout::SkipWords);
@@ -2558,4 +2567,19 @@ QTextDocument *QTextCursor::document() const
     return 0; // document went away
 }
 
+/*!
+    \enum QTextCursor::MoveStyle
+
+    This enum describes the movement style available to QTextCursor. The options
+    are:
+
+    \value Logical Within a left-to-right text block, increase cursor position
+    when pressing left arrow key, decrease cursor position when pressing the
+    right arrow key. If the text block is right-to-left, the opposite behavior
+    applies.
+    \value Visual Pressing the left arrow key will always cause the cursor to move
+    left, regardless of the text's writing direction. The same behavior applies to
+    right arrow key.
+*/
+
 QT_END_NAMESPACE
index 4eaeb41..9e4c0b8 100644 (file)
@@ -86,6 +86,10 @@ public:
         MoveAnchor,
         KeepAnchor
     };
+    enum MoveStyle {
+        Logical,
+        Visual
+    };
 
     void setPosition(int pos, MoveMode mode = MoveAnchor);
     int position() const;
index 7d84e50..9169955 100644 (file)
@@ -586,6 +586,29 @@ void QTextDocument::setDefaultTextOption(const QTextOption &option)
 }
 
 /*!
+    \since 4.8
+
+    The default cursor movement style is used by all QTextCursor objects
+    created from the document. The default is QTextCursor::Logical.
+*/
+QTextCursor::MoveStyle QTextDocument::defaultCursorMoveStyle() const
+{
+    Q_D(const QTextDocument);
+    return d->defaultCursorMoveStyle;
+}
+
+/*!
+    \since 4.8
+
+    Set the default cursor movement style.
+*/
+void QTextDocument::setDefaultCursorMoveStyle(QTextCursor::MoveStyle style)
+{
+    Q_D(QTextDocument);
+    d->defaultCursorMoveStyle = style;
+}
+
+/*!
     \fn void QTextDocument::markContentsDirty(int position, int length)
 
     Marks the contents specified by the given \a position and \a length
index f87ccc9..e515b36 100644 (file)
@@ -46,6 +46,7 @@
 #include <QtCore/qsize.h>
 #include <QtCore/qrect.h>
 #include <QtGui/qfont.h>
+#include <QtGui/qtextcursor.h>
 
 QT_BEGIN_HEADER
 
@@ -60,7 +61,6 @@ class QPainter;
 class QPrinter;
 class QAbstractTextDocumentLayout;
 class QPoint;
-class QTextCursor;
 class QTextObject;
 class QTextFormat;
 class QTextFrame;
@@ -269,6 +269,9 @@ public:
     QTextOption defaultTextOption() const;
     void setDefaultTextOption(const QTextOption &option);
 
+    QTextCursor::MoveStyle defaultCursorMoveStyle() const;
+    void setDefaultCursorMoveStyle(QTextCursor::MoveStyle style);
+
 Q_SIGNALS:
     void contentsChange(int from, int charsRemoves, int charsAdded);
     void contentsChanged();
index a997720..779b1ff 100644 (file)
@@ -209,6 +209,7 @@ QTextDocumentPrivate::QTextDocumentPrivate()
 
     defaultTextOption.setTabStop(80); // same as in qtextengine.cpp
     defaultTextOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
+    defaultCursorMoveStyle = QTextCursor::Logical;
 
     indentWidth = 40;
     documentMargin = 4;
@@ -1382,6 +1383,20 @@ int QTextDocumentPrivate::previousCursorPosition(int position, QTextLayout::Curs
     return it.layout()->previousCursorPosition(position-start, mode) + start;
 }
 
+int QTextDocumentPrivate::leftCursorPosition(int position) const
+{
+    QTextBlock it = blocksFind(position);
+    int start = it.position();
+    return it.layout()->leftCursorPosition(position-start) + start;
+}
+
+int QTextDocumentPrivate::rightCursorPosition(int position) const
+{
+    QTextBlock it = blocksFind(position);
+    int start = it.position();
+    return it.layout()->rightCursorPosition(position-start) + start;
+}
+
 void QTextDocumentPrivate::changeObjectFormat(QTextObject *obj, int format)
 {
     beginEditBlock();
index b464f2e..6563920 100644 (file)
@@ -64,6 +64,7 @@
 #include "private/qtextformat_p.h"
 #include "QtGui/qtextdocument.h"
 #include "QtGui/qtextobject.h"
+#include "QtGui/qtextcursor.h"
 #include "QtCore/qmap.h"
 #include "QtCore/qvariant.h"
 #include "QtCore/qurl.h"
@@ -244,6 +245,8 @@ public:
 
     int nextCursorPosition(int position, QTextLayout::CursorMode mode) const;
     int previousCursorPosition(int position, QTextLayout::CursorMode mode) const;
+    int leftCursorPosition(int position) const;
+    int rightCursorPosition(int position) const;
 
     void changeObjectFormat(QTextObject *group, int format);
 
@@ -339,6 +342,7 @@ private:
 
 public:
     QTextOption defaultTextOption;
+    QTextCursor::MoveStyle defaultCursorMoveStyle;
 #ifndef QT_NO_CSSPARSER
     QCss::StyleSheet parsedDefaultStyleSheet;
 #endif
index ce157be..130f012 100644 (file)
@@ -2996,10 +2996,19 @@ void QTextDocumentLayout::resizeInlineObject(QTextInlineObject item, int posInDo
 
     QSizeF inlineSize = (pos == QTextFrameFormat::InFlow ? intrinsic : QSizeF(0, 0));
     item.setWidth(inlineSize.width());
-    if (f.verticalAlignment() == QTextCharFormat::AlignMiddle) {
+
+    QFontMetrics m(f.font());
+    switch (f.verticalAlignment())
+    {
+    case QTextCharFormat::AlignMiddle:
         item.setDescent(inlineSize.height() / 2);
         item.setAscent(inlineSize.height() / 2 - 1);
-    } else {
+        break;
+    case QTextCharFormat::AlignBaseline:
+        item.setDescent(m.descent());
+        item.setAscent(inlineSize.height() - m.descent() - 1);
+        break;
+    default:
         item.setDescent(0);
         item.setAscent(inlineSize.height() - 1);
     }
index 08d0eca..ff27bc6 100644 (file)
@@ -856,6 +856,21 @@ void QTextEngine::shapeLine(const QScriptLine &line)
     }
 }
 
+#if !defined(QT_ENABLE_HARFBUZZ_FOR_MAC)
+static bool enableHarfBuzz()
+{
+    static enum { Yes, No, Unknown } status = Unknown;
+
+    if (status == Unknown) {
+        QByteArray v = qgetenv("QT_ENABLE_HARFBUZZ");
+        bool value = !v.isEmpty() && v != "0" && v != "false";
+        if (value) status = Yes;
+        else status = No;
+    }
+    return status == Yes;
+}
+#endif
+
 void QTextEngine::shapeText(int item) const
 {
     Q_ASSERT(item < layoutData->items.size());
@@ -865,7 +880,24 @@ void QTextEngine::shapeText(int item) const
         return;
 
 #if defined(Q_WS_MAC)
-    shapeTextMac(item);
+#if !defined(QT_ENABLE_HARFBUZZ_FOR_MAC)
+    if (enableHarfBuzz()) {
+#endif
+        QFontEngine *actualFontEngine = fontEngine(si, &si.ascent, &si.descent, &si.leading);
+        if (actualFontEngine->type() == QFontEngine::Multi)
+            actualFontEngine = static_cast<QFontEngineMulti *>(actualFontEngine)->engine(0);
+
+        HB_Face face = actualFontEngine->harfbuzzFace();
+        HB_Script script = (HB_Script) si.analysis.script;
+        if (face->supported_scripts[script])
+            shapeTextWithHarfbuzz(item);
+        else
+            shapeTextMac(item);
+#if !defined(QT_ENABLE_HARFBUZZ_FOR_MAC)
+    } else {
+        shapeTextMac(item);
+    }
+#endif
 #elif defined(Q_WS_WINCE)
     shapeTextWithCE(item);
 #else
@@ -1242,6 +1274,10 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const
             actualFontEngine = static_cast<QFontEngineMulti *>(font)->engine(engineIdx);
         }
 
+        si.ascent = qMax(actualFontEngine->ascent(), si.ascent);
+        si.descent = qMax(actualFontEngine->descent(), si.descent);
+        si.leading = qMax(actualFontEngine->leading(), si.leading);
+
         shaper_item.font = actualFontEngine->harfbuzzFont();
         shaper_item.face = actualFontEngine->harfbuzzFace();
 
@@ -1304,6 +1340,7 @@ static void init(QTextEngine *e)
     e->ignoreBidi = false;
     e->cacheGlyphs = false;
     e->forceJustification = false;
+    e->visualMovement = false;
 
     e->layoutData = 0;
 
@@ -1565,6 +1602,8 @@ bool QTextEngine::isRightToLeft() const
     default:
         break;
     }
+    if (!layoutData)
+        itemize();
     // this places the cursor in the right position depending on the keyboard layout
     if (layoutData->string.isEmpty())
         return QApplication::keyboardInputDirection() == Qt::RightToLeft;
@@ -2737,6 +2776,182 @@ QFixed QTextEngine::leadingSpaceWidth(const QScriptLine &line)
     return width(line.from + pos, line.length - pos);
 }
 
+QFixed QTextEngine::alignLine(const QScriptLine &line)
+{
+    QFixed x = 0;
+    justify(line);
+    // if width is QFIXED_MAX that means we used setNumColumns() and that implicitly makes this line left aligned.
+    if (!line.justified && line.width != QFIXED_MAX) {
+        int align = option.alignment();
+        if (align & Qt::AlignLeft)
+            x -= leadingSpaceWidth(line);
+        if (align & Qt::AlignJustify && isRightToLeft())
+            align = Qt::AlignRight;
+        if (align & Qt::AlignRight)
+            x = line.width - (line.textAdvance + leadingSpaceWidth(line));
+        else if (align & Qt::AlignHCenter)
+            x = (line.width - (line.textAdvance + leadingSpaceWidth(line)))/2;
+    }
+    return x;
+}
+
+QFixed QTextEngine::offsetInLigature(const QScriptItem *si, int pos, int max, int glyph_pos)
+{
+    unsigned short *logClusters = this->logClusters(si);
+    const QGlyphLayout &glyphs = shapedGlyphs(si);
+
+    int offsetInCluster = 0;
+    for (int i = pos - 1; i >= 0; i--) {
+        if (logClusters[i] == glyph_pos)
+            offsetInCluster++;
+        else
+            break;
+    }
+
+    // in the case that the offset is inside a (multi-character) glyph,
+    // interpolate the position.
+    if (offsetInCluster > 0) {
+        int clusterLength = 0;
+        for (int i = pos - offsetInCluster; i < max; i++) {
+            if (logClusters[i] == glyph_pos)
+                clusterLength++;
+            else
+                break;
+        }
+        if (clusterLength)
+            return glyphs.advances_x[glyph_pos] * offsetInCluster / clusterLength;
+    }
+
+    return 0;
+}
+
+int QTextEngine::previousLogicalPosition(int oldPos) const
+{
+    const HB_CharAttributes *attrs = attributes();
+    if (!attrs || oldPos < 0)
+        return oldPos;
+
+    if (oldPos <= 0)
+        return 0;
+    oldPos--;
+    while (oldPos && !attrs[oldPos].charStop)
+        oldPos--;
+    return oldPos;
+}
+
+int QTextEngine::nextLogicalPosition(int oldPos) const
+{
+    const HB_CharAttributes *attrs = attributes();
+    int len = block.isValid() ? block.length() - 1
+                              : layoutData->string.length();
+    Q_ASSERT(len <= layoutData->string.length());
+    if (!attrs || oldPos < 0 || oldPos >= len)
+        return oldPos;
+
+    oldPos++;
+    while (oldPos < len && !attrs[oldPos].charStop)
+        oldPos++;
+    return oldPos;
+}
+
+int QTextEngine::lineNumberForTextPosition(int pos)
+{
+    if (!layoutData)
+        itemize();
+    if (pos == layoutData->string.length() && lines.size())
+        return lines.size() - 1;
+    for (int i = 0; i < lines.size(); ++i) {
+        const QScriptLine& line = lines[i];
+        if (line.from + line.length > pos)
+            return i;
+    }
+    return -1;
+}
+
+void QTextEngine::insertionPointsForLine(int lineNum, QVector<int> &insertionPoints)
+{
+    QTextLineItemIterator iterator(this, lineNum);
+    bool rtl = isRightToLeft();
+    bool lastLine = lineNum >= lines.size() - 1;
+
+    while (!iterator.atEnd()) {
+        iterator.next();
+        const QScriptItem *si = &layoutData->items[iterator.item];
+        if (si->analysis.bidiLevel % 2) {
+            int i = iterator.itemEnd - 1, min = iterator.itemStart;
+            if (lastLine && (rtl ? iterator.atBeginning() : iterator.atEnd()))
+                i++;
+            for (; i >= min; i--)
+                insertionPoints.push_back(i);
+        } else {
+            int i = iterator.itemStart, max = iterator.itemEnd;
+            if (lastLine && (rtl ? iterator.atBeginning() : iterator.atEnd()))
+                max++;
+            for (; i < max; i++)
+                insertionPoints.push_back(i);
+        }
+    }
+}
+
+int QTextEngine::endOfLine(int lineNum)
+{
+    QVector<int> insertionPoints;
+    insertionPointsForLine(lineNum, insertionPoints);
+
+    if (insertionPoints.size() > 0)
+        return insertionPoints.last();
+    return 0;
+}
+
+int QTextEngine::beginningOfLine(int lineNum)
+{
+    QVector<int> insertionPoints;
+    insertionPointsForLine(lineNum, insertionPoints);
+
+    if (insertionPoints.size() > 0)
+        return insertionPoints.first();
+    return 0;
+}
+
+int QTextEngine::positionAfterVisualMovement(int pos, QTextCursor::MoveOperation op)
+{
+    if (!layoutData)
+        itemize();
+
+    bool moveRight = (op == QTextCursor::Right);
+    bool alignRight = isRightToLeft();
+    if (!layoutData->hasBidi)
+        return moveRight ^ alignRight ? nextLogicalPosition(pos) : previousLogicalPosition(pos);
+
+    int lineNum = lineNumberForTextPosition(pos);
+    Q_ASSERT(lineNum >= 0);
+
+    QVector<int> insertionPoints;
+    insertionPointsForLine(lineNum, insertionPoints);
+    int i, max = insertionPoints.size();
+    for (i = 0; i < max; i++)
+        if (pos == insertionPoints[i]) {
+            if (moveRight) {
+                if (i + 1 < max)
+                    return insertionPoints[i + 1];
+            } else {
+                if (i > 0)
+                    return insertionPoints[i - 1];
+            }
+
+            if (moveRight ^ alignRight) {
+                if (lineNum + 1 < lines.size())
+                    return alignRight ? endOfLine(lineNum + 1) : beginningOfLine(lineNum + 1);
+            }
+            else {
+                if (lineNum > 0)
+                    return alignRight ? beginningOfLine(lineNum - 1) : endOfLine(lineNum - 1);
+            }
+        }
+
+    return pos;
+}
+
 QStackTextEngine::QStackTextEngine(const QString &string, const QFont &f)
     : QTextEngine(string, f),
       _layoutData(string, _memory, MemSize)
@@ -2841,5 +3056,127 @@ glyph_metrics_t glyph_metrics_t::transformed(const QTransform &matrix) const
     return m;
 }
 
+QTextLineItemIterator::QTextLineItemIterator(QTextEngine *_eng, int _lineNum, const QPointF &pos,
+                                             const QTextLayout::FormatRange *_selection)
+    : eng(_eng),
+      line(eng->lines[_lineNum]),
+      si(0),
+      lineNum(_lineNum),
+      lineEnd(line.from + line.length),
+      firstItem(eng->findItem(line.from)),
+      lastItem(eng->findItem(lineEnd - 1)),
+      nItems((firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0),
+      logicalItem(-1),
+      item(-1),
+      visualOrder(nItems),
+      levels(nItems),
+      selection(_selection)
+{
+    pos_x = x = QFixed::fromReal(pos.x());
+
+    x += line.x;
+
+    x += eng->alignLine(line);
+
+    for (int i = 0; i < nItems; ++i)
+        levels[i] = eng->layoutData->items[i+firstItem].analysis.bidiLevel;
+    QTextEngine::bidiReorder(nItems, levels.data(), visualOrder.data());
+
+    eng->shapeLine(line);
+}
+
+QScriptItem &QTextLineItemIterator::next()
+{
+    x += itemWidth;
+
+    ++logicalItem;
+    item = visualOrder[logicalItem] + firstItem;
+    itemLength = eng->length(item);
+    si = &eng->layoutData->items[item];
+    if (!si->num_glyphs)
+        eng->shape(item);
+
+    if (si->analysis.flags >= QScriptAnalysis::TabOrObject) {
+        itemWidth = si->width;
+        return *si;
+    }
+
+    unsigned short *logClusters = eng->logClusters(si);
+    QGlyphLayout glyphs = eng->shapedGlyphs(si);
+
+    itemStart = qMax(line.from, si->position);
+    glyphsStart = logClusters[itemStart - si->position];
+    if (lineEnd < si->position + itemLength) {
+        itemEnd = lineEnd;
+        glyphsEnd = logClusters[itemEnd-si->position];
+    } else {
+        itemEnd = si->position + itemLength;
+        glyphsEnd = si->num_glyphs;
+    }
+    // show soft-hyphen at line-break
+    if (si->position + itemLength >= lineEnd
+        && eng->layoutData->string.at(lineEnd - 1) == 0x00ad)
+        glyphs.attributes[glyphsEnd - 1].dontPrint = false;
+
+    itemWidth = 0;
+    for (int g = glyphsStart; g < glyphsEnd; ++g)
+        itemWidth += glyphs.effectiveAdvance(g);
+
+    return *si;
+}
+
+bool QTextLineItemIterator::getSelectionBounds(QFixed *selectionX, QFixed *selectionWidth) const
+{
+    *selectionX = *selectionWidth = 0;
+
+    if (!selection)
+        return false;
+
+    if (si->analysis.flags >= QScriptAnalysis::TabOrObject) {
+        if (si->position >= selection->start + selection->length
+            || si->position + itemLength <= selection->start)
+            return false;
+
+        *selectionX = x;
+        *selectionWidth = itemWidth;
+    } else {
+        unsigned short *logClusters = eng->logClusters(si);
+        QGlyphLayout glyphs = eng->shapedGlyphs(si);
+
+        int from = qMax(itemStart, selection->start) - si->position;
+        int to = qMin(itemEnd, selection->start + selection->length) - si->position;
+        if (from >= to)
+            return false;
+
+        int start_glyph = logClusters[from];
+        int end_glyph = (to == eng->length(item)) ? si->num_glyphs : logClusters[to];
+        QFixed soff;
+        QFixed swidth;
+        if (si->analysis.bidiLevel %2) {
+            for (int g = glyphsEnd - 1; g >= end_glyph; --g)
+                soff += glyphs.effectiveAdvance(g);
+            for (int g = end_glyph - 1; g >= start_glyph; --g)
+                swidth += glyphs.effectiveAdvance(g);
+        } else {
+            for (int g = glyphsStart; g < start_glyph; ++g)
+                soff += glyphs.effectiveAdvance(g);
+            for (int g = start_glyph; g < end_glyph; ++g)
+                swidth += glyphs.effectiveAdvance(g);
+        }
+
+        // If the starting character is in the middle of a ligature,
+        // selection should only contain the right part of that ligature
+        // glyph, so we need to get the width of the left part here and
+        // add it to *selectionX
+        QFixed leftOffsetInLigature = eng->offsetInLigature(si, from, to, start_glyph);
+        *selectionX = x + soff + leftOffsetInLigature;
+        *selectionWidth = swidth - leftOffsetInLigature;
+        // If the ending character is also part of a ligature, swidth does
+        // not contain that part yet, we also need to find out the width of
+        // that left part
+        *selectionWidth += eng->offsetInLigature(si, to, eng->length(item), end_glyph);
+    }
+    return true;
+}
 
 QT_END_NAMESPACE
index 97e8c5b..2c6e579 100644 (file)
@@ -605,11 +605,11 @@ void QTextEngine::shapeTextMac(int item) const
     unsigned short *log_clusters = logClusters(&si);
 
     bool stringToCMapFailed = false;
-    if (!fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters, attributes())) {
+    if (!fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters, attributes(), &si)) {
         ensureSpace(num_glyphs);
         g = availableGlyphs(&si);
         stringToCMapFailed = !fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters,
-                                               attributes());
+                                               attributes(), &si);
     }
 
     if (!stringToCMapFailed) {
index 366c5c3..c476485 100644 (file)
@@ -64,6 +64,7 @@
 #include "QtGui/qpaintengine.h"
 #include "QtGui/qtextobject.h"
 #include "QtGui/qtextoption.h"
+#include "QtGui/qtextcursor.h"
 #include "QtCore/qset.h"
 #include "QtCore/qdebug.h"
 #ifndef QT_BUILD_COMPAT_LIB
@@ -471,6 +472,7 @@ public:
     void shape(int item) const;
 
     void justify(const QScriptLine &si);
+    QFixed alignLine(const QScriptLine &line);
 
     QFixed width(int charFrom, int numChars) const;
     glyph_metrics_t boundingBox(int from,  int len) const;
@@ -586,12 +588,18 @@ public:
     uint cacheGlyphs : 1;
     uint stackEngine : 1;
     uint forceJustification : 1;
+    uint visualMovement : 1;
 
     int *underlinePositions;
 
     mutable LayoutData *layoutData;
 
     inline bool hasFormats() const { return (block.docHandle() || specialData); }
+    inline bool visualCursorMovement() const
+    {
+        return (visualMovement ||
+                (block.docHandle() ? block.docHandle()->defaultCursorMoveStyle == QTextCursor::Visual : false));
+    }
 
     struct SpecialData {
         int preeditPosition;
@@ -611,6 +619,13 @@ public:
     void shapeLine(const QScriptLine &line);
     QFixed leadingSpaceWidth(const QScriptLine &line);
 
+    QFixed offsetInLigature(const QScriptItem *si, int pos, int max, int glyph_pos);
+    int previousLogicalPosition(int oldPos) const;
+    int nextLogicalPosition(int oldPos) const;
+    int lineNumberForTextPosition(int pos);
+    int positionAfterVisualMovement(int oldPos, QTextCursor::MoveOperation op);
+    void insertionPointsForLine(int lineNum, QVector<int> &insertionPoints);
+
 private:
     void setBoundary(int strPos) const;
     void addRequiredBoundaries() const;
@@ -625,6 +640,8 @@ private:
     void splitItem(int item, int pos) const;
 
     void resolveAdditionalFormats() const;
+    int endOfLine(int lineNum);
+    int beginningOfLine(int lineNum);
 };
 
 class QStackTextEngine : public QTextEngine {
@@ -635,6 +652,49 @@ public:
     void *_memory[MemSize];
 };
 
+struct QTextLineItemIterator
+{
+    QTextLineItemIterator(QTextEngine *eng, int lineNum, const QPointF &pos = QPointF(),
+                          const QTextLayout::FormatRange *_selection = 0);
+
+    inline bool atEnd() const { return logicalItem >= nItems - 1; }
+    inline bool atBeginning() const { return logicalItem <= 0; }
+    QScriptItem &next();
+
+    bool getSelectionBounds(QFixed *selectionX, QFixed *selectionWidth) const;
+    inline bool isOutsideSelection() const {
+        QFixed tmp1, tmp2;
+        return !getSelectionBounds(&tmp1, &tmp2);
+    }
+
+    QTextEngine *eng;
+
+    QFixed x;
+    QFixed pos_x;
+    const QScriptLine &line;
+    QScriptItem *si;
+
+    int lineNum;
+    int lineEnd;
+    int firstItem;
+    int lastItem;
+    int nItems;
+    int logicalItem;
+    int item;
+    int itemLength;
+
+    int glyphsStart;
+    int glyphsEnd;
+    int itemStart;
+    int itemEnd;
+
+    QFixed itemWidth;
+
+    QVarLengthArray<int> visualOrder;
+    QVarLengthArray<uchar> levels;
+
+    const QTextLayout::FormatRange *selection;
+};
 
 Q_DECLARE_OPERATORS_FOR_FLAGS(QTextEngine::ShaperFlags)
 
index ff28eaa..4f4752a 100644 (file)
@@ -378,7 +378,8 @@ public:
         AlignSubScript,
         AlignMiddle,
         AlignTop,
-        AlignBottom
+        AlignBottom,
+        AlignBaseline
     };
     enum UnderlineStyle { // keep in sync with Qt::PenStyle!
         NoUnderline,
index 93f71d3..cb5ba0e 100644 (file)
@@ -72,23 +72,6 @@ QT_BEGIN_NAMESPACE
 #define SuppressText 0x5012
 #define SuppressBackground 0x513
 
-static QFixed alignLine(QTextEngine *eng, const QScriptLine &line)
-{
-    QFixed x = 0;
-    eng->justify(line);
-    // if width is QFIXED_MAX that means we used setNumColumns() and that implicitly makes this line left aligned.
-    if (!line.justified && line.width != QFIXED_MAX) {
-        int align = eng->option.alignment();
-        if (align & Qt::AlignJustify && eng->isRightToLeft())
-            align = Qt::AlignRight;
-        if (align & Qt::AlignRight)
-            x = line.width - (line.textAdvance + eng->leadingSpaceWidth(line));
-        else if (align & Qt::AlignHCenter)
-            x = (line.width - line.textAdvance)/2;
-    }
-    return x;
-}
-
 /*!
     \class QTextLayout::FormatRange
     \reentrant
@@ -596,6 +579,30 @@ bool QTextLayout::cacheEnabled() const
 }
 
 /*!
+    Set the visual cursor movement style. If the QTextLayout is backed by
+    a document, you can ignore this and use the option in QTextDocument,
+    this option is for widgets like QLineEdit or custom widgets without
+    a QTextDocument. Default value is QTextCursor::Logical.
+
+    \sa setCursorMoveStyle()
+*/
+void QTextLayout::setCursorMoveStyle(QTextCursor::MoveStyle style)
+{
+    d->visualMovement = style == QTextCursor::Visual ? true : false;
+}
+
+/*!
+    The cursor movement style of this QTextLayout. The default is
+    QTextCursor::Logical.
+
+    \sa setCursorMoveStyle()
+*/
+QTextCursor::MoveStyle QTextLayout::cursorMoveStyle() const
+{
+    return d->visualMovement ? QTextCursor::Visual : QTextCursor::Logical;
+}
+
+/*!
     Begins the layout process.
 
     \sa endLayout()
@@ -718,6 +725,34 @@ int QTextLayout::previousCursorPosition(int oldPos, CursorMode mode) const
 }
 
 /*!
+    Returns the cursor position to the right of \a oldPos, next to it.
+    It's dependent on the visual position of characters, after bi-directional
+    reordering.
+
+    \sa leftCursorPosition(), nextCursorPosition()
+*/
+int QTextLayout::rightCursorPosition(int oldPos) const
+{
+    int newPos = d->positionAfterVisualMovement(oldPos, QTextCursor::Right);
+//    qDebug("%d -> %d", oldPos, newPos);
+    return newPos;
+}
+
+/*!
+    Returns the cursor position to the left of \a oldPos, next to it.
+    It's dependent on the visual position of characters, after bi-directional
+    reordering.
+
+    \sa rightCursorPosition(), previousCursorPosition()
+*/
+int QTextLayout::leftCursorPosition(int oldPos) const
+{
+    int newPos = d->positionAfterVisualMovement(oldPos, QTextCursor::Left);
+//    qDebug("%d -> %d", oldPos, newPos);
+    return newPos;
+}
+
+/*!/
     Returns true if position \a pos is a valid cursor position.
 
     In a Unicode context some positions in the text are not valid
@@ -815,16 +850,8 @@ QTextLine QTextLayout::lineAt(int i) const
 */
 QTextLine QTextLayout::lineForTextPosition(int pos) const
 {
-    for (int i = 0; i < d->lines.size(); ++i) {
-        const QScriptLine& line = d->lines[i];
-        if (line.from + (int)line.length > pos)
-            return QTextLine(i, d);
-    }
-    if (!d->layoutData)
-        d->itemize();
-    if (pos == d->layoutData->string.length() && d->lines.size())
-        return QTextLine(d->lines.size()-1, d);
-    return QTextLine();
+    int lineNum = d->lineNumberForTextPosition(pos);
+    return lineNum >= 0 ? lineAt(lineNum) : QTextLine();
 }
 
 /*!
@@ -919,201 +946,6 @@ void QTextLayout::setFlags(int flags)
     }
 }
 
-struct QTextLineItemIterator
-{
-    QTextLineItemIterator(QTextEngine *eng, int lineNum, const QPointF &pos = QPointF(),
-                          const QTextLayout::FormatRange *_selection = 0);
-
-    inline bool atEnd() const { return logicalItem >= nItems - 1; }
-    QScriptItem &next();
-
-    bool getSelectionBounds(QFixed *selectionX, QFixed *selectionWidth) const;
-    inline bool isOutsideSelection() const {
-        QFixed tmp1, tmp2;
-        return !getSelectionBounds(&tmp1, &tmp2);
-    }
-
-    QTextEngine *eng;
-
-    QFixed x;
-    QFixed pos_x;
-    const QScriptLine &line;
-    QScriptItem *si;
-
-    int lineEnd;
-    int firstItem;
-    int lastItem;
-    int nItems;
-    int logicalItem;
-    int item;
-    int itemLength;
-
-    int glyphsStart;
-    int glyphsEnd;
-    int itemStart;
-    int itemEnd;
-
-    QFixed itemWidth;
-
-    QVarLengthArray<int> visualOrder;
-    QVarLengthArray<uchar> levels;
-
-    const QTextLayout::FormatRange *selection;
-};
-
-QTextLineItemIterator::QTextLineItemIterator(QTextEngine *_eng, int lineNum, const QPointF &pos,
-                                             const QTextLayout::FormatRange *_selection)
-    : eng(_eng),
-      line(eng->lines[lineNum]),
-      si(0),
-      lineEnd(line.from + line.length),
-      firstItem(eng->findItem(line.from)),
-      lastItem(eng->findItem(lineEnd - 1)),
-      nItems((firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0),
-      logicalItem(-1),
-      item(-1),
-      visualOrder(nItems),
-      levels(nItems),
-      selection(_selection)
-{
-    pos_x = x = QFixed::fromReal(pos.x());
-
-    x += line.x;
-
-    x += alignLine(eng, line);
-
-    for (int i = 0; i < nItems; ++i)
-        levels[i] = eng->layoutData->items[i+firstItem].analysis.bidiLevel;
-    QTextEngine::bidiReorder(nItems, levels.data(), visualOrder.data());
-
-    eng->shapeLine(line);
-}
-
-QScriptItem &QTextLineItemIterator::next()
-{
-    x += itemWidth;
-
-    ++logicalItem;
-    item = visualOrder[logicalItem] + firstItem;
-    itemLength = eng->length(item);
-    si = &eng->layoutData->items[item];
-    if (!si->num_glyphs)
-        eng->shape(item);
-
-    if (si->analysis.flags >= QScriptAnalysis::TabOrObject) {
-        itemWidth = si->width;
-        return *si;
-    }
-
-    unsigned short *logClusters = eng->logClusters(si);
-    QGlyphLayout glyphs = eng->shapedGlyphs(si);
-
-    itemStart = qMax(line.from, si->position);
-    glyphsStart = logClusters[itemStart - si->position];
-    if (lineEnd < si->position + itemLength) {
-        itemEnd = lineEnd;
-        glyphsEnd = logClusters[itemEnd-si->position];
-    } else {
-        itemEnd = si->position + itemLength;
-        glyphsEnd = si->num_glyphs;
-    }
-    // show soft-hyphen at line-break
-    if (si->position + itemLength >= lineEnd
-        && eng->layoutData->string.at(lineEnd - 1) == 0x00ad)
-        glyphs.attributes[glyphsEnd - 1].dontPrint = false;
-
-    itemWidth = 0;
-    for (int g = glyphsStart; g < glyphsEnd; ++g)
-        itemWidth += glyphs.effectiveAdvance(g);
-
-    return *si;
-}
-
-static QFixed offsetInLigature(const unsigned short *logClusters,
-                               const QGlyphLayout &glyphs,
-                               int pos, int max, int glyph_pos)
-{
-    int offsetInCluster = 0;
-    for (int i = pos - 1; i >= 0; i--) {
-        if (logClusters[i] == glyph_pos)
-            offsetInCluster++;
-        else
-            break;
-    }
-
-    // in the case that the offset is inside a (multi-character) glyph,
-    // interpolate the position.
-    if (offsetInCluster > 0) {
-        int clusterLength = 0;
-        for (int i = pos - offsetInCluster; i < max; i++) {
-            if (logClusters[i] == glyph_pos)
-                clusterLength++;
-            else
-                break;
-        }
-        if (clusterLength)
-            return glyphs.advances_x[glyph_pos] * offsetInCluster / clusterLength;
-    }
-
-    return 0;
-}
-
-bool QTextLineItemIterator::getSelectionBounds(QFixed *selectionX, QFixed *selectionWidth) const
-{
-    *selectionX = *selectionWidth = 0;
-
-    if (!selection)
-        return false;
-
-    if (si->analysis.flags >= QScriptAnalysis::TabOrObject) {
-        if (si->position >= selection->start + selection->length
-            || si->position + itemLength <= selection->start)
-            return false;
-
-        *selectionX = x;
-        *selectionWidth = itemWidth;
-    } else {
-        unsigned short *logClusters = eng->logClusters(si);
-        QGlyphLayout glyphs = eng->shapedGlyphs(si);
-
-        int from = qMax(itemStart, selection->start) - si->position;
-        int to = qMin(itemEnd, selection->start + selection->length) - si->position;
-        if (from >= to)
-            return false;
-
-        int start_glyph = logClusters[from];
-        int end_glyph = (to == eng->length(item)) ? si->num_glyphs : logClusters[to];
-        QFixed soff;
-        QFixed swidth;
-        if (si->analysis.bidiLevel %2) {
-            for (int g = glyphsEnd - 1; g >= end_glyph; --g)
-                soff += glyphs.effectiveAdvance(g);
-            for (int g = end_glyph - 1; g >= start_glyph; --g)
-                swidth += glyphs.effectiveAdvance(g);
-        } else {
-            for (int g = glyphsStart; g < start_glyph; ++g)
-                soff += glyphs.effectiveAdvance(g);
-            for (int g = start_glyph; g < end_glyph; ++g)
-                swidth += glyphs.effectiveAdvance(g);
-        }
-
-        // If the starting character is in the middle of a ligature,
-        // selection should only contain the right part of that ligature
-        // glyph, so we need to get the width of the left part here and
-        // add it to *selectionX
-        QFixed leftOffsetInLigature = offsetInLigature(logClusters, glyphs, from,
-                                                       to, start_glyph);
-        *selectionX = x + soff + leftOffsetInLigature;
-        *selectionWidth = swidth - leftOffsetInLigature;
-        // If the ending character is also part of a ligature, swidth does
-        // not contain that part yet, we also need to find out the width of
-        // that left part
-        *selectionWidth += offsetInLigature(logClusters, glyphs, to,
-                                            eng->length(item), end_glyph);
-    }
-    return true;
-}
-
 static void addSelectedRegionsToPath(QTextEngine *eng, int lineNumber, const QPointF &pos, QTextLayout::FormatRange *selection,
                                      QPainterPath *region, QRectF boundingRect)
 {
@@ -1228,6 +1060,7 @@ void QTextLayout::draw(QPainter *p, const QPointF &pos, const QVector<FormatRang
 
             QRectF lineRect(tl.naturalTextRect());
             lineRect.translate(position);
+            lineRect.adjust(0, 0, d->leadingSpaceWidth(sl).toReal(), 0);
 
             bool isLastLineInBlock = (line == d->lines.size()-1);
             int sl_length = sl.length + (isLastLineInBlock? 1 : 0); // the infamous newline
@@ -1382,18 +1215,9 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition
     QFixed pos_y = QFixed::fromReal(position.y());
 
     cursorPosition = qBound(0, cursorPosition, d->layoutData->string.length());
-    int line = 0;
-    if (cursorPosition == d->layoutData->string.length()) {
-        line = d->lines.size() - 1;
-    } else {
-        // ### binary search
-        for (line = 0; line < d->lines.size(); line++) {
-            const QScriptLine &sl = d->lines[line];
-            if (sl.from <= cursorPosition && sl.from + (int)sl.length > cursorPosition)
-                break;
-        }
-    }
-
+    int line = d->lineNumberForTextPosition(cursorPosition);
+    if (line < 0)
+        line = 0;
     if (line >= d->lines.size())
         return;
 
@@ -1402,7 +1226,15 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition
 
     qreal x = position.x() + l.cursorToX(cursorPosition);
 
-    int itm = d->findItem(cursorPosition - 1);
+    int itm;
+
+    if (d->visualCursorMovement()) {
+        if (cursorPosition == sl.from + sl.length)
+            cursorPosition--;
+        itm = d->findItem(cursorPosition);
+    } else
+        itm = d->findItem(cursorPosition - 1);
+
     QFixed base = sl.base();
     QFixed descent = sl.descent;
     bool rightToLeft = d->isRightToLeft();
@@ -1512,7 +1344,7 @@ QRectF QTextLine::rect() const
 QRectF QTextLine::naturalTextRect() const
 {
     const QScriptLine& sl = eng->lines[i];
-    QFixed x = sl.x + alignLine(eng, sl);
+    QFixed x = sl.x + eng->alignLine(sl);
 
     QFixed width = sl.textWidth;
     if (sl.justified)
@@ -2317,6 +2149,9 @@ QList<QGlyphs> QTextLine::glyphs(int from, int length) const
                     QGlyphLayout subLayout = glyphLayout.mid(start, end - start);
                     glyphLayoutHash.insertMulti(multiFontEngine->engine(which),
                                                 GlyphInfo(subLayout, pos, flags));
+                    for (int i = 0; i < subLayout.numGlyphs; i++)
+                        pos += QPointF(subLayout.advances_x[i].toReal(),
+                                       subLayout.advances_y[i].toReal());
 
                     start = end;
                     which = e;
@@ -2632,9 +2467,10 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
         eng->itemize();
 
     const QScriptLine &line = eng->lines[i];
+    bool lastLine = i >= eng->lines.size() - 1;
 
     QFixed x = line.x;
-    x += alignLine(eng, line);
+    x += eng->alignLine(line);
 
     if (!i && !eng->layoutData->items.size()) {
         *cursorPos = 0;
@@ -2720,21 +2556,29 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
     logClusters = eng->logClusters(si);
     glyphs = eng->shapedGlyphs(si);
     if (si->analysis.flags >= QScriptAnalysis::TabOrObject) {
-        if(pos == l)
+        if (pos == (reverse ? 0 : l))
             x += si->width;
     } else {
+        bool rtl = eng->isRightToLeft();
+        bool visual = eng->visualCursorMovement();
         if (reverse) {
             int end = qMin(lineEnd, si->position + l) - si->position;
             int glyph_end = end == l ? si->num_glyphs : logClusters[end];
-            for (int i = glyph_end - 1; i >= glyph_pos; i--)
+            int glyph_start = glyph_pos;
+            if (visual && !rtl && !(lastLine && itm == (visualOrder[nItems - 1] + firstItem)))
+                glyph_start++;
+            for (int i = glyph_end - 1; i >= glyph_start; i--)
                 x += glyphs.effectiveAdvance(i);
         } else {
             int start = qMax(line.from - si->position, 0);
             int glyph_start = logClusters[start];
-            for (int i = glyph_start; i < glyph_pos; i++)
+            int glyph_end = glyph_pos;
+            if (!visual || !rtl || (lastLine && itm == visualOrder[0] + firstItem))
+                glyph_end--;
+            for (int i = glyph_start; i <= glyph_end; i++)
                 x += glyphs.effectiveAdvance(i);
         }
-        x += offsetInLigature(logClusters, glyphs, pos, line.length, glyph_pos);
+        x += eng->offsetInLigature(si, pos, line.length, glyph_pos);
     }
 
     *cursorPos = pos + si->position;
@@ -2753,6 +2597,8 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
 {
     QFixed x = QFixed::fromReal(_x);
     const QScriptLine &line = eng->lines[i];
+    bool lastLine = i >= eng->lines.size() - 1;
+    int lineNum = i;
 
     if (!eng->layoutData)
         eng->itemize();
@@ -2770,7 +2616,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
         return 0;
 
     x -= line.x;
-    x -= alignLine(eng, line);
+    x -= eng->alignLine(line);
 //     qDebug("xToCursor: x=%f, cpos=%d", x.toReal(), cpos);
 
     QVarLengthArray<int> visualOrder(nItems);
@@ -2779,6 +2625,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
         levels[i] = eng->layoutData->items[i+firstItem].analysis.bidiLevel;
     QTextEngine::bidiReorder(nItems, levels.data(), visualOrder.data());
 
+    bool visual = eng->visualCursorMovement();
     if (x <= 0) {
         // left of first item
         int item = visualOrder[0]+firstItem;
@@ -2795,8 +2642,13 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
                || (line.justified && x < line.width)) {
         // has to be in one of the runs
         QFixed pos;
+        bool rtl = eng->isRightToLeft();
 
         eng->shapeLine(line);
+        QVector<int> insertionPoints;
+        if (visual && rtl)
+            eng->insertionPointsForLine(lineNum, insertionPoints);
+        int nchars = 0;
         for (int i = 0; i < nItems; ++i) {
             int item = visualOrder[i]+firstItem;
             QScriptItem &si = eng->layoutData->items[item];
@@ -2826,6 +2678,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
 
             if (pos + item_width < x) {
                 pos += item_width;
+                nchars += end;
                 continue;
             }
 //             qDebug("      inside run");
@@ -2870,27 +2723,60 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
             } else {
                 QFixed dist = INT_MAX/256;
                 if (si.analysis.bidiLevel % 2) {
-                    pos += item_width;
-                    while (gs <= ge) {
-                        if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) {
-                            glyph_pos = gs;
-                            dist = qAbs(x-pos);
+                    if (!visual || rtl || (lastLine && i == nItems - 1)) {
+                        pos += item_width;
+                        while (gs <= ge) {
+                            if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) {
+                                glyph_pos = gs;
+                                dist = qAbs(x-pos);
+                            }
+                            pos -= glyphs.effectiveAdvance(gs);
+                            ++gs;
+                        }
+                    } else {
+                        while (ge >= gs) {
+                            if (glyphs.attributes[ge].clusterStart && qAbs(x-pos) < dist) {
+                                glyph_pos = ge;
+                                dist = qAbs(x-pos);
+                            }
+                            pos += glyphs.effectiveAdvance(ge);
+                            --ge;
                         }
-                        pos -= glyphs.effectiveAdvance(gs);
-                        ++gs;
                     }
                 } else {
-                    while (gs <= ge) {
-                        if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) {
-                            glyph_pos = gs;
-                            dist = qAbs(x-pos);
+                    if (!visual || !rtl || (lastLine && i == 0)) {
+                        while (gs <= ge) {
+                            if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) {
+                                glyph_pos = gs;
+                                dist = qAbs(x-pos);
+                            }
+                            pos += glyphs.effectiveAdvance(gs);
+                            ++gs;
                         }
-                        pos += glyphs.effectiveAdvance(gs);
-                        ++gs;
+                    } else {
+                        QFixed oldPos = pos;
+                        while (gs <= ge) {
+                            pos += glyphs.effectiveAdvance(gs);
+                            if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) {
+                                glyph_pos = gs;
+                                dist = qAbs(x-pos);
+                            }
+                            ++gs;
+                        }
+                        pos = oldPos;
                     }
                 }
-                if (qAbs(x-pos) < dist)
+                if (qAbs(x-pos) < dist) {
+                    if (visual) {
+                        if (!rtl && i < nItems - 1) {
+                            nchars += end;
+                            continue;
+                        }
+                        if (rtl && nchars > 0)
+                            return insertionPoints[lastLine ? nchars : nchars - 1];
+                    }
                     return si.position + end;
+                }
             }
             Q_ASSERT(glyph_pos != -1);
             int j;
index 9dd8ebd..6aa81f9 100644 (file)
@@ -50,6 +50,7 @@
 #include <QtGui/qevent.h>
 #include <QtGui/qtextformat.h>
 #include <QtGui/qglyphs.h>
+#include <QtGui/qtextcursor.h>
 
 QT_BEGIN_HEADER
 
@@ -136,6 +137,9 @@ public:
     void setCacheEnabled(bool enable);
     bool cacheEnabled() const;
 
+    void setCursorMoveStyle(QTextCursor::MoveStyle style);
+    QTextCursor::MoveStyle cursorMoveStyle() const;
+
     void beginLayout();
     void endLayout();
     void clearLayout();
@@ -153,6 +157,8 @@ public:
     bool isValidCursorPosition(int pos) const;
     int nextCursorPosition(int oldPos, CursorMode mode = SkipCharacters) const;
     int previousCursorPosition(int oldPos, CursorMode mode = SkipCharacters) const;
+    int leftCursorPosition(int oldPos) const;
+    int rightCursorPosition(int oldPos) const;
 
     void draw(QPainter *p, const QPointF &pos, const QVector<FormatRange> &selections = QVector<FormatRange>(),
               const QRectF &clip = QRectF()) const;
index df9398c..e5d57d0 100644 (file)
@@ -114,6 +114,9 @@ unix:x11 {
         OBJECTIVE_SOURCES += \
                 text/qfontengine_coretext.mm \
                 text/qfontengine_mac.mm
+        contains(QT_CONFIG, harfbuzz) {
+            DEFINES += QT_ENABLE_HARFBUZZ_FOR_MAC
+        }
 }
 
 embedded {
@@ -136,7 +139,8 @@ qpa {
        SOURCES += \
                 text/qfont_qpa.cpp \
                 text/qfontengine_qpa.cpp \
-                text/qplatformfontdatabase_qpa.cpp
+                text/qplatformfontdatabase_qpa.cpp \
+                text/qrawfont_qpa.cpp
 
        HEADERS += \
                 text/qplatformfontdatabase_qpa.h
index 289faa9..eb4e142 100644 (file)
@@ -1585,6 +1585,7 @@ void QLineControl::processKeyEvent(QKeyEvent* event)
     }
 
     bool unknown = false;
+    bool visual = cursorMoveStyle() == QTextCursor::Visual;
 
     if (false) {
     }
@@ -1649,11 +1650,11 @@ void QLineControl::processKeyEvent(QKeyEvent* event)
 #endif
             moveCursor(selectionEnd(), false);
         } else {
-            cursorForward(0, layoutDirection() == Qt::LeftToRight ? 1 : -1);
+            cursorForward(0, visual ? 1 : (layoutDirection() == Qt::LeftToRight ? 1 : -1));
         }
     }
     else if (event == QKeySequence::SelectNextChar) {
-        cursorForward(1, layoutDirection() == Qt::LeftToRight ? 1 : -1);
+        cursorForward(1, visual ? 1 : (layoutDirection() == Qt::LeftToRight ? 1 : -1));
     }
     else if (event == QKeySequence::MoveToPreviousChar) {
 #if !defined(Q_WS_WIN) || defined(QT_NO_COMPLETER)
@@ -1664,11 +1665,11 @@ void QLineControl::processKeyEvent(QKeyEvent* event)
 #endif
             moveCursor(selectionStart(), false);
         } else {
-            cursorForward(0, layoutDirection() == Qt::LeftToRight ? -1 : 1);
+            cursorForward(0, visual ? -1 : (layoutDirection() == Qt::LeftToRight ? -1 : 1));
         }
     }
     else if (event == QKeySequence::SelectPreviousChar) {
-        cursorForward(1, layoutDirection() == Qt::LeftToRight ? -1 : 1);
+        cursorForward(1, visual ? -1 : (layoutDirection() == Qt::LeftToRight ? -1 : 1));
     }
     else if (event == QKeySequence::MoveToNextWord) {
         if (echoMode() == QLineEdit::Normal)
index 3c505c8..0042f17 100644 (file)
@@ -160,6 +160,8 @@ public:
     int cursorWidth() const { return m_cursorWidth; }
     void setCursorWidth(int value) { m_cursorWidth = value; }
 
+    QTextCursor::MoveStyle cursorMoveStyle() const { return m_textLayout.cursorMoveStyle(); }
+    void setCursorMoveStyle(QTextCursor::MoveStyle style) { m_textLayout.setCursorMoveStyle(style); }
 
     void moveCursor(int pos, bool mark = false);
     void cursorForward(bool mark, int steps)
@@ -167,10 +169,12 @@ public:
         int c = m_cursor;
         if (steps > 0) {
             while (steps--)
-                c = m_textLayout.nextCursorPosition(c);
+                c = cursorMoveStyle() == QTextCursor::Visual ? m_textLayout.rightCursorPosition(c)
+                                                             : m_textLayout.nextCursorPosition(c);
         } else if (steps < 0) {
             while (steps++)
-                c = m_textLayout.previousCursorPosition(c);
+                c = cursorMoveStyle() == QTextCursor::Visual ? m_textLayout.leftCursorPosition(c)
+                                                             : m_textLayout.previousCursorPosition(c);
         }
         moveCursor(c, mark);
     }
index 07bd273..43c3f52 100644 (file)
@@ -1112,6 +1112,34 @@ void QLineEdit::setDragEnabled(bool b)
 
 
 /*!
+  \property QLineEdit::cursorMoveStyle
+  \brief the movement style of cursor in this line edit
+  \since 4.8
+
+  When this property is set to QTextCursor::Visual, the line edit will use visual
+  movement style. Pressing the left arrow key will always cause the cursor to move
+  left, regardless of the text's writing direction. The same behavior applies to
+  right arrow key.
+
+  When the property is QTextCursor::Logical (the default), within a LTR text block,
+  increase cursor position when pressing left arrow key, decrease cursor position
+  when pressing the right arrow key. If the text block is right to left, the opposite
+  behavior applies.
+*/
+
+QTextCursor::MoveStyle QLineEdit::cursorMoveStyle() const
+{
+    Q_D(const QLineEdit);
+    return d->control->cursorMoveStyle();
+}
+
+void QLineEdit::setCursorMoveStyle(QTextCursor::MoveStyle style)
+{
+    Q_D(QLineEdit);
+    d->control->setCursorMoveStyle(style);
+}
+
+/*!
     \property QLineEdit::acceptableInput
     \brief whether the input satisfies the inputMask and the
     validator.
index 636cee7..73a736c 100644 (file)
@@ -43,6 +43,7 @@
 #define QLINEEDIT_H
 
 #include <QtGui/qframe.h>
+#include <QtGui/qtextcursor.h>
 #include <QtCore/qstring.h>
 #include <QtCore/qmargins.h>
 
@@ -158,6 +159,9 @@ public:
     void setDragEnabled(bool b);
     bool dragEnabled() const;
 
+    void setCursorMoveStyle(QTextCursor::MoveStyle style);
+    QTextCursor::MoveStyle cursorMoveStyle() const;
+
     QString inputMask() const;
     void setInputMask(const QString &inputMask);
     bool hasAcceptableInput() const;
index 18c684f..673f614 100644 (file)
@@ -1548,6 +1548,14 @@ namespace {
 
 }
 
+#if defined(Q_WS_WIN)
+static bool fontSmoothingApproximately(qreal target)
+{
+    extern Q_GUI_EXPORT qreal qt_fontsmoothing_gamma; // qapplication_win.cpp
+    return (qAbs(qt_fontsmoothing_gamma - target) < 0.2);
+}
+#endif
+
 // #define QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO
 
 void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyphType,
@@ -1786,7 +1794,6 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp
         shaderManager->setMaskType(QGLEngineShaderManager::PixelMask);
         prepareForDraw(false); // Text always causes src pixels to be transparent
     }
-    //### TODO: Gamma correction
 
     QGLTextureGlyphCache::FilterMode filterMode = (s->matrix.type() > QTransform::TxTranslate)?QGLTextureGlyphCache::Linear:QGLTextureGlyphCache::Nearest;
     if (lastMaskTextureUsed != cache->texture() || cache->filterMode() != filterMode) {
@@ -1809,12 +1816,31 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp
         }
     }
 
+    bool srgbFrameBufferEnabled = false;
+    if (ctx->d_ptr->extension_flags & QGLExtensions::SRGBFrameBuffer) {
+#if defined(Q_WS_MAC)
+        if (glyphType == QFontEngineGlyphCache::Raster_RGBMask)
+#elif defined(Q_WS_WIN)
+        if (glyphType != QFontEngineGlyphCache::Raster_RGBMask || fontSmoothingApproximately(2.1))
+#else
+        if (false)
+#endif
+        {
+            glEnable(FRAMEBUFFER_SRGB_EXT);
+            srgbFrameBufferEnabled = true;
+        }
+    }
+
 #if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO)
     glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, 0);
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 #else
     glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, elementIndices.data());
 #endif
+
+    if (srgbFrameBufferEnabled)
+        glDisable(FRAMEBUFFER_SRGB_EXT);
+
 }
 
 void QGL2PaintEngineEx::drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap,
@@ -1986,7 +2012,8 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
 
 #if !defined(QT_OPENGL_ES_2)
 #if defined(Q_WS_WIN)
-    if (qt_cleartype_enabled)
+    if (qt_cleartype_enabled
+        && (fontSmoothingApproximately(1.0) || fontSmoothingApproximately(2.1)))
 #endif
 #if defined(Q_WS_MAC)
     if (qt_applefontsmoothing_enabled)
index 94024f3..a5faa36 100644 (file)
@@ -1564,6 +1564,19 @@ QVertexSet<T> QTriangulator<T>::triangulate()
 template <typename T>
 QVertexSet<T> QTriangulator<T>::polyline()
 {
+    for (int i = 0; i < m_vertices.size(); ++i) {
+        Q_ASSERT(qAbs(m_vertices.at(i).x) < (1 << 21));
+        Q_ASSERT(qAbs(m_vertices.at(i).y) < (1 << 21));
+    }
+
+    if (!(m_hint & (QVectorPath::OddEvenFill | QVectorPath::WindingFill)))
+        m_hint |= QVectorPath::OddEvenFill;
+
+    if (m_hint & QVectorPath::NonConvexShapeMask) {
+        ComplexToSimple c2s(this);
+        c2s.decompose();
+    }
+
     QVertexSet<T> result;
     result.indices = m_indices;
     result.vertices.resize(2 * m_vertices.size());
@@ -3084,7 +3097,7 @@ QPolylineSet qPolyline(const QVectorPath &path,
     } else {
         QTriangulator<quint16> triangulator;
         triangulator.initialize(path, matrix, lod);
-        QVertexSet<quint16> vertexSet = triangulator.triangulate();
+        QVertexSet<quint16> vertexSet = triangulator.polyline();
         polyLineSet.vertices = vertexSet.vertices;
         polyLineSet.indices.setDataUshort(vertexSet.indices);
     }
@@ -3104,7 +3117,7 @@ QPolylineSet qPolyline(const QPainterPath &path,
     } else {
         QTriangulator<quint16> triangulator;
         triangulator.initialize(path, matrix, lod);
-        QVertexSet<quint16> vertexSet = triangulator.triangulate();
+        QVertexSet<quint16> vertexSet = triangulator.polyline();
         polyLineSet.vertices = vertexSet.vertices;
         polyLineSet.indices.setDataUshort(vertexSet.indices);
     }
index a205b92..081738a 100644 (file)
@@ -58,7 +58,7 @@
 
 QT_BEGIN_NAMESPACE
 
-class QVertexIndexVector
+class Q_OPENGL_EXPORT QVertexIndexVector
 {
 public:
     enum Type {
@@ -111,7 +111,7 @@ private:
     QVector<quint16> indices16;
 };
 
-struct QTriangleSet
+struct Q_OPENGL_EXPORT QTriangleSet
 {
     inline QTriangleSet() { }
     inline QTriangleSet(const QTriangleSet &other) : vertices(other.vertices), indices(other.indices) { }
@@ -122,14 +122,14 @@ struct QTriangleSet
     QVertexIndexVector indices; // [i[0], j[0], k[0], i[1], j[1], k[1], i[2], ...]
 };
 
-struct QPolylineSet
+struct Q_OPENGL_EXPORT QPolylineSet
 {
     inline QPolylineSet() { }
     inline QPolylineSet(const QPolylineSet &other) : vertices(other.vertices), indices(other.indices) { }
     QPolylineSet &operator = (const QPolylineSet &other) {vertices = other.vertices; indices = other.indices; return *this;}
 
     QVector<qreal> vertices; // [x[0], y[0], x[1], y[1], x[2], ...]
-    QVertexIndexVector indices;
+    QVertexIndexVector indices; // End of polyline is marked with -1.
 };
 
 // The vertex coordinates of the returned triangle set will be rounded to a grid with a mesh size
@@ -139,9 +139,9 @@ struct QPolylineSet
 // 'lod' is the level of detail. Default is 1. Curves are split into more lines when 'lod' is higher.
 QTriangleSet qTriangulate(const qreal *polygon, int count, uint hint = QVectorPath::PolygonHint | QVectorPath::OddEvenFill, const QTransform &matrix = QTransform());
 QTriangleSet qTriangulate(const QVectorPath &path, const QTransform &matrix = QTransform(), qreal lod = 1);
-QTriangleSet qTriangulate(const QPainterPath &path, const QTransform &matrix = QTransform(), qreal lod = 1);
+QTriangleSet Q_OPENGL_EXPORT qTriangulate(const QPainterPath &path, const QTransform &matrix = QTransform(), qreal lod = 1);
 QPolylineSet qPolyline(const QVectorPath &path, const QTransform &matrix = QTransform(), qreal lod = 1);
-QPolylineSet qPolyline(const QPainterPath &path, const QTransform &matrix = QTransform(), qreal lod = 1);
+QPolylineSet Q_OPENGL_EXPORT qPolyline(const QPainterPath &path, const QTransform &matrix = QTransform(), qreal lod = 1);
 
 QT_END_NAMESPACE
 
index 057fb55..4cb976f 100644 (file)
@@ -43,6 +43,7 @@
 #include "qplatformdefs.h"
 #include "qgl.h"
 #include <qdebug.h>
+#include <qglfunctions.h>
 
 #if defined(Q_WS_X11)
 #include "private/qt_x11_p.h"
@@ -1663,6 +1664,7 @@ const QGLContext *qt_gl_transfer_context(const QGLContext *ctx)
 QGLContextPrivate::QGLContextPrivate(QGLContext *context)
     : internal_context(false)
     , q_ptr(context)
+    , functions(0)
 {
     group = new QGLContextGroup(context);
     texture_destroyer = new QGLTextureDestroyer;
@@ -1671,6 +1673,8 @@ QGLContextPrivate::QGLContextPrivate(QGLContext *context)
 
 QGLContextPrivate::~QGLContextPrivate()
 {
+    delete functions;
+
     if (!group->m_refs.deref()) {
         Q_ASSERT(group->context() == q_ptr);
         delete group;
@@ -2711,6 +2715,19 @@ int QGLContextPrivate::maxTextureSize()
 }
 
 /*!
+  Returns a QGLFunctions object that is initialized for this context.
+ */
+QGLFunctions *QGLContext::functions() const
+{
+    QGLContextPrivate *d = const_cast<QGLContextPrivate *>(d_func());
+    if (!d->functions) {
+        d->functions = new QGLFunctions(this);
+        d->functions->initializeGLFunctions(this);
+    }
+    return d->functions;
+}
+
+/*!
   Generates and binds a 2D GL texture to the current context, based
   on \a image. The generated texture id is returned and can be used in
   later \c glBindTexture() calls.
@@ -3792,6 +3809,20 @@ QGLWidget::QGLWidget(QWidget *parent, const QGLWidget* shareWidget, Qt::WindowFl
     d->init(new QGLContext(QGLFormat::defaultFormat(), this), shareWidget);
 }
 
+/*!
+  \internal
+ */
+QGLWidget::QGLWidget(QGLWidgetPrivate &dd, const QGLFormat &format, QWidget *parent, const QGLWidget *shareWidget, Qt::WindowFlags f)
+    : QWidget(dd, parent, f | Qt::MSWindowsOwnDC)
+{
+    Q_D(QGLWidget);
+    setAttribute(Qt::WA_PaintOnScreen);
+    setAttribute(Qt::WA_NoSystemBackground);
+    setAutoFillBackground(true); // for compatibility
+    d->init(new QGLContext(format, this), shareWidget);
+
+}
+
 
 /*!
     Constructs an OpenGL widget with parent \a parent.
@@ -5490,6 +5521,13 @@ QGLExtensions::Extensions QGLExtensions::currentContextExtensions()
     if (extensions.match("GL_EXT_bgra"))
         glExtensions |= BGRATextureFormat;
 
+    {
+        GLboolean srgbCapableFramebuffers;
+        glGetBooleanv(FRAMEBUFFER_SRGB_CAPABLE_EXT, &srgbCapableFramebuffers);
+        if (srgbCapableFramebuffers)
+            glExtensions |= SRGBFrameBuffer;
+    }
+
     return glExtensions;
 }
 
index c57995d..dfd1ae1 100644 (file)
@@ -307,6 +307,8 @@ Q_OPENGL_EXPORT bool operator!=(const QGLFormat&, const QGLFormat&);
 Q_OPENGL_EXPORT QDebug operator<<(QDebug, const QGLFormat &);
 #endif
 
+class QGLFunctions;
+
 class Q_OPENGL_EXPORT QGLContext
 {
     Q_DECLARE_PRIVATE(QGLContext)
@@ -332,6 +334,8 @@ public:
 
     virtual void swapBuffers() const;
 
+    QGLFunctions *functions() const;
+
     enum BindOption {
         NoBindOption                            = 0x0000,
         InvertedYBindOption                     = 0x0001,
@@ -466,6 +470,7 @@ private:
     friend class QX11GLPixmapData;
     friend class QX11GLSharedContexts;
     friend class QGLContextResourceBase;
+    friend class QSGDistanceFieldGlyphCache;
 private:
     Q_DISABLE_COPY(QGLContext)
 };
@@ -589,6 +594,11 @@ protected:
     virtual void glDraw();
     int fontDisplayListBase(const QFont & fnt, int listBase = 2000); // ### Qt 5: remove
 
+    QGLWidget(QGLWidgetPrivate &dd,
+              const QGLFormat &format = QGLFormat(),
+              QWidget *parent = 0,
+              const QGLWidget* shareWidget = 0,
+              Qt::WindowFlags f = 0);
 private:
     Q_DISABLE_COPY(QGLWidget)
 
index 50d13c9..46683c7 100644 (file)
@@ -159,7 +159,7 @@ public:
     QGLFormat::OpenGLContextProfile profile;
 };
 
-class QGLWidgetPrivate : public QWidgetPrivate
+class Q_OPENGL_EXPORT QGLWidgetPrivate : public QWidgetPrivate
 {
     Q_DECLARE_PUBLIC(QGLWidget)
 public:
@@ -288,7 +288,8 @@ public:
         PVRTCTextureCompression = 0x00020000,
         FragmentShader          = 0x00040000,
         ElementIndexUint        = 0x00080000,
-        Depth24                 = 0x00100000
+        Depth24                 = 0x00100000,
+        SRGBFrameBuffer         = 0x00200000
     };
     Q_DECLARE_FLAGS(Extensions, Extension)
 
@@ -441,6 +442,8 @@ public:
     QHash<QGLContextResourceBase *, void *> m_resources;
     QGLTextureDestroyer *texture_destroyer;
 
+    QGLFunctions *functions;
+
     bool vertexAttributeArraysEnabledState[QT_GL_VERTEX_ARRAY_TRACKED_COUNT];
 
     static inline QGLContextGroup *contextGroup(const QGLContext *ctx) { return ctx->d_ptr->group; }
@@ -499,7 +502,7 @@ private:
     QGLContext *m_ctx;
 };
 
-class QGLTextureDestroyer : public QObject
+class Q_OPENGL_EXPORT QGLTextureDestroyer : public QObject
 {
     Q_OBJECT
 public:
index 529c7a1..ac80ce8 100644 (file)
@@ -477,6 +477,14 @@ struct QGLExtensionFuncs
 
 // OpenGL constants
 
+#ifndef FRAMEBUFFER_SRGB_CAPABLE_EXT
+#define FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA
+#endif
+
+#ifndef FRAMEBUFFER_SRGB_EXT
+#define FRAMEBUFFER_SRGB_EXT 0x8DB9
+#endif
+
 #ifndef GL_ARRAY_BUFFER
 #define GL_ARRAY_BUFFER                   0x8892
 #endif
index be8219a..8027081 100644 (file)
@@ -1348,7 +1348,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
 
 #ifndef QT_OPENGL_ES_2
 
-static void qglfResolveActiveTexture(GLenum texture)
+static void QGLF_APIENTRY qglfResolveActiveTexture(GLenum texture)
 {
     typedef void (QGLF_APIENTRYP type_glActiveTexture)(GLenum texture);
 
@@ -1368,7 +1368,7 @@ static void qglfResolveActiveTexture(GLenum texture)
         funcs->activeTexture = qglfResolveActiveTexture;
 }
 
-static void qglfResolveAttachShader(GLuint program, GLuint shader)
+static void QGLF_APIENTRY qglfResolveAttachShader(GLuint program, GLuint shader)
 {
     typedef void (QGLF_APIENTRYP type_glAttachShader)(GLuint program, GLuint shader);
 
@@ -1388,7 +1388,7 @@ static void qglfResolveAttachShader(GLuint program, GLuint shader)
         funcs->attachShader = qglfResolveAttachShader;
 }
 
-static void qglfResolveBindAttribLocation(GLuint program, GLuint index, const char* name)
+static void QGLF_APIENTRY qglfResolveBindAttribLocation(GLuint program, GLuint index, const char* name)
 {
     typedef void (QGLF_APIENTRYP type_glBindAttribLocation)(GLuint program, GLuint index, const char* name);
 
@@ -1408,7 +1408,7 @@ static void qglfResolveBindAttribLocation(GLuint program, GLuint index, const ch
         funcs->bindAttribLocation = qglfResolveBindAttribLocation;
 }
 
-static void qglfResolveBindBuffer(GLenum target, GLuint buffer)
+static void QGLF_APIENTRY qglfResolveBindBuffer(GLenum target, GLuint buffer)
 {
     typedef void (QGLF_APIENTRYP type_glBindBuffer)(GLenum target, GLuint buffer);
 
@@ -1438,7 +1438,7 @@ static void qglfResolveBindBuffer(GLenum target, GLuint buffer)
         funcs->bindBuffer = qglfResolveBindBuffer;
 }
 
-static void qglfResolveBindFramebuffer(GLenum target, GLuint framebuffer)
+static void QGLF_APIENTRY qglfResolveBindFramebuffer(GLenum target, GLuint framebuffer)
 {
     typedef void (QGLF_APIENTRYP type_glBindFramebuffer)(GLenum target, GLuint framebuffer);
 
@@ -1468,7 +1468,7 @@ static void qglfResolveBindFramebuffer(GLenum target, GLuint framebuffer)
         funcs->bindFramebuffer = qglfResolveBindFramebuffer;
 }
 
-static void qglfResolveBindRenderbuffer(GLenum target, GLuint renderbuffer)
+static void QGLF_APIENTRY qglfResolveBindRenderbuffer(GLenum target, GLuint renderbuffer)
 {
     typedef void (QGLF_APIENTRYP type_glBindRenderbuffer)(GLenum target, GLuint renderbuffer);
 
@@ -1498,7 +1498,7 @@ static void qglfResolveBindRenderbuffer(GLenum target, GLuint renderbuffer)
         funcs->bindRenderbuffer = qglfResolveBindRenderbuffer;
 }
 
-static void qglfResolveBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+static void QGLF_APIENTRY qglfResolveBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
 {
     typedef void (QGLF_APIENTRYP type_glBlendColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
 
@@ -1528,7 +1528,7 @@ static void qglfResolveBlendColor(GLclampf red, GLclampf green, GLclampf blue, G
         funcs->blendColor = qglfResolveBlendColor;
 }
 
-static void qglfResolveBlendEquation(GLenum mode)
+static void QGLF_APIENTRY qglfResolveBlendEquation(GLenum mode)
 {
     typedef void (QGLF_APIENTRYP type_glBlendEquation)(GLenum mode);
 
@@ -1558,7 +1558,7 @@ static void qglfResolveBlendEquation(GLenum mode)
         funcs->blendEquation = qglfResolveBlendEquation;
 }
 
-static void qglfResolveBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
+static void QGLF_APIENTRY qglfResolveBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
 {
     typedef void (QGLF_APIENTRYP type_glBlendEquationSeparate)(GLenum modeRGB, GLenum modeAlpha);
 
@@ -1588,7 +1588,7 @@ static void qglfResolveBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
         funcs->blendEquationSeparate = qglfResolveBlendEquationSeparate;
 }
 
-static void qglfResolveBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+static void QGLF_APIENTRY qglfResolveBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
 {
     typedef void (QGLF_APIENTRYP type_glBlendFuncSeparate)(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
 
@@ -1618,7 +1618,7 @@ static void qglfResolveBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum sr
         funcs->blendFuncSeparate = qglfResolveBlendFuncSeparate;
 }
 
-static void qglfResolveBufferData(GLenum target, qgl_GLsizeiptr size, const void* data, GLenum usage)
+static void QGLF_APIENTRY qglfResolveBufferData(GLenum target, qgl_GLsizeiptr size, const void* data, GLenum usage)
 {
     typedef void (QGLF_APIENTRYP type_glBufferData)(GLenum target, qgl_GLsizeiptr size, const void* data, GLenum usage);
 
@@ -1648,7 +1648,7 @@ static void qglfResolveBufferData(GLenum target, qgl_GLsizeiptr size, const void
         funcs->bufferData = qglfResolveBufferData;
 }
 
-static void qglfResolveBufferSubData(GLenum target, qgl_GLintptr offset, qgl_GLsizeiptr size, const void* data)
+static void QGLF_APIENTRY qglfResolveBufferSubData(GLenum target, qgl_GLintptr offset, qgl_GLsizeiptr size, const void* data)
 {
     typedef void (QGLF_APIENTRYP type_glBufferSubData)(GLenum target, qgl_GLintptr offset, qgl_GLsizeiptr size, const void* data);
 
@@ -1678,7 +1678,7 @@ static void qglfResolveBufferSubData(GLenum target, qgl_GLintptr offset, qgl_GLs
         funcs->bufferSubData = qglfResolveBufferSubData;
 }
 
-static GLenum qglfResolveCheckFramebufferStatus(GLenum target)
+static GLenum QGLF_APIENTRY qglfResolveCheckFramebufferStatus(GLenum target)
 {
     typedef GLenum (QGLF_APIENTRYP type_glCheckFramebufferStatus)(GLenum target);
 
@@ -1708,7 +1708,7 @@ static GLenum qglfResolveCheckFramebufferStatus(GLenum target)
     return GLenum(0);
 }
 
-static void qglfResolveCompileShader(GLuint shader)
+static void QGLF_APIENTRY qglfResolveCompileShader(GLuint shader)
 {
     typedef void (QGLF_APIENTRYP type_glCompileShader)(GLuint shader);
 
@@ -1728,7 +1728,7 @@ static void qglfResolveCompileShader(GLuint shader)
         funcs->compileShader = qglfResolveCompileShader;
 }
 
-static void qglfResolveCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data)
+static void QGLF_APIENTRY qglfResolveCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data)
 {
     typedef void (QGLF_APIENTRYP type_glCompressedTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data);
 
@@ -1758,7 +1758,7 @@ static void qglfResolveCompressedTexImage2D(GLenum target, GLint level, GLenum i
         funcs->compressedTexImage2D = qglfResolveCompressedTexImage2D;
 }
 
-static void qglfResolveCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data)
+static void QGLF_APIENTRY qglfResolveCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data)
 {
     typedef void (QGLF_APIENTRYP type_glCompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data);
 
@@ -1788,7 +1788,7 @@ static void qglfResolveCompressedTexSubImage2D(GLenum target, GLint level, GLint
         funcs->compressedTexSubImage2D = qglfResolveCompressedTexSubImage2D;
 }
 
-static GLuint qglfResolveCreateProgram()
+static GLuint QGLF_APIENTRY qglfResolveCreateProgram()
 {
     typedef GLuint (QGLF_APIENTRYP type_glCreateProgram)();
 
@@ -1808,7 +1808,7 @@ static GLuint qglfResolveCreateProgram()
     return GLuint(0);
 }
 
-static GLuint qglfResolveCreateShader(GLenum type)
+static GLuint QGLF_APIENTRY qglfResolveCreateShader(GLenum type)
 {
     typedef GLuint (QGLF_APIENTRYP type_glCreateShader)(GLenum type);
 
@@ -1828,7 +1828,7 @@ static GLuint qglfResolveCreateShader(GLenum type)
     return GLuint(0);
 }
 
-static void qglfResolveDeleteBuffers(GLsizei n, const GLuint* buffers)
+static void QGLF_APIENTRY qglfResolveDeleteBuffers(GLsizei n, const GLuint* buffers)
 {
     typedef void (QGLF_APIENTRYP type_glDeleteBuffers)(GLsizei n, const GLuint* buffers);
 
@@ -1858,7 +1858,7 @@ static void qglfResolveDeleteBuffers(GLsizei n, const GLuint* buffers)
         funcs->deleteBuffers = qglfResolveDeleteBuffers;
 }
 
-static void qglfResolveDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
+static void QGLF_APIENTRY qglfResolveDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
 {
     typedef void (QGLF_APIENTRYP type_glDeleteFramebuffers)(GLsizei n, const GLuint* framebuffers);
 
@@ -1888,7 +1888,7 @@ static void qglfResolveDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
         funcs->deleteFramebuffers = qglfResolveDeleteFramebuffers;
 }
 
-static void qglfResolveDeleteProgram(GLuint program)
+static void QGLF_APIENTRY qglfResolveDeleteProgram(GLuint program)
 {
     typedef void (QGLF_APIENTRYP type_glDeleteProgram)(GLuint program);
 
@@ -1908,7 +1908,7 @@ static void qglfResolveDeleteProgram(GLuint program)
         funcs->deleteProgram = qglfResolveDeleteProgram;
 }
 
-static void qglfResolveDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
+static void QGLF_APIENTRY qglfResolveDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
 {
     typedef void (QGLF_APIENTRYP type_glDeleteRenderbuffers)(GLsizei n, const GLuint* renderbuffers);
 
@@ -1938,7 +1938,7 @@ static void qglfResolveDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffer
         funcs->deleteRenderbuffers = qglfResolveDeleteRenderbuffers;
 }
 
-static void qglfResolveDeleteShader(GLuint shader)
+static void QGLF_APIENTRY qglfResolveDeleteShader(GLuint shader)
 {
     typedef void (QGLF_APIENTRYP type_glDeleteShader)(GLuint shader);
 
@@ -1958,7 +1958,7 @@ static void qglfResolveDeleteShader(GLuint shader)
         funcs->deleteShader = qglfResolveDeleteShader;
 }
 
-static void qglfResolveDetachShader(GLuint program, GLuint shader)
+static void QGLF_APIENTRY qglfResolveDetachShader(GLuint program, GLuint shader)
 {
     typedef void (QGLF_APIENTRYP type_glDetachShader)(GLuint program, GLuint shader);
 
@@ -1978,7 +1978,7 @@ static void qglfResolveDetachShader(GLuint program, GLuint shader)
         funcs->detachShader = qglfResolveDetachShader;
 }
 
-static void qglfResolveDisableVertexAttribArray(GLuint index)
+static void QGLF_APIENTRY qglfResolveDisableVertexAttribArray(GLuint index)
 {
     typedef void (QGLF_APIENTRYP type_glDisableVertexAttribArray)(GLuint index);
 
@@ -1998,7 +1998,7 @@ static void qglfResolveDisableVertexAttribArray(GLuint index)
         funcs->disableVertexAttribArray = qglfResolveDisableVertexAttribArray;
 }
 
-static void qglfResolveEnableVertexAttribArray(GLuint index)
+static void QGLF_APIENTRY qglfResolveEnableVertexAttribArray(GLuint index)
 {
     typedef void (QGLF_APIENTRYP type_glEnableVertexAttribArray)(GLuint index);
 
@@ -2018,7 +2018,7 @@ static void qglfResolveEnableVertexAttribArray(GLuint index)
         funcs->enableVertexAttribArray = qglfResolveEnableVertexAttribArray;
 }
 
-static void qglfResolveFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+static void QGLF_APIENTRY qglfResolveFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
 {
     typedef void (QGLF_APIENTRYP type_glFramebufferRenderbuffer)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
 
@@ -2048,7 +2048,7 @@ static void qglfResolveFramebufferRenderbuffer(GLenum target, GLenum attachment,
         funcs->framebufferRenderbuffer = qglfResolveFramebufferRenderbuffer;
 }
 
-static void qglfResolveFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+static void QGLF_APIENTRY qglfResolveFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
 {
     typedef void (QGLF_APIENTRYP type_glFramebufferTexture2D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
 
@@ -2078,7 +2078,7 @@ static void qglfResolveFramebufferTexture2D(GLenum target, GLenum attachment, GL
         funcs->framebufferTexture2D = qglfResolveFramebufferTexture2D;
 }
 
-static void qglfResolveGenBuffers(GLsizei n, GLuint* buffers)
+static void QGLF_APIENTRY qglfResolveGenBuffers(GLsizei n, GLuint* buffers)
 {
     typedef void (QGLF_APIENTRYP type_glGenBuffers)(GLsizei n, GLuint* buffers);
 
@@ -2108,7 +2108,7 @@ static void qglfResolveGenBuffers(GLsizei n, GLuint* buffers)
         funcs->genBuffers = qglfResolveGenBuffers;
 }
 
-static void qglfResolveGenerateMipmap(GLenum target)
+static void QGLF_APIENTRY qglfResolveGenerateMipmap(GLenum target)
 {
     typedef void (QGLF_APIENTRYP type_glGenerateMipmap)(GLenum target);
 
@@ -2138,7 +2138,7 @@ static void qglfResolveGenerateMipmap(GLenum target)
         funcs->generateMipmap = qglfResolveGenerateMipmap;
 }
 
-static void qglfResolveGenFramebuffers(GLsizei n, GLuint* framebuffers)
+static void QGLF_APIENTRY qglfResolveGenFramebuffers(GLsizei n, GLuint* framebuffers)
 {
     typedef void (QGLF_APIENTRYP type_glGenFramebuffers)(GLsizei n, GLuint* framebuffers);
 
@@ -2168,7 +2168,7 @@ static void qglfResolveGenFramebuffers(GLsizei n, GLuint* framebuffers)
         funcs->genFramebuffers = qglfResolveGenFramebuffers;
 }
 
-static void qglfResolveGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
+static void QGLF_APIENTRY qglfResolveGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
 {
     typedef void (QGLF_APIENTRYP type_glGenRenderbuffers)(GLsizei n, GLuint* renderbuffers);
 
@@ -2198,7 +2198,7 @@ static void qglfResolveGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
         funcs->genRenderbuffers = qglfResolveGenRenderbuffers;
 }
 
-static void qglfResolveGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name)
+static void QGLF_APIENTRY qglfResolveGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name)
 {
     typedef void (QGLF_APIENTRYP type_glGetActiveAttrib)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name);
 
@@ -2218,7 +2218,7 @@ static void qglfResolveGetActiveAttrib(GLuint program, GLuint index, GLsizei buf
         funcs->getActiveAttrib = qglfResolveGetActiveAttrib;
 }
 
-static void qglfResolveGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name)
+static void QGLF_APIENTRY qglfResolveGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name)
 {
     typedef void (QGLF_APIENTRYP type_glGetActiveUniform)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name);
 
@@ -2238,7 +2238,7 @@ static void qglfResolveGetActiveUniform(GLuint program, GLuint index, GLsizei bu
         funcs->getActiveUniform = qglfResolveGetActiveUniform;
 }
 
-static void qglfResolveGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
+static void QGLF_APIENTRY qglfResolveGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
 {
     typedef void (QGLF_APIENTRYP type_glGetAttachedShaders)(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders);
 
@@ -2258,7 +2258,7 @@ static void qglfResolveGetAttachedShaders(GLuint program, GLsizei maxcount, GLsi
         funcs->getAttachedShaders = qglfResolveGetAttachedShaders;
 }
 
-static int qglfResolveGetAttribLocation(GLuint program, const char* name)
+static int QGLF_APIENTRY qglfResolveGetAttribLocation(GLuint program, const char* name)
 {
     typedef int (QGLF_APIENTRYP type_glGetAttribLocation)(GLuint program, const char* name);
 
@@ -2278,7 +2278,7 @@ static int qglfResolveGetAttribLocation(GLuint program, const char* name)
     return int(0);
 }
 
-static void qglfResolveGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
+static void QGLF_APIENTRY qglfResolveGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
 {
     typedef void (QGLF_APIENTRYP type_glGetBufferParameteriv)(GLenum target, GLenum pname, GLint* params);
 
@@ -2308,7 +2308,7 @@ static void qglfResolveGetBufferParameteriv(GLenum target, GLenum pname, GLint*
         funcs->getBufferParameteriv = qglfResolveGetBufferParameteriv;
 }
 
-static void qglfResolveGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
+static void QGLF_APIENTRY qglfResolveGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
 {
     typedef void (QGLF_APIENTRYP type_glGetFramebufferAttachmentParameteriv)(GLenum target, GLenum attachment, GLenum pname, GLint* params);
 
@@ -2338,7 +2338,7 @@ static void qglfResolveGetFramebufferAttachmentParameteriv(GLenum target, GLenum
         funcs->getFramebufferAttachmentParameteriv = qglfResolveGetFramebufferAttachmentParameteriv;
 }
 
-static void qglfResolveGetProgramiv(GLuint program, GLenum pname, GLint* params)
+static void QGLF_APIENTRY qglfResolveGetProgramiv(GLuint program, GLenum pname, GLint* params)
 {
     typedef void (QGLF_APIENTRYP type_glGetProgramiv)(GLuint program, GLenum pname, GLint* params);
 
@@ -2358,7 +2358,7 @@ static void qglfResolveGetProgramiv(GLuint program, GLenum pname, GLint* params)
         funcs->getProgramiv = qglfResolveGetProgramiv;
 }
 
-static void qglfResolveGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, char* infolog)
+static void QGLF_APIENTRY qglfResolveGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, char* infolog)
 {
     typedef void (QGLF_APIENTRYP type_glGetProgramInfoLog)(GLuint program, GLsizei bufsize, GLsizei* length, char* infolog);
 
@@ -2378,7 +2378,7 @@ static void qglfResolveGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsize
         funcs->getProgramInfoLog = qglfResolveGetProgramInfoLog;
 }
 
-static void qglfResolveGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
+static void QGLF_APIENTRY qglfResolveGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
 {
     typedef void (QGLF_APIENTRYP type_glGetRenderbufferParameteriv)(GLenum target, GLenum pname, GLint* params);
 
@@ -2408,7 +2408,7 @@ static void qglfResolveGetRenderbufferParameteriv(GLenum target, GLenum pname, G
         funcs->getRenderbufferParameteriv = qglfResolveGetRenderbufferParameteriv;
 }
 
-static void qglfResolveGetShaderiv(GLuint shader, GLenum pname, GLint* params)
+static void QGLF_APIENTRY qglfResolveGetShaderiv(GLuint shader, GLenum pname, GLint* params)
 {
     typedef void (QGLF_APIENTRYP type_glGetShaderiv)(GLuint shader, GLenum pname, GLint* params);
 
@@ -2428,7 +2428,7 @@ static void qglfResolveGetShaderiv(GLuint shader, GLenum pname, GLint* params)
         funcs->getShaderiv = qglfResolveGetShaderiv;
 }
 
-static void qglfResolveGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog)
+static void QGLF_APIENTRY qglfResolveGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog)
 {
     typedef void (QGLF_APIENTRYP type_glGetShaderInfoLog)(GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog);
 
@@ -2448,14 +2448,14 @@ static void qglfResolveGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei*
         funcs->getShaderInfoLog = qglfResolveGetShaderInfoLog;
 }
 
-static void qglfSpecialGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
+static void QGLF_APIENTRY qglfSpecialGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
 {
     Q_UNUSED(shadertype);
     Q_UNUSED(precisiontype);
     range[0] = range[1] = precision[0] = 0;
 }
 
-static void qglfResolveGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
+static void QGLF_APIENTRY qglfResolveGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
 {
     typedef void (QGLF_APIENTRYP type_glGetShaderPrecisionFormat)(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
 
@@ -2485,7 +2485,7 @@ static void qglfResolveGetShaderPrecisionFormat(GLenum shadertype, GLenum precis
     funcs->getShaderPrecisionFormat(shadertype, precisiontype, range, precision);
 }
 
-static void qglfResolveGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, char* source)
+static void QGLF_APIENTRY qglfResolveGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, char* source)
 {
     typedef void (QGLF_APIENTRYP type_glGetShaderSource)(GLuint shader, GLsizei bufsize, GLsizei* length, char* source);
 
@@ -2505,7 +2505,7 @@ static void qglfResolveGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei*
         funcs->getShaderSource = qglfResolveGetShaderSource;
 }
 
-static void qglfResolveGetUniformfv(GLuint program, GLint location, GLfloat* params)
+static void QGLF_APIENTRY qglfResolveGetUniformfv(GLuint program, GLint location, GLfloat* params)
 {
     typedef void (QGLF_APIENTRYP type_glGetUniformfv)(GLuint program, GLint location, GLfloat* params);
 
@@ -2525,7 +2525,7 @@ static void qglfResolveGetUniformfv(GLuint program, GLint location, GLfloat* par
         funcs->getUniformfv = qglfResolveGetUniformfv;
 }
 
-static void qglfResolveGetUniformiv(GLuint program, GLint location, GLint* params)
+static void QGLF_APIENTRY qglfResolveGetUniformiv(GLuint program, GLint location, GLint* params)
 {
     typedef void (QGLF_APIENTRYP type_glGetUniformiv)(GLuint program, GLint location, GLint* params);
 
@@ -2545,7 +2545,7 @@ static void qglfResolveGetUniformiv(GLuint program, GLint location, GLint* param
         funcs->getUniformiv = qglfResolveGetUniformiv;
 }
 
-static int qglfResolveGetUniformLocation(GLuint program, const char* name)
+static int QGLF_APIENTRY qglfResolveGetUniformLocation(GLuint program, const char* name)
 {
     typedef int (QGLF_APIENTRYP type_glGetUniformLocation)(GLuint program, const char* name);
 
@@ -2565,7 +2565,7 @@ static int qglfResolveGetUniformLocation(GLuint program, const char* name)
     return int(0);
 }
 
-static void qglfResolveGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
+static void QGLF_APIENTRY qglfResolveGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
 {
     typedef void (QGLF_APIENTRYP type_glGetVertexAttribfv)(GLuint index, GLenum pname, GLfloat* params);
 
@@ -2585,7 +2585,7 @@ static void qglfResolveGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* pa
         funcs->getVertexAttribfv = qglfResolveGetVertexAttribfv;
 }
 
-static void qglfResolveGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
+static void QGLF_APIENTRY qglfResolveGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
 {
     typedef void (QGLF_APIENTRYP type_glGetVertexAttribiv)(GLuint index, GLenum pname, GLint* params);
 
@@ -2605,7 +2605,7 @@ static void qglfResolveGetVertexAttribiv(GLuint index, GLenum pname, GLint* para
         funcs->getVertexAttribiv = qglfResolveGetVertexAttribiv;
 }
 
-static void qglfResolveGetVertexAttribPointerv(GLuint index, GLenum pname, void** pointer)
+static void QGLF_APIENTRY qglfResolveGetVertexAttribPointerv(GLuint index, GLenum pname, void** pointer)
 {
     typedef void (QGLF_APIENTRYP type_glGetVertexAttribPointerv)(GLuint index, GLenum pname, void** pointer);
 
@@ -2625,7 +2625,7 @@ static void qglfResolveGetVertexAttribPointerv(GLuint index, GLenum pname, void*
         funcs->getVertexAttribPointerv = qglfResolveGetVertexAttribPointerv;
 }
 
-static GLboolean qglfResolveIsBuffer(GLuint buffer)
+static GLboolean QGLF_APIENTRY qglfResolveIsBuffer(GLuint buffer)
 {
     typedef GLboolean (QGLF_APIENTRYP type_glIsBuffer)(GLuint buffer);
 
@@ -2655,7 +2655,7 @@ static GLboolean qglfResolveIsBuffer(GLuint buffer)
     return GLboolean(0);
 }
 
-static GLboolean qglfResolveIsFramebuffer(GLuint framebuffer)
+static GLboolean QGLF_APIENTRY qglfResolveIsFramebuffer(GLuint framebuffer)
 {
     typedef GLboolean (QGLF_APIENTRYP type_glIsFramebuffer)(GLuint framebuffer);
 
@@ -2685,12 +2685,12 @@ static GLboolean qglfResolveIsFramebuffer(GLuint framebuffer)
     return GLboolean(0);
 }
 
-static GLboolean qglfSpecialIsProgram(GLuint program)
+static GLboolean QGLF_APIENTRY qglfSpecialIsProgram(GLuint program)
 {
     return program != 0;
 }
 
-static GLboolean qglfResolveIsProgram(GLuint program)
+static GLboolean QGLF_APIENTRY qglfResolveIsProgram(GLuint program)
 {
     typedef GLboolean (QGLF_APIENTRYP type_glIsProgram)(GLuint program);
 
@@ -2710,7 +2710,7 @@ static GLboolean qglfResolveIsProgram(GLuint program)
     return funcs->isProgram(program);
 }
 
-static GLboolean qglfResolveIsRenderbuffer(GLuint renderbuffer)
+static GLboolean QGLF_APIENTRY qglfResolveIsRenderbuffer(GLuint renderbuffer)
 {
     typedef GLboolean (QGLF_APIENTRYP type_glIsRenderbuffer)(GLuint renderbuffer);
 
@@ -2740,12 +2740,12 @@ static GLboolean qglfResolveIsRenderbuffer(GLuint renderbuffer)
     return GLboolean(0);
 }
 
-static GLboolean qglfSpecialIsShader(GLuint shader)
+static GLboolean QGLF_APIENTRY qglfSpecialIsShader(GLuint shader)
 {
     return shader != 0;
 }
 
-static GLboolean qglfResolveIsShader(GLuint shader)
+static GLboolean QGLF_APIENTRY qglfResolveIsShader(GLuint shader)
 {
     typedef GLboolean (QGLF_APIENTRYP type_glIsShader)(GLuint shader);
 
@@ -2765,7 +2765,7 @@ static GLboolean qglfResolveIsShader(GLuint shader)
     return funcs->isShader(shader);
 }
 
-static void qglfResolveLinkProgram(GLuint program)
+static void QGLF_APIENTRY qglfResolveLinkProgram(GLuint program)
 {
     typedef void (QGLF_APIENTRYP type_glLinkProgram)(GLuint program);
 
@@ -2785,11 +2785,11 @@ static void qglfResolveLinkProgram(GLuint program)
         funcs->linkProgram = qglfResolveLinkProgram;
 }
 
-static void qglfSpecialReleaseShaderCompiler()
+static void QGLF_APIENTRY qglfSpecialReleaseShaderCompiler()
 {
 }
 
-static void qglfResolveReleaseShaderCompiler()
+static void QGLF_APIENTRY qglfResolveReleaseShaderCompiler()
 {
     typedef void (QGLF_APIENTRYP type_glReleaseShaderCompiler)();
 
@@ -2809,7 +2809,7 @@ static void qglfResolveReleaseShaderCompiler()
     funcs->releaseShaderCompiler();
 }
 
-static void qglfResolveRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+static void QGLF_APIENTRY qglfResolveRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
 {
     typedef void (QGLF_APIENTRYP type_glRenderbufferStorage)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
 
@@ -2839,7 +2839,7 @@ static void qglfResolveRenderbufferStorage(GLenum target, GLenum internalformat,
         funcs->renderbufferStorage = qglfResolveRenderbufferStorage;
 }
 
-static void qglfResolveSampleCoverage(GLclampf value, GLboolean invert)
+static void QGLF_APIENTRY qglfResolveSampleCoverage(GLclampf value, GLboolean invert)
 {
     typedef void (QGLF_APIENTRYP type_glSampleCoverage)(GLclampf value, GLboolean invert);
 
@@ -2869,7 +2869,7 @@ static void qglfResolveSampleCoverage(GLclampf value, GLboolean invert)
         funcs->sampleCoverage = qglfResolveSampleCoverage;
 }
 
-static void qglfResolveShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLint length)
+static void QGLF_APIENTRY qglfResolveShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLint length)
 {
     typedef void (QGLF_APIENTRYP type_glShaderBinary)(GLint n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLint length);
 
@@ -2889,7 +2889,7 @@ static void qglfResolveShaderBinary(GLint n, const GLuint* shaders, GLenum binar
         funcs->shaderBinary = qglfResolveShaderBinary;
 }
 
-static void qglfResolveShaderSource(GLuint shader, GLsizei count, const char** string, const GLint* length)
+static void QGLF_APIENTRY qglfResolveShaderSource(GLuint shader, GLsizei count, const char** string, const GLint* length)
 {
     typedef void (QGLF_APIENTRYP type_glShaderSource)(GLuint shader, GLsizei count, const char** string, const GLint* length);
 
@@ -2909,7 +2909,7 @@ static void qglfResolveShaderSource(GLuint shader, GLsizei count, const char** s
         funcs->shaderSource = qglfResolveShaderSource;
 }
 
-static void qglfResolveStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
+static void QGLF_APIENTRY qglfResolveStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
 {
     typedef void (QGLF_APIENTRYP type_glStencilFuncSeparate)(GLenum face, GLenum func, GLint ref, GLuint mask);
 
@@ -2939,7 +2939,7 @@ static void qglfResolveStencilFuncSeparate(GLenum face, GLenum func, GLint ref,
         funcs->stencilFuncSeparate = qglfResolveStencilFuncSeparate;
 }
 
-static void qglfResolveStencilMaskSeparate(GLenum face, GLuint mask)
+static void QGLF_APIENTRY qglfResolveStencilMaskSeparate(GLenum face, GLuint mask)
 {
     typedef void (QGLF_APIENTRYP type_glStencilMaskSeparate)(GLenum face, GLuint mask);
 
@@ -2969,7 +2969,7 @@ static void qglfResolveStencilMaskSeparate(GLenum face, GLuint mask)
         funcs->stencilMaskSeparate = qglfResolveStencilMaskSeparate;
 }
 
-static void qglfResolveStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
+static void QGLF_APIENTRY qglfResolveStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
 {
     typedef void (QGLF_APIENTRYP type_glStencilOpSeparate)(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
 
@@ -2999,7 +2999,7 @@ static void qglfResolveStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail,
         funcs->stencilOpSeparate = qglfResolveStencilOpSeparate;
 }
 
-static void qglfResolveUniform1f(GLint location, GLfloat x)
+static void QGLF_APIENTRY qglfResolveUniform1f(GLint location, GLfloat x)
 {
     typedef void (QGLF_APIENTRYP type_glUniform1f)(GLint location, GLfloat x);
 
@@ -3019,7 +3019,7 @@ static void qglfResolveUniform1f(GLint location, GLfloat x)
         funcs->uniform1f = qglfResolveUniform1f;
 }
 
-static void qglfResolveUniform1fv(GLint location, GLsizei count, const GLfloat* v)
+static void QGLF_APIENTRY qglfResolveUniform1fv(GLint location, GLsizei count, const GLfloat* v)
 {
     typedef void (QGLF_APIENTRYP type_glUniform1fv)(GLint location, GLsizei count, const GLfloat* v);
 
@@ -3039,7 +3039,7 @@ static void qglfResolveUniform1fv(GLint location, GLsizei count, const GLfloat*
         funcs->uniform1fv = qglfResolveUniform1fv;
 }
 
-static void qglfResolveUniform1i(GLint location, GLint x)
+static void QGLF_APIENTRY qglfResolveUniform1i(GLint location, GLint x)
 {
     typedef void (QGLF_APIENTRYP type_glUniform1i)(GLint location, GLint x);
 
@@ -3059,7 +3059,7 @@ static void qglfResolveUniform1i(GLint location, GLint x)
         funcs->uniform1i = qglfResolveUniform1i;
 }
 
-static void qglfResolveUniform1iv(GLint location, GLsizei count, const GLint* v)
+static void QGLF_APIENTRY qglfResolveUniform1iv(GLint location, GLsizei count, const GLint* v)
 {
     typedef void (QGLF_APIENTRYP type_glUniform1iv)(GLint location, GLsizei count, const GLint* v);
 
@@ -3079,7 +3079,7 @@ static void qglfResolveUniform1iv(GLint location, GLsizei count, const GLint* v)
         funcs->uniform1iv = qglfResolveUniform1iv;
 }
 
-static void qglfResolveUniform2f(GLint location, GLfloat x, GLfloat y)
+static void QGLF_APIENTRY qglfResolveUniform2f(GLint location, GLfloat x, GLfloat y)
 {
     typedef void (QGLF_APIENTRYP type_glUniform2f)(GLint location, GLfloat x, GLfloat y);
 
@@ -3099,7 +3099,7 @@ static void qglfResolveUniform2f(GLint location, GLfloat x, GLfloat y)
         funcs->uniform2f = qglfResolveUniform2f;
 }
 
-static void qglfResolveUniform2fv(GLint location, GLsizei count, const GLfloat* v)
+static void QGLF_APIENTRY qglfResolveUniform2fv(GLint location, GLsizei count, const GLfloat* v)
 {
     typedef void (QGLF_APIENTRYP type_glUniform2fv)(GLint location, GLsizei count, const GLfloat* v);
 
@@ -3119,7 +3119,7 @@ static void qglfResolveUniform2fv(GLint location, GLsizei count, const GLfloat*
         funcs->uniform2fv = qglfResolveUniform2fv;
 }
 
-static void qglfResolveUniform2i(GLint location, GLint x, GLint y)
+static void QGLF_APIENTRY qglfResolveUniform2i(GLint location, GLint x, GLint y)
 {
     typedef void (QGLF_APIENTRYP type_glUniform2i)(GLint location, GLint x, GLint y);
 
@@ -3139,7 +3139,7 @@ static void qglfResolveUniform2i(GLint location, GLint x, GLint y)
         funcs->uniform2i = qglfResolveUniform2i;
 }
 
-static void qglfResolveUniform2iv(GLint location, GLsizei count, const GLint* v)
+static void QGLF_APIENTRY qglfResolveUniform2iv(GLint location, GLsizei count, const GLint* v)
 {
     typedef void (QGLF_APIENTRYP type_glUniform2iv)(GLint location, GLsizei count, const GLint* v);
 
@@ -3159,7 +3159,7 @@ static void qglfResolveUniform2iv(GLint location, GLsizei count, const GLint* v)
         funcs->uniform2iv = qglfResolveUniform2iv;
 }
 
-static void qglfResolveUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
+static void QGLF_APIENTRY qglfResolveUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
 {
     typedef void (QGLF_APIENTRYP type_glUniform3f)(GLint location, GLfloat x, GLfloat y, GLfloat z);
 
@@ -3179,7 +3179,7 @@ static void qglfResolveUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z
         funcs->uniform3f = qglfResolveUniform3f;
 }
 
-static void qglfResolveUniform3fv(GLint location, GLsizei count, const GLfloat* v)
+static void QGLF_APIENTRY qglfResolveUniform3fv(GLint location, GLsizei count, const GLfloat* v)
 {
     typedef void (QGLF_APIENTRYP type_glUniform3fv)(GLint location, GLsizei count, const GLfloat* v);
 
@@ -3199,7 +3199,7 @@ static void qglfResolveUniform3fv(GLint location, GLsizei count, const GLfloat*
         funcs->uniform3fv = qglfResolveUniform3fv;
 }
 
-static void qglfResolveUniform3i(GLint location, GLint x, GLint y, GLint z)
+static void QGLF_APIENTRY qglfResolveUniform3i(GLint location, GLint x, GLint y, GLint z)
 {
     typedef void (QGLF_APIENTRYP type_glUniform3i)(GLint location, GLint x, GLint y, GLint z);
 
@@ -3219,7 +3219,7 @@ static void qglfResolveUniform3i(GLint location, GLint x, GLint y, GLint z)
         funcs->uniform3i = qglfResolveUniform3i;
 }
 
-static void qglfResolveUniform3iv(GLint location, GLsizei count, const GLint* v)
+static void QGLF_APIENTRY qglfResolveUniform3iv(GLint location, GLsizei count, const GLint* v)
 {
     typedef void (QGLF_APIENTRYP type_glUniform3iv)(GLint location, GLsizei count, const GLint* v);
 
@@ -3239,7 +3239,7 @@ static void qglfResolveUniform3iv(GLint location, GLsizei count, const GLint* v)
         funcs->uniform3iv = qglfResolveUniform3iv;
 }
 
-static void qglfResolveUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+static void QGLF_APIENTRY qglfResolveUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
 {
     typedef void (QGLF_APIENTRYP type_glUniform4f)(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
 
@@ -3259,7 +3259,7 @@ static void qglfResolveUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z
         funcs->uniform4f = qglfResolveUniform4f;
 }
 
-static void qglfResolveUniform4fv(GLint location, GLsizei count, const GLfloat* v)
+static void QGLF_APIENTRY qglfResolveUniform4fv(GLint location, GLsizei count, const GLfloat* v)
 {
     typedef void (QGLF_APIENTRYP type_glUniform4fv)(GLint location, GLsizei count, const GLfloat* v);
 
@@ -3279,7 +3279,7 @@ static void qglfResolveUniform4fv(GLint location, GLsizei count, const GLfloat*
         funcs->uniform4fv = qglfResolveUniform4fv;
 }
 
-static void qglfResolveUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
+static void QGLF_APIENTRY qglfResolveUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
 {
     typedef void (QGLF_APIENTRYP type_glUniform4i)(GLint location, GLint x, GLint y, GLint z, GLint w);
 
@@ -3299,7 +3299,7 @@ static void qglfResolveUniform4i(GLint location, GLint x, GLint y, GLint z, GLin
         funcs->uniform4i = qglfResolveUniform4i;
 }
 
-static void qglfResolveUniform4iv(GLint location, GLsizei count, const GLint* v)
+static void QGLF_APIENTRY qglfResolveUniform4iv(GLint location, GLsizei count, const GLint* v)
 {
     typedef void (QGLF_APIENTRYP type_glUniform4iv)(GLint location, GLsizei count, const GLint* v);
 
@@ -3319,7 +3319,7 @@ static void qglfResolveUniform4iv(GLint location, GLsizei count, const GLint* v)
         funcs->uniform4iv = qglfResolveUniform4iv;
 }
 
-static void qglfResolveUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+static void QGLF_APIENTRY qglfResolveUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
 {
     typedef void (QGLF_APIENTRYP type_glUniformMatrix2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
 
@@ -3339,7 +3339,7 @@ static void qglfResolveUniformMatrix2fv(GLint location, GLsizei count, GLboolean
         funcs->uniformMatrix2fv = qglfResolveUniformMatrix2fv;
 }
 
-static void qglfResolveUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+static void QGLF_APIENTRY qglfResolveUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
 {
     typedef void (QGLF_APIENTRYP type_glUniformMatrix3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
 
@@ -3359,7 +3359,7 @@ static void qglfResolveUniformMatrix3fv(GLint location, GLsizei count, GLboolean
         funcs->uniformMatrix3fv = qglfResolveUniformMatrix3fv;
 }
 
-static void qglfResolveUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+static void QGLF_APIENTRY qglfResolveUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
 {
     typedef void (QGLF_APIENTRYP type_glUniformMatrix4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
 
@@ -3379,7 +3379,7 @@ static void qglfResolveUniformMatrix4fv(GLint location, GLsizei count, GLboolean
         funcs->uniformMatrix4fv = qglfResolveUniformMatrix4fv;
 }
 
-static void qglfResolveUseProgram(GLuint program)
+static void QGLF_APIENTRY qglfResolveUseProgram(GLuint program)
 {
     typedef void (QGLF_APIENTRYP type_glUseProgram)(GLuint program);
 
@@ -3399,7 +3399,7 @@ static void qglfResolveUseProgram(GLuint program)
         funcs->useProgram = qglfResolveUseProgram;
 }
 
-static void qglfResolveValidateProgram(GLuint program)
+static void QGLF_APIENTRY qglfResolveValidateProgram(GLuint program)
 {
     typedef void (QGLF_APIENTRYP type_glValidateProgram)(GLuint program);
 
@@ -3419,7 +3419,7 @@ static void qglfResolveValidateProgram(GLuint program)
         funcs->validateProgram = qglfResolveValidateProgram;
 }
 
-static void qglfResolveVertexAttrib1f(GLuint indx, GLfloat x)
+static void QGLF_APIENTRY qglfResolveVertexAttrib1f(GLuint indx, GLfloat x)
 {
     typedef void (QGLF_APIENTRYP type_glVertexAttrib1f)(GLuint indx, GLfloat x);
 
@@ -3439,7 +3439,7 @@ static void qglfResolveVertexAttrib1f(GLuint indx, GLfloat x)
         funcs->vertexAttrib1f = qglfResolveVertexAttrib1f;
 }
 
-static void qglfResolveVertexAttrib1fv(GLuint indx, const GLfloat* values)
+static void QGLF_APIENTRY qglfResolveVertexAttrib1fv(GLuint indx, const GLfloat* values)
 {
     typedef void (QGLF_APIENTRYP type_glVertexAttrib1fv)(GLuint indx, const GLfloat* values);
 
@@ -3459,7 +3459,7 @@ static void qglfResolveVertexAttrib1fv(GLuint indx, const GLfloat* values)
         funcs->vertexAttrib1fv = qglfResolveVertexAttrib1fv;
 }
 
-static void qglfResolveVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y)
+static void QGLF_APIENTRY qglfResolveVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y)
 {
     typedef void (QGLF_APIENTRYP type_glVertexAttrib2f)(GLuint indx, GLfloat x, GLfloat y);
 
@@ -3479,7 +3479,7 @@ static void qglfResolveVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y)
         funcs->vertexAttrib2f = qglfResolveVertexAttrib2f;
 }
 
-static void qglfResolveVertexAttrib2fv(GLuint indx, const GLfloat* values)
+static void QGLF_APIENTRY qglfResolveVertexAttrib2fv(GLuint indx, const GLfloat* values)
 {
     typedef void (QGLF_APIENTRYP type_glVertexAttrib2fv)(GLuint indx, const GLfloat* values);
 
@@ -3499,7 +3499,7 @@ static void qglfResolveVertexAttrib2fv(GLuint indx, const GLfloat* values)
         funcs->vertexAttrib2fv = qglfResolveVertexAttrib2fv;
 }
 
-static void qglfResolveVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z)
+static void QGLF_APIENTRY qglfResolveVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z)
 {
     typedef void (QGLF_APIENTRYP type_glVertexAttrib3f)(GLuint indx, GLfloat x, GLfloat y, GLfloat z);
 
@@ -3519,7 +3519,7 @@ static void qglfResolveVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat
         funcs->vertexAttrib3f = qglfResolveVertexAttrib3f;
 }
 
-static void qglfResolveVertexAttrib3fv(GLuint indx, const GLfloat* values)
+static void QGLF_APIENTRY qglfResolveVertexAttrib3fv(GLuint indx, const GLfloat* values)
 {
     typedef void (QGLF_APIENTRYP type_glVertexAttrib3fv)(GLuint indx, const GLfloat* values);
 
@@ -3539,7 +3539,7 @@ static void qglfResolveVertexAttrib3fv(GLuint indx, const GLfloat* values)
         funcs->vertexAttrib3fv = qglfResolveVertexAttrib3fv;
 }
 
-static void qglfResolveVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+static void QGLF_APIENTRY qglfResolveVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
 {
     typedef void (QGLF_APIENTRYP type_glVertexAttrib4f)(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
 
@@ -3559,7 +3559,7 @@ static void qglfResolveVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat
         funcs->vertexAttrib4f = qglfResolveVertexAttrib4f;
 }
 
-static void qglfResolveVertexAttrib4fv(GLuint indx, const GLfloat* values)
+static void QGLF_APIENTRY qglfResolveVertexAttrib4fv(GLuint indx, const GLfloat* values)
 {
     typedef void (QGLF_APIENTRYP type_glVertexAttrib4fv)(GLuint indx, const GLfloat* values);
 
@@ -3579,7 +3579,7 @@ static void qglfResolveVertexAttrib4fv(GLuint indx, const GLfloat* values)
         funcs->vertexAttrib4fv = qglfResolveVertexAttrib4fv;
 }
 
-static void qglfResolveVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr)
+static void QGLF_APIENTRY qglfResolveVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr)
 {
     typedef void (QGLF_APIENTRYP type_glVertexAttribPointer)(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr);
 
index 44d9bad..759af4f 100644 (file)
@@ -59,6 +59,10 @@ QT_MODULE(OpenGL)
 typedef ptrdiff_t qgl_GLintptr;
 typedef ptrdiff_t qgl_GLsizeiptr;
 
+#ifdef Q_WS_WIN
+#    define QGLF_APIENTRY APIENTRY
+#endif
+
 #ifndef Q_WS_MAC
 # ifndef QGLF_APIENTRYP
 #   ifdef QGLF_APIENTRY
@@ -1945,6 +1949,9 @@ inline void QGLFunctions::glVertexAttribPointer(GLuint indx, GLint size, GLenum
 #ifndef GL_RGBA4
 #define GL_RGBA4 0x8056
 #endif
+#ifndef GL_BGRA
+#define GL_BGRA 0x80E1
+#endif
 #ifndef GL_SAMPLE_ALPHA_TO_COVERAGE
 #define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
 #endif
index f4176fb..241e309 100644 (file)
@@ -90,7 +90,7 @@ protected:
 
 // Wraps a QGLWidget
 class QGLWidget;
-class QGLWidgetGLPaintDevice : public QGLPaintDevice
+class Q_OPENGL_EXPORT QGLWidgetGLPaintDevice : public QGLPaintDevice
 {
 public:
     QGLWidgetGLPaintDevice();
index 8d2603c..2b9728c 100644 (file)
 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
 {
     Q_UNUSED(launchOptions)
+    Q_UNUSED(application)
     foreach (QWidget *widget, qApp->topLevelWidgets()) {
-        QRect geom = widget->geometry();
-        CGRect bar = application.statusBarFrame;
-        if (geom.y() <= bar.size.height) {
-            geom.setY(bar.size.height);
-            widget->setGeometry(geom);
-        }
         QUIKitWindow *platformWindow = static_cast<QUIKitWindow *>(widget->platformWindow());
         platformWindow->ensureNativeWindow();
     }
index d4b4192..3a432d1 100644 (file)
@@ -66,7 +66,7 @@ QUIKitIntegration::~QUIKitIntegration()
 
 QPixmapData *QUIKitIntegration::createPixmapData(QPixmapData::PixelType type) const
 {
-        return new QRasterPixmapData(type);
+    return new QRasterPixmapData(type);
 }
 
 QPlatformWindow *QUIKitIntegration::createPlatformWindow(QWidget *widget, WId winId) const
index 21494c9..78389f2 100644 (file)
@@ -54,7 +54,7 @@ QUIKitScreen::QUIKitScreen(int screenIndex)
     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
     UIScreen *screen = [[UIScreen screens] objectAtIndex:screenIndex];
     CGRect bounds = [screen bounds];
-    m_geometry = QRect(0, 0, bounds.size.width, bounds.size.height);
+    m_geometry = QRect(bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height);
 
     m_format = QImage::Format_ARGB32;
 
@@ -62,7 +62,7 @@ QUIKitScreen::QUIKitScreen(int screenIndex)
 
     const qreal inch = 25.4;
     qreal dpi = 160.;
-    int dragDistance = 14;
+    int dragDistance = 12;
     if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
         dpi = 132.;
         dragDistance = 10;
index 9e73754..5c6496a 100644 (file)
@@ -47,6 +47,8 @@
 #import <UIKit/UIKit.h>
 #import <OpenGLES/ES1/gl.h>
 #import <OpenGLES/ES1/glext.h>
+#import <OpenGLES/ES2/gl.h>
+#import <OpenGLES/ES2/glext.h>
 #import <OpenGLES/EAGL.h>
 
 @interface EAGLView : UIView <UIKeyInput>
@@ -59,6 +61,7 @@
 
     GLuint mFramebuffer, mColorRenderbuffer, mDepthRenderbuffer;
 
+    id delegate;
     // ------- Text Input ----------
     UITextAutocapitalizationType autocapitalizationType;
     UITextAutocorrectionType autocorrectionType;
@@ -77,6 +80,8 @@
 - (void)setWindow:(QPlatformWindow *)window;
 - (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons;
 
+@property (readonly,getter=fbo) GLint fbo;
+@property (nonatomic, assign) id delegate;
 
 // ------- Text Input ----------
 
 
 @end
 
+@protocol EAGLViewDelegate
+- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer;
+@end
+
 class EAGLPlatformContext;
 
 QT_BEGIN_NAMESPACE
@@ -103,7 +112,7 @@ public:
     ~QUIKitWindow();
 
     UIWindow *nativeWindow() const { return mWindow; }
-    UIView *nativeView() const { return mView; }
+    EAGLView *nativeView() const { return mView; }
     void setGeometry(const QRect &rect);
 
     UIWindow *ensureNativeWindow();
index 52d1846..1f57baa 100644 (file)
@@ -79,7 +79,11 @@ public:
         mFormat.setStereo(false);
         mFormat.setDirectRendering(false);
 
+#if defined(QT_OPENGL_ES_2)
+        EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
+#else
         EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
+#endif
         [mView setContext:aContext];
     }
 
@@ -116,6 +120,8 @@ private:
 
 @implementation EAGLView
 
+@synthesize delegate;
+
 + (Class)layerClass
 {
     return [CAEAGLLayer class];
@@ -156,8 +162,8 @@ private:
 {
     if (mContext) {
         [EAGLContext setCurrentContext:mContext];
-        glBindRenderbufferOES(GL_RENDERBUFFER_OES, mColorRenderbuffer);
-        [mContext presentRenderbuffer:GL_RENDERBUFFER_OES];
+        glBindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer);
+        [mContext presentRenderbuffer:GL_RENDERBUFFER];
     }
 }
 
@@ -167,15 +173,15 @@ private:
     {
         [EAGLContext setCurrentContext:mContext];
         if (mFramebuffer) {
-            glDeleteFramebuffersOES(1, &mFramebuffer);
+            glDeleteFramebuffers(1, &mFramebuffer);
             mFramebuffer = 0;
         }
         if (mColorRenderbuffer) {
-            glDeleteRenderbuffersOES(1, &mColorRenderbuffer);
+            glDeleteRenderbuffers(1, &mColorRenderbuffer);
             mColorRenderbuffer = 0;
         }
         if (mDepthRenderbuffer) {
-            glDeleteRenderbuffersOES(1, &mDepthRenderbuffer);
+            glDeleteRenderbuffers(1, &mDepthRenderbuffer);
             mDepthRenderbuffer = 0;
         }
     }
@@ -186,24 +192,27 @@ private:
     if (mContext && !mFramebuffer)
     {
         [EAGLContext setCurrentContext:mContext];
-        glGenFramebuffersOES(1, &mFramebuffer);
-        glBindFramebufferOES(GL_FRAMEBUFFER_OES, mFramebuffer);
-
-        glGenRenderbuffersOES(1, &mColorRenderbuffer);
-        glBindRenderbufferOES(GL_RENDERBUFFER_OES, mColorRenderbuffer);
-        [mContext renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer *)self.layer];
-        glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &mFramebufferWidth);
-        glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &mFramebufferHeight);
-        glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, mColorRenderbuffer);
-
-        glGenRenderbuffersOES(1, &mDepthRenderbuffer);
-        glBindRenderbufferOES(GL_RENDERBUFFER_OES, mDepthRenderbuffer);
-        glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH24_STENCIL8_OES, mFramebufferWidth, mFramebufferHeight);
-        glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, mDepthRenderbuffer);
-        glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_STENCIL_ATTACHMENT_OES, GL_RENDERBUFFER_OES, mDepthRenderbuffer);
-
-        if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES)
-            NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
+        glGenFramebuffers(1, &mFramebuffer);
+        glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
+
+        glGenRenderbuffers(1, &mColorRenderbuffer);
+        glBindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer);
+        [mContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer];
+        glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &mFramebufferWidth);
+        glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &mFramebufferHeight);
+        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mColorRenderbuffer);
+
+        glGenRenderbuffers(1, &mDepthRenderbuffer);
+        glBindRenderbuffer(GL_RENDERBUFFER, mDepthRenderbuffer);
+        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, mFramebufferWidth, mFramebufferHeight);
+        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthRenderbuffer);
+        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDepthRenderbuffer);
+
+        if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
+            NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
+        if (delegate && [delegate respondsToSelector:@selector(eaglView:usesFramebuffer:)]) {
+            [delegate eaglView:self usesFramebuffer:mFramebuffer];
+        }
     }
 }
 
@@ -214,11 +223,16 @@ private:
         [EAGLContext setCurrentContext:mContext];
         if (!mFramebuffer)
             [self createFramebuffer];
-        glBindFramebufferOES(GL_FRAMEBUFFER_OES, mFramebuffer);
+        glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
         glViewport(0, 0, mFramebufferWidth, mFramebufferHeight);
     }
 }
 
+- (GLint)fbo
+{
+    return mFramebuffer;
+}
+
 - (void)setWindow:(QPlatformWindow *)window
 {
     mWindow = window;
@@ -322,6 +336,7 @@ QUIKitWindow::QUIKitWindow(QWidget *tlw) :
     CGRect screenBounds = [mScreen->uiScreen() bounds];
     QRect geom(screenBounds.origin.x, screenBounds.origin.y, screenBounds.size.width, screenBounds.size.height);
     setGeometry(geom);
+    mView = [[EAGLView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
     // TODO ensure the native window if the application is already running
 }
 
@@ -334,7 +349,7 @@ QUIKitWindow::~QUIKitWindow()
 
 void QUIKitWindow::setGeometry(const QRect &rect)
 {
-    if (mWindow) {
+    if (mWindow && rect != geometry()) {
         mWindow.frame = CGRectMake(rect.x(), rect.y(), rect.width(), rect.height());
         mView.frame = CGRectMake(0, 0, rect.width(), rect.height());
         [mView deleteFramebuffer];
@@ -347,14 +362,16 @@ UIWindow *QUIKitWindow::ensureNativeWindow()
 {
     if (!mWindow) {
         // window
-        QRect geom = geometry();
-        CGRect frame = CGRectMake(geom.x(), geom.y(), geom.width(), geom.height());
-        mWindow = [[UIWindow alloc] initWithFrame:frame];
+        CGRect frame = [mScreen->uiScreen() applicationFrame];
+        QRect geom = QRect(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height);
+        widget()->setGeometry(geom);
+        mWindow = [[UIWindow alloc] init];
         mWindow.screen = mScreen->uiScreen();
-        mWindow.frame = frame; // for some reason setting the screen resets frame.origin
+        mWindow.frame = frame; // for some reason setting the screen resets frame.origin, so we need to set the frame afterwards
 
         // view
-        mView = [[EAGLView alloc] initWithFrame:CGRectMake(0, 0, geom.width(), geom.height())];
+        [mView deleteFramebuffer];
+        mView.frame = CGRectMake(0, 0, frame.size.width, frame.size.height); // fill
         [mView setMultipleTouchEnabled:YES];
         [mView setWindow:this];
         [mWindow addSubview:mView];
index bb7dcd7..8caa15f 100644 (file)
 
 #include <QtDebug>
 
+class EAGLPaintDevice;
+
+@interface PaintDeviceHelper : NSObject {
+    EAGLPaintDevice *device;
+}
+
+@property (nonatomic, assign) EAGLPaintDevice *device;
+
+- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer;
+
+@end
+
 class EAGLPaintDevice : public QGLPaintDevice
 {
 public:
     EAGLPaintDevice(QPlatformWindow *window)
         :QGLPaintDevice(), mWindow(window)
     {
+#if defined(QT_OPENGL_ES_2)
+        helper = [[PaintDeviceHelper alloc] init];
+        helper.device = this;
+        EAGLView *view = static_cast<QUIKitWindow *>(window)->nativeView();
+        view.delegate = helper;
+        m_thisFBO = view.fbo;
+#endif
     }
 
+    ~EAGLPaintDevice()
+    {
+#if defined(QT_OPENGL_ES_2)
+        [helper release];
+#endif
+    }
+
+    void setFramebuffer(GLuint buffer) { m_thisFBO = buffer; }
     int devType() const { return QInternal::OpenGL; }
     QSize size() const { return mWindow->geometry().size(); }
     QGLContext* context() const { return QGLContext::fromPlatformGLContext(mWindow->glContext()); }
 
     QPaintEngine *paintEngine() const { return qt_qgl_paint_engine(); }
 
-    void  beginPaint(){
-        QGLPaintDevice::beginPaint();
-    }
 private:
     QPlatformWindow *mWindow;
+    PaintDeviceHelper *helper;
 };
 
+@implementation PaintDeviceHelper
+@synthesize device;
+
+- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer
+{
+    Q_UNUSED(view)
+    if (device)
+        device->setFramebuffer(buffer);
+}
+
+@end
+
 QT_BEGIN_NAMESPACE
 
 QUIKitWindowSurface::QUIKitWindowSurface(QWidget *window)
index 39e7be5..ddd1763 100644 (file)
@@ -49,7 +49,6 @@
 
 QWaylandEglIntegration::QWaylandEglIntegration(struct wl_display *waylandDisplay)
     : mWaylandDisplay(waylandDisplay)
-    , mNativeEglDisplay(wl_egl_display_create(mWaylandDisplay))
 {
     qDebug() << "Using Wayland-EGL";
 }
@@ -63,7 +62,7 @@ QWaylandEglIntegration::~QWaylandEglIntegration()
 void QWaylandEglIntegration::initialize()
 {
     EGLint major,minor;
-    mEglDisplay = eglGetDisplay((EGLNativeDisplayType)mNativeEglDisplay);
+    mEglDisplay = eglGetDisplay(mWaylandDisplay);
     if (mEglDisplay == NULL) {
         qWarning("EGL not available");
     } else {
@@ -84,11 +83,6 @@ EGLDisplay QWaylandEglIntegration::eglDisplay() const
     return mEglDisplay;
 }
 
-wl_egl_display * QWaylandEglIntegration::nativeDisplay() const
-{
-    return mNativeEglDisplay;
-}
-
 QWaylandGLIntegration *QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay)
 {
     return new QWaylandEglIntegration(waylandDisplay->wl_display());
index bf4c3fe..3a26f97 100644 (file)
@@ -65,9 +65,6 @@ private:
     struct wl_display *mWaylandDisplay;
 
     EGLDisplay mEglDisplay;
-    struct wl_egl_display *mNativeEglDisplay;
-
-
 };
 
 #endif // QWAYLANDEGLINTEGRATION_H
index d7cf0a5..cf52f39 100644 (file)
@@ -103,7 +103,7 @@ void QWaylandEglWindow::newSurfaceCreated()
     if (!size.isValid())
         size = QSize(0,0);
 
-    mWaylandEglWindow = wl_egl_window_create(mEglIntegration->nativeDisplay(),mSurface,size.width(),size.height(),visual);
+    mWaylandEglWindow = wl_egl_window_create(mSurface,size.width(),size.height(),visual);
     if (mGLContext) {
         EGLNativeWindowType window(reinterpret_cast<EGLNativeWindowType>(mWaylandEglWindow));
         EGLSurface surface = eglCreateWindowSurface(mEglIntegration->eglDisplay(),mGLContext->eglConfig(),window,NULL);
index 549d039..856321d 100644 (file)
@@ -63,7 +63,6 @@ private:
     QWaylandEglIntegration *mEglIntegration;
     QWaylandGLContext *mGLContext;
     struct wl_egl_window *mWaylandEglWindow;
-    EGLConfig mConfig;
 
     const QWaylandWindow *mParentWindow;
 };
index bc97864..cd07011 100644 (file)
@@ -1,12 +1,11 @@
+include (../../../eglconvenience/eglconvenience.pri)
+
 LIBS += -lwayland-egl -lEGL
 INCLUDEPATH += $$PWD
 SOURCES += $$PWD/qwaylandeglintegration.cpp \
            $$PWD/qwaylandglcontext.cpp \
-           $$PWD/qwaylandeglwindow.cpp \
-           $$PWD/../../../eglconvenience/qeglconvenience.cpp
+           $$PWD/qwaylandeglwindow.cpp
 
 HEADERS += $$PWD/qwaylandeglintegration.h \
            $$PWD/qwaylandglcontext.h \
-           $$PWD/qwaylandeglwindow.h \
-           $$PWD/../../../eglconvenience/qeglconvenience.h \
-    gl_integration/wayland_egl/qwaylandeglinclude.h
+           $$PWD/qwaylandeglwindow.h
index 95b4112..7537b52 100644 (file)
@@ -111,9 +111,9 @@ const struct wl_xcomposite_listener QWaylandXCompositeEGLIntegration::xcomposite
 void QWaylandXCompositeEGLIntegration::wlDisplayHandleGlobal(wl_display *display, uint32_t id, const char *interface, uint32_t version, void *data)
 {
     Q_UNUSED(version);
-    if (strcmp(interface, "xcomposite") == 0) {
+    if (strcmp(interface, "wl_xcomposite") == 0) {
         QWaylandXCompositeEGLIntegration *integration = static_cast<QWaylandXCompositeEGLIntegration *>(data);
-        integration->mWaylandComposite = wl_xcomposite_create(display,id);
+        integration->mWaylandComposite = wl_xcomposite_create(display,id,1);
         wl_xcomposite_add_listener(integration->mWaylandComposite,&xcomposite_listener,integration);
     }
 
index 43c0135..5cb6ef3 100644 (file)
@@ -106,9 +106,9 @@ const struct wl_xcomposite_listener QWaylandXCompositeGLXIntegration::xcomposite
 void QWaylandXCompositeGLXIntegration::wlDisplayHandleGlobal(wl_display *display, uint32_t id, const char *interface, uint32_t version, void *data)
 {
     Q_UNUSED(version);
-    if (strcmp(interface, "xcomposite") == 0) {
+    if (strcmp(interface, "wl_xcomposite") == 0) {
         QWaylandXCompositeGLXIntegration *integration = static_cast<QWaylandXCompositeGLXIntegration *>(data);
-        integration->mWaylandComposite = wl_xcomposite_create(display,id);
+        integration->mWaylandComposite = wl_xcomposite_create(display,id,1);
         wl_xcomposite_add_listener(integration->mWaylandComposite,&xcomposite_listener,integration);
     }
 
index 72376e1..85da7a9 100644 (file)
@@ -39,7 +39,6 @@
 **
 ****************************************************************************/
 
-
 #ifndef XCOMPOSITE_CLIENT_PROTOCOL_H
 #define XCOMPOSITE_CLIENT_PROTOCOL_H
 
@@ -55,84 +54,63 @@ struct wl_client;
 
 struct wl_xcomposite;
 
-struct wl_proxy;
-
-extern void
-wl_proxy_marshal(struct wl_proxy *p, uint32_t opcode, ...);
-extern struct wl_proxy *
-wl_proxy_create(struct wl_proxy *factory,
-               const struct wl_interface *interface);
-extern struct wl_proxy *
-wl_proxy_create_for_id(struct wl_display *display,
-                      const struct wl_interface *interface, uint32_t id);
-extern void
-wl_proxy_destroy(struct wl_proxy *proxy);
-
-extern int
-wl_proxy_add_listener(struct wl_proxy *proxy,
-                     void (**implementation)(void), void *data);
-
-extern void
-wl_proxy_set_user_data(struct wl_proxy *proxy, void *user_data);
-
-extern void *
-wl_proxy_get_user_data(struct wl_proxy *proxy);
-
 extern const struct wl_interface wl_xcomposite_interface;
 
 struct wl_xcomposite_listener {
        void (*root)(void *data,
-                    struct wl_xcomposite *xcomposite,
+                    struct wl_xcomposite *wl_xcomposite,
                     const char *display_name,
                     uint32_t root_window);
 };
 
 static inline int
-wl_xcomposite_add_listener(struct wl_xcomposite *xcomposite,
-                          const struct wl_xcomposite_listener *listener, void *data)
+wl_xcomposite_add_listener(struct wl_xcomposite *wl_xcomposite,
+                             const struct wl_xcomposite_listener *listener, void *data)
 {
-       return wl_proxy_add_listener((struct wl_proxy *) xcomposite,
+       return wl_proxy_add_listener((struct wl_proxy *) wl_xcomposite,
                                     (void (**)(void)) listener, data);
 }
 
 #define WL_XCOMPOSITE_CREATE_BUFFER    0
 
 static inline struct wl_xcomposite *
-wl_xcomposite_create(struct wl_display *display, uint32_t id)
+wl_xcomposite_create(struct wl_display *display, uint32_t id, uint32_t version)
 {
+       wl_display_bind(display, id, "wl_xcomposite", version);
+
        return (struct wl_xcomposite *)
                wl_proxy_create_for_id(display, &wl_xcomposite_interface, id);
 }
 
 static inline void
-wl_xcomposite_set_user_data(struct wl_xcomposite *xcomposite, void *user_data)
+wl_xcomposite_set_user_data(struct wl_xcomposite *wl_xcomposite, void *user_data)
 {
-       wl_proxy_set_user_data((struct wl_proxy *) xcomposite, user_data);
+       wl_proxy_set_user_data((struct wl_proxy *) wl_xcomposite, user_data);
 }
 
 static inline void *
-wl_xcomposite_get_user_data(struct wl_xcomposite *xcomposite)
+wl_xcomposite_get_user_data(struct wl_xcomposite *wl_xcomposite)
 {
-       return wl_proxy_get_user_data((struct wl_proxy *) xcomposite);
+       return wl_proxy_get_user_data((struct wl_proxy *) wl_xcomposite);
 }
 
 static inline void
-wl_xcomposite_destroy(struct wl_xcomposite *xcomposite)
+wl_xcomposite_destroy(struct wl_xcomposite *wl_xcomposite)
 {
-       wl_proxy_destroy((struct wl_proxy *) xcomposite);
+       wl_proxy_destroy((struct wl_proxy *) wl_xcomposite);
 }
 
 static inline struct wl_buffer *
-wl_xcomposite_create_buffer(struct wl_xcomposite *xcomposite, uint32_t x_window, int width, int height, struct wl_visual *visual)
+wl_xcomposite_create_buffer(struct wl_xcomposite *wl_xcomposite, uint32_t x_window, int width, int height, struct wl_visual *visual)
 {
        struct wl_proxy *id;
 
-       id = wl_proxy_create((struct wl_proxy *) xcomposite,
+       id = wl_proxy_create((struct wl_proxy *) wl_xcomposite,
                             &wl_buffer_interface);
        if (!id)
                return NULL;
 
-       wl_proxy_marshal((struct wl_proxy *) xcomposite,
+       wl_proxy_marshal((struct wl_proxy *) wl_xcomposite,
                         WL_XCOMPOSITE_CREATE_BUFFER, id, x_window, width, height, visual);
 
        return (struct wl_buffer *) id;
index 5c966fd..a1b6325 100644 (file)
 #include <stdint.h>
 #include "wayland-util.h"
 
-static const struct wl_message xcomposite_requests[] = {
+static const struct wl_message wl_xcomposite_requests[] = {
        { "create_buffer", "nuiio" },
 };
 
-static const struct wl_message xcomposite_events[] = {
+static const struct wl_message wl_xcomposite_events[] = {
        { "root", "su" },
 };
 
 WL_EXPORT const struct wl_interface wl_xcomposite_interface = {
-       "xcomposite", 1,
-       ARRAY_LENGTH(xcomposite_requests), xcomposite_requests,
-       ARRAY_LENGTH(xcomposite_events), xcomposite_events,
+       "wl_xcomposite", 1,
+       ARRAY_LENGTH(wl_xcomposite_requests), wl_xcomposite_requests,
+       ARRAY_LENGTH(wl_xcomposite_events), wl_xcomposite_events,
 };
 
index 8779d5f..faeb3e8 100644 (file)
@@ -44,6 +44,7 @@
 
 #include <QtCore/QSize>
 
+#include <wayland-client.h>
 #include <wayland-client-protocol.h>
 
 class QWaylandBuffer {
index 1c56561..876b46a 100644 (file)
@@ -126,6 +126,7 @@ QWaylandDisplay::QWaylandDisplay(void)
 #ifdef QT_WAYLAND_GL_SUPPORT
     mEglIntegration = QWaylandGLIntegration::createGLIntegration(this);
 #endif
+    blockingReadEvents();
 
     qRegisterMetaType<uint32_t>("uint32_t");
 
@@ -216,9 +217,6 @@ void QWaylandDisplay::outputHandleGeometry(void *data,
                                            int32_t x, int32_t y,
                                            int32_t width, int32_t height)
 {
-    //call back function called from another thread;
-    //but its safe to call createScreen from another thread since
-    //QWaylandScreen does a moveToThread
     QWaylandDisplay *waylandDisplay = static_cast<QWaylandDisplay *>(data);
     QRect outputRect = QRect(x, y, width, height);
     waylandDisplay->createNewScreen(output,outputRect);
@@ -252,17 +250,17 @@ void QWaylandDisplay::displayHandleGlobal(uint32_t id,
 {
     Q_UNUSED(version);
 
-    if (interface == "output") {
-        struct wl_output *output = wl_output_create(mDisplay, id);
+    if (interface == "wl_output") {
+        struct wl_output *output = wl_output_create(mDisplay, id, 1);
         wl_output_add_listener(output, &outputListener, this);
-    } else if (interface == "compositor") {
-        mCompositor = wl_compositor_create(mDisplay, id);
-    } else if (interface == "shm") {
-        mShm = wl_shm_create(mDisplay, id);
-    } else if (interface == "shell"){
-        mShell = wl_shell_create(mDisplay, id);
+    } else if (interface == "wl_compositor") {
+        mCompositor = wl_compositor_create(mDisplay, id, 1);
+    } else if (interface == "wl_shm") {
+        mShm = wl_shm_create(mDisplay, id, 1);
+    } else if (interface == "wl_shell"){
+        mShell = wl_shell_create(mDisplay, id, 1);
         wl_shell_add_listener(mShell, &shellListener, this);
-    } else if (interface == "input_device") {
+    } else if (interface == "wl_input_device") {
         QWaylandInputDevice *inputDevice =
             new QWaylandInputDevice(mDisplay, id);
         mInputDevices.append(inputDevice);
index 6c2f341..f9e7c95 100644 (file)
@@ -61,7 +61,7 @@
 QWaylandInputDevice::QWaylandInputDevice(struct wl_display *display,
                                         uint32_t id)
     : mDisplay(display)
-    , mInputDevice(wl_input_device_create(display, id))
+    , mInputDevice(wl_input_device_create(display, id, 1))
     , mPointerFocus(NULL)
     , mKeyboardFocus(NULL)
     , mButtons(0)
@@ -101,6 +101,12 @@ void QWaylandInputDevice::inputHandleMotion(void *data,
     QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
     QWaylandWindow *window = inputDevice->mPointerFocus;
 
+    if (window == NULL) {
+       /* We destroyed the pointer focus surface, but the server
+        * didn't get the message yet. */
+       return;
+    }
+
     inputDevice->mSurfacePos = QPoint(surface_x, surface_y);
     inputDevice->mGlobalPos = QPoint(x, y);
     inputDevice->mTime = time;
@@ -120,6 +126,12 @@ void QWaylandInputDevice::inputHandleButton(void *data,
     QWaylandWindow *window = inputDevice->mPointerFocus;
     Qt::MouseButton qt_button;
 
+    if (window == NULL) {
+       /* We destroyed the pointer focus surface, but the server
+        * didn't get the message yet. */
+       return;
+    }
+
     switch (button) {
     case 272:
        qt_button = Qt::LeftButton;
@@ -229,6 +241,12 @@ void QWaylandInputDevice::inputHandleKey(void *data,
     QEvent::Type type;
     char s[2];
 
+    if (window == NULL) {
+       /* We destroyed the keyboard focus surface, but the server
+        * didn't get the message yet. */
+       return;
+    }
+
     code = key + inputDevice->mXkb->min_key_code;
 
     level = 0;
@@ -250,9 +268,6 @@ void QWaylandInputDevice::inputHandleKey(void *data,
 
     sym = translateKey(sym, s, sizeof s);
 
-    qWarning("keycode %d, sym %d, string %d, modifiers 0x%x",
-            code, sym, s[0], (int) inputDevice->mModifiers);
-
     if (window) {
         QWindowSystemInterface::handleKeyEvent(window->widget(),
                                                time, type, sym,
index 3f3ee5e..b6401f6 100644 (file)
@@ -44,6 +44,7 @@
 #include "qwaylanddisplay.h"
 #include "qwaylandshmsurface.h"
 #include "qwaylandshmwindow.h"
+#include "qwaylandnativeinterface.h"
 
 #include "qgenericunixfontdatabase.h"
 
@@ -62,9 +63,15 @@ QWaylandIntegration::QWaylandIntegration(bool useOpenGL)
     : mFontDb(new QGenericUnixFontDatabase())
     , mDisplay(new QWaylandDisplay())
     , mUseOpenGL(useOpenGL)
+    , mNativeInterface(new QWaylandNativeInterface)
 {
 }
 
+QPlatformNativeInterface * QWaylandIntegration::nativeInterface() const
+{
+    return mNativeInterface;
+}
+
 QList<QPlatformScreen *>
 QWaylandIntegration::screens() const
 {
index fc9b8d6..71f6d9c 100644 (file)
@@ -63,12 +63,15 @@ public:
 
     QPlatformFontDatabase *fontDatabase() const;
 
+    QPlatformNativeInterface *nativeInterface() const;
+
 private:
     bool hasOpenGL() const;
 
     QPlatformFontDatabase *mFontDb;
     QWaylandDisplay *mDisplay;
     bool mUseOpenGL;
+    QPlatformNativeInterface *mNativeInterface;
 };
 
 QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wayland/qwaylandnativeinterface.cpp b/src/plugins/platforms/wayland/qwaylandnativeinterface.cpp
new file mode 100644 (file)
index 0000000..c3bfba0
--- /dev/null
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandnativeinterface.h"
+
+#include "qwaylanddisplay.h"
+#include "qwaylandwindow.h"
+#include <QtGui/private/qapplication_p.h>
+
+void *QWaylandNativeInterface::nativeResourceForWidget(const QByteArray &resourceString, QWidget *widget)
+{
+    QByteArray lowerCaseResource = resourceString.toLower();
+
+    if (lowerCaseResource == "display")
+       return qPlatformScreenForWidget(widget)->display()->wl_display();
+    if (lowerCaseResource == "surface") {
+       return ((QWaylandWindow *) widget->platformWindow())->wl_surface();
+    }
+
+    return NULL;
+}
+
+
+QWaylandScreen * QWaylandNativeInterface::qPlatformScreenForWidget(QWidget *widget)
+{
+    QWaylandScreen *screen;
+
+    if (widget) {
+        screen = static_cast<QWaylandScreen *>(QPlatformScreen::platformScreenForWidget(widget));
+    } else {
+        screen = static_cast<QWaylandScreen *>(QApplicationPrivate::platformIntegration()->screens()[0]);
+    }
+    return screen;
+}
diff --git a/src/plugins/platforms/wayland/qwaylandnativeinterface.h b/src/plugins/platforms/wayland/qwaylandnativeinterface.h
new file mode 100644 (file)
index 0000000..ac4cdb9
--- /dev/null
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDNATIVEINTERFACE_H
+#define QWAYLANDNATIVEINTERFACE_H
+
+#include "qwaylandscreen.h"
+
+#include <QtGui/QPlatformNativeInterface>
+
+class QWaylandNativeInterface : public QPlatformNativeInterface
+{
+public:
+    void *nativeResourceForWidget(const QByteArray &resourceString,
+                                 QWidget *widget);
+
+private:
+    static QWaylandScreen *qPlatformScreenForWidget(QWidget *widget);
+};
+
+
+#endif // QWAYLANDNATIVEINTERFACE_H
index 6f52291..53f2f48 100644 (file)
@@ -146,6 +146,7 @@ void QWaylandWindow::newSurfaceCreated()
 void QWaylandWindow::frameCallback(struct wl_surface *surface, void *data, uint32_t time)
 {
     Q_UNUSED(time);
+    Q_UNUSED(surface);
     QWaylandWindow *self = static_cast<QWaylandWindow*>(data);
     self->mWaitingForFrameSync = false;
 }
index 1e60508..47d49a7 100644 (file)
@@ -74,6 +74,9 @@ public:
     void damage(const QRegion &region);
 
     void waitForFrameSync();
+
+    struct wl_surface *wl_surface() const { return mSurface; }
+
 protected:
     struct wl_surface *mSurface;
     virtual void newSurfaceCreated();
index 6ca5a53..3139232 100644 (file)
@@ -8,6 +8,7 @@ DEFINES += $$QMAKE_DEFINES_WAYLAND
 
 SOURCES =   main.cpp \
             qwaylandintegration.cpp \
+            qwaylandnativeinterface.cpp \
             qwaylandshmsurface.cpp \
             qwaylandinputdevice.cpp \
             qwaylandcursor.cpp \
@@ -17,6 +18,7 @@ SOURCES =   main.cpp \
             qwaylandshmwindow.cpp
 
 HEADERS =   qwaylandintegration.h \
+            qwaylandnativeinterface.h \
             qwaylandcursor.h \
             qwaylanddisplay.h \
             qwaylandwindow.h \
index 3d8e290..58b31b4 100644 (file)
@@ -71,6 +71,10 @@ private slots:
     void bidiReorderString();
     void bidiCursor_qtbug2795();
     void bidiCursor_PDF();
+    void bidiCursorMovement_data();
+    void bidiCursorMovement();
+    void bidiCursorLogicalMovement_data();
+    void bidiCursorLogicalMovement();
 };
 
 tst_QComplexText::tst_QComplexText()
@@ -185,6 +189,90 @@ void tst_QComplexText::bidiCursor_qtbug2795()
     QVERIFY(x1 == x2);
 }
 
+void tst_QComplexText::bidiCursorMovement_data()
+{
+    QTest::addColumn<QString>("logical");
+    QTest::addColumn<int>("basicDir");
+
+    const LV *data = logical_visual;
+    while ( data->name ) {
+        //next we fill it with data
+        QTest::newRow( data->name )
+            << QString::fromUtf8( data->logical )
+            << (int) data->basicDir;
+        data++;
+    }
+}
+
+void tst_QComplexText::bidiCursorMovement()
+{
+    QFETCH(QString, logical);
+    QFETCH(int,  basicDir);
+
+    QTextLayout layout(logical);
+
+    QTextOption option = layout.textOption();
+    option.setTextDirection(basicDir == QChar::DirL ? Qt::LeftToRight : Qt::RightToLeft);
+    layout.setTextOption(option);
+    layout.setCursorMoveStyle(QTextCursor::Visual);
+    bool moved;
+    int oldPos, newPos = 0;
+    qreal x, newX;
+
+    layout.beginLayout();
+    QTextLine line = layout.createLine();
+    layout.endLayout();
+
+    newX = line.cursorToX(0);
+    do {
+        oldPos = newPos;
+        x = newX;
+        newX = line.cursorToX(oldPos);
+        if (basicDir == QChar::DirL) {
+            QVERIFY(newX >= x);
+            newPos = layout.rightCursorPosition(oldPos);
+        } else
+        {
+            QVERIFY(newX <= x);
+            newPos = layout.leftCursorPosition(oldPos);
+        }
+        moved = (oldPos != newPos);
+    } while (moved);
+}
+
+void tst_QComplexText::bidiCursorLogicalMovement_data()
+{
+    bidiCursorMovement_data();
+}
+
+void tst_QComplexText::bidiCursorLogicalMovement()
+{
+    QFETCH(QString, logical);
+    QFETCH(int,  basicDir);
+
+    QTextLayout layout(logical);
+
+    QTextOption option = layout.textOption();
+    option.setTextDirection(basicDir == QChar::DirL ? Qt::LeftToRight : Qt::RightToLeft);
+    layout.setTextOption(option);
+    bool moved;
+    int oldPos, newPos = 0;
+
+    do {
+        oldPos = newPos;
+        newPos = layout.nextCursorPosition(oldPos);
+        QVERIFY(newPos >= oldPos);
+        moved = (oldPos != newPos);
+    } while (moved);
+
+    do {
+        oldPos = newPos;
+        newPos = layout.previousCursorPosition(oldPos);
+        QVERIFY(newPos <= oldPos);
+        moved = (oldPos != newPos);
+    } while (moved);
+}
+
 void tst_QComplexText::bidiCursor_PDF()
 {
     QString str = QString::fromUtf8("\342\200\252hello\342\200\254");
index 9176174..f45481c 100644 (file)
@@ -282,6 +282,12 @@ private slots:
     void validateAndSet();
 #endif
 
+    void bidiVisualMovement_data();
+    void bidiVisualMovement();
+
+    void bidiLogicalMovement_data();
+    void bidiLogicalMovement();
+
 protected slots:
 #ifdef QT3_SUPPORT
     void lostFocus();
@@ -3760,5 +3766,135 @@ void tst_QLineEdit::QTBUG13520_textNotVisible()
 }
 
 
+void tst_QLineEdit::bidiVisualMovement_data()
+{
+    QTest::addColumn<QString>("logical");
+    QTest::addColumn<int>("basicDir");
+    QTest::addColumn<IntList>("positionList");
+
+    QTest::newRow("Latin text")
+        << QString::fromUtf8("abc")
+        << (int) QChar::DirL
+        << (IntList() << 0 << 1 << 2 << 3);
+    QTest::newRow("Hebrew text, one item")
+        << QString::fromUtf8("\327\220\327\221\327\222")
+        << (int) QChar::DirR
+        << (QList<int>() << 0 << 1 << 2 << 3);
+    QTest::newRow("Hebrew text after Latin text")
+        << QString::fromUtf8("abc\327\220\327\221\327\222")
+        << (int) QChar::DirL
+        << (QList<int>() << 0 << 1 << 2 << 6 << 5 << 4 << 3);
+    QTest::newRow("Latin text after Hebrew text")
+        << QString::fromUtf8("\327\220\327\221\327\222abc")
+        << (int) QChar::DirR
+        << (QList<int>() << 0 << 1 << 2 << 6 << 5 << 4 << 3);
+    QTest::newRow("LTR, 3 items")
+        << QString::fromUtf8("abc\327\220\327\221\327\222abc")
+        << (int) QChar::DirL
+        << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 9);
+    QTest::newRow("RTL, 3 items")
+        << QString::fromUtf8("\327\220\327\221\327\222abc\327\220\327\221\327\222")
+        << (int) QChar::DirR
+        << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 9);
+    QTest::newRow("LTR, 4 items")
+        << QString::fromUtf8("abc\327\220\327\221\327\222abc\327\220\327\221\327\222")
+        << (int) QChar::DirL
+        << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 12 << 11 << 10 << 9);
+    QTest::newRow("RTL, 4 items")
+        << QString::fromUtf8("\327\220\327\221\327\222abc\327\220\327\221\327\222abc")
+        << (int) QChar::DirR
+        << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 12 << 11 << 10 << 9);
+}
+
+void tst_QLineEdit::bidiVisualMovement()
+{
+    QFETCH(QString, logical);
+    QFETCH(int,     basicDir);
+    QFETCH(IntList, positionList);
+
+    QLineEdit le;
+    le.setText(logical);
+
+    le.setCursorMoveStyle(QTextCursor::Visual);
+    le.setCursorPosition(0);
+
+    bool moved;
+    int i = 0, oldPos, newPos = 0;
+
+    do {
+        oldPos = newPos;
+        QVERIFY(oldPos == positionList[i]);
+        if (basicDir == QChar::DirL) {
+            QTest::keyClick(&le, Qt::Key_Right);
+        } else
+            QTest::keyClick(&le, Qt::Key_Left);
+        newPos = le.cursorPosition();
+        moved = (oldPos != newPos);
+        i++;
+    } while (moved);
+
+    QVERIFY(i == positionList.size());
+
+    do {
+        i--;
+        oldPos = newPos;
+        QVERIFY(oldPos == positionList[i]);
+        if (basicDir == QChar::DirL) {
+            QTest::keyClick(&le, Qt::Key_Left);
+        } else
+        {
+            QTest::keyClick(&le, Qt::Key_Right);
+        }
+        newPos = le.cursorPosition();
+        moved = (oldPos != newPos);
+    } while (moved && i >= 0);
+}
+
+void tst_QLineEdit::bidiLogicalMovement_data()
+{
+    bidiVisualMovement_data();
+}
+
+void tst_QLineEdit::bidiLogicalMovement()
+{
+    QFETCH(QString, logical);
+    QFETCH(int,     basicDir);
+
+    QLineEdit le;
+    le.setText(logical);
+
+    le.setCursorMoveStyle(QTextCursor::Logical);
+    le.setCursorPosition(0);
+
+    bool moved;
+    int i = 0, oldPos, newPos = 0;
+
+    do {
+        oldPos = newPos;
+        QVERIFY(oldPos == i);
+        if (basicDir == QChar::DirL) {
+            QTest::keyClick(&le, Qt::Key_Right);
+        } else
+            QTest::keyClick(&le, Qt::Key_Left);
+        newPos = le.cursorPosition();
+        moved = (oldPos != newPos);
+        i++;
+    } while (moved);
+
+    do {
+        i--;
+        oldPos = newPos;
+        QVERIFY(oldPos == i);
+        if (basicDir == QChar::DirL) {
+            QTest::keyClick(&le, Qt::Key_Left);
+        } else
+        {
+            QTest::keyClick(&le, Qt::Key_Right);
+        }
+        newPos = le.cursorPosition();
+        moved = (oldPos != newPos);
+    } while (moved && i >= 0);
+}
+
 QTEST_MAIN(tst_QLineEdit)
 #include "tst_qlineedit.moc"
index 4d032e8..4ba51de 100644 (file)
@@ -1337,7 +1337,7 @@ void tst_QPixmap::toSymbianCFbsBitmap()
 
 void tst_QPixmap::onlyNullPixmapsOutsideGuiThread()
 {
-#if !defined(Q_WS_WIN)
+#if !defined(Q_WS_WIN) && !defined(Q_WS_MAC)
     class Thread : public QThread
     {
     public:
@@ -1370,7 +1370,7 @@ void tst_QPixmap::onlyNullPixmapsOutsideGuiThread()
     thread.wait();
 #endif
 
-#endif // !defined(Q_WS_WIN)
+#endif // !defined(Q_WS_WIN) && !defined(Q_WS_MAC)
 }
 
 void tst_QPixmap::refUnref()
index 3aa4006..4b42c74 100644 (file)
@@ -104,7 +104,7 @@ void tst_QRawFont::invalidRawFont()
 {
     QRawFont font;
     QVERIFY(!font.isValid());
-    QCOMPARE(font.pixelSize(), -1);
+    QCOMPARE(font.pixelSize(), 0.0);
     QVERIFY(font.familyName().isEmpty());
     QCOMPARE(font.style(), QFont::StyleNormal);
     QCOMPARE(font.weight(), -1);
@@ -165,7 +165,7 @@ void tst_QRawFont::correctFontData_data()
     QTest::addColumn<QFont::Weight>("weight");
     QTest::addColumn<QFont::HintingPreference>("hintingPreference");
     QTest::addColumn<qreal>("unitsPerEm");
-    QTest::addColumn<int>("pixelSize");
+    QTest::addColumn<qreal>("pixelSize");
 
     int hintingPreferences[] = {
         int(QFont::PreferDefaultHinting),
@@ -189,7 +189,7 @@ void tst_QRawFont::correctFontData_data()
                 << QFont::Normal
                 << QFont::HintingPreference(*hintingPreference)
                 << 1000.0
-                << 10;
+                << 10.0;
 
         fileName = QLatin1String(SRCDIR "testfont_bold_italic.ttf");
         title = fileName
@@ -203,7 +203,7 @@ void tst_QRawFont::correctFontData_data()
                 << QFont::Bold
                 << QFont::HintingPreference(*hintingPreference)
                 << 1000.0
-                << 10;
+                << 10.0;
 
         ++hintingPreference;
     }
@@ -217,7 +217,7 @@ void tst_QRawFont::correctFontData()
     QFETCH(QFont::Weight, weight);
     QFETCH(QFont::HintingPreference, hintingPreference);
     QFETCH(qreal, unitsPerEm);
-    QFETCH(int, pixelSize);
+    QFETCH(qreal, pixelSize);
 
     QRawFont font(fileName, 10, hintingPreference);
     QVERIFY(font.isValid());
@@ -284,7 +284,7 @@ void tst_QRawFont::textLayout()
 
     QString familyName = QString::fromLatin1("QtBidiTestFont");
     QFont font(familyName);
-    font.setPixelSize(18);
+    font.setPixelSize(18.0);
     QCOMPARE(QFontInfo(font).family(), familyName);
 
     QTextLayout layout(QLatin1String("Foobar"));
@@ -301,7 +301,7 @@ void tst_QRawFont::textLayout()
     QRawFont rawFont = glyphs.font();
     QVERIFY(rawFont.isValid());
     QCOMPARE(rawFont.familyName(), familyName);
-    QCOMPARE(rawFont.pixelSize(), 18);
+    QCOMPARE(rawFont.pixelSize(), 18.0);
 
     QVector<quint32> expectedGlyphIndices;
     expectedGlyphIndices << 44 << 83 << 83 << 70 << 69 << 86;
@@ -597,12 +597,12 @@ void tst_QRawFont::fromFont()
 
     QFont font(familyName);
     font.setHintingPreference(hintingPreference);
-    font.setPixelSize(26);
+    font.setPixelSize(26.0);
 
     QRawFont rawFont = QRawFont::fromFont(font, writingSystem);
     QVERIFY(rawFont.isValid());
     QCOMPARE(rawFont.familyName(), familyName);
-    QCOMPARE(rawFont.pixelSize(), 26);
+    QCOMPARE(rawFont.pixelSize(), 26.0);
 
     QVERIFY(fontDatabase.removeApplicationFont(id));
 }
@@ -623,7 +623,7 @@ void tst_QRawFont::copyConstructor()
 
     {
         QString rawFontFamilyName;
-        int rawFontPixelSize;
+        qreal rawFontPixelSize;
         qreal rawFontAscent;
         qreal rawFontDescent;
         int rawFontTableSize;
@@ -691,7 +691,7 @@ void tst_QRawFont::detach()
 
     {
         QString rawFontFamilyName;
-        int rawFontPixelSize;
+        qreal rawFontPixelSize;
         qreal rawFontAscent;
         qreal rawFontDescent;
         int rawFontTableSize;
@@ -773,15 +773,15 @@ void tst_QRawFont::unsupportedWritingSystem()
 
     QFont font("QtBidiTestFont");
     font.setHintingPreference(hintingPreference);
-    font.setPixelSize(12);
+    font.setPixelSize(12.0);
 
     QRawFont rawFont = QRawFont::fromFont(font, QFontDatabase::Any);
     QCOMPARE(rawFont.familyName(), QString::fromLatin1("QtBidiTestFont"));
-    QCOMPARE(rawFont.pixelSize(), 12);
+    QCOMPARE(rawFont.pixelSize(), 12.0);
 
     rawFont = QRawFont::fromFont(font, QFontDatabase::Hebrew);
     QCOMPARE(rawFont.familyName(), QString::fromLatin1("QtBidiTestFont"));
-    QCOMPARE(rawFont.pixelSize(), 12);
+    QCOMPARE(rawFont.pixelSize(), 12.0);
 
     QString arabicText = QFontDatabase::writingSystemSample(QFontDatabase::Arabic);
 
@@ -798,11 +798,11 @@ void tst_QRawFont::unsupportedWritingSystem()
     QGlyphs glyphs = glyphss.at(0);
     QRawFont layoutFont = glyphs.font();
     QVERIFY(layoutFont.familyName() != QString::fromLatin1("QtBidiTestFont"));
-    QCOMPARE(layoutFont.pixelSize(), 12);
+    QCOMPARE(layoutFont.pixelSize(), 12.0);
 
     rawFont = QRawFont::fromFont(font, QFontDatabase::Arabic);
     QCOMPARE(rawFont.familyName(), layoutFont.familyName());
-    QCOMPARE(rawFont.pixelSize(), 12);
+    QCOMPARE(rawFont.pixelSize(), 12.0);
 
     fontDatabase.removeApplicationFont(id);
 }
index 9ca17b9..5a64593 100644 (file)
@@ -42,7 +42,6 @@
 
 #include <QtTest/QtTest>
 
-
 #include <qtextedit.h>
 #include <qtextcursor.h>
 #include <qtextlist.h>
@@ -69,6 +68,7 @@ typedef QList<keyPairType> pairListType;
 Q_DECLARE_METATYPE(pairListType);
 Q_DECLARE_METATYPE(keyPairType);
 Q_DECLARE_METATYPE(QList<bool>);
+Q_DECLARE_METATYPE(QList<int>);
 
 #ifdef Q_WS_MAC
 #include <Carbon/Carbon.h>
@@ -205,6 +205,11 @@ private slots:
 #ifndef QT_NO_CONTEXTMENU
     void taskQTBUG_7902_contextMenuCrash();
 #endif
+    void bidiVisualMovement_data();
+    void bidiVisualMovement();
+
+    void bidiLogicalMovement_data();
+    void bidiLogicalMovement();
 
 private:
     void createSelection();
@@ -2235,5 +2240,147 @@ void tst_QTextEdit::taskQTBUG_7902_contextMenuCrash()
 }
 #endif
 
+void tst_QTextEdit::bidiVisualMovement_data()
+{
+    QTest::addColumn<QString>("logical");
+    QTest::addColumn<int>("basicDir");
+    QTest::addColumn<QList<int> >("positionList");
+
+    QTest::newRow("Latin text")
+        << QString::fromUtf8("abc")
+        << (int) QChar::DirL
+        << (QList<int>() << 0 << 1 << 2 << 3);
+    QTest::newRow("Hebrew text, one item")
+        << QString::fromUtf8("\327\220\327\221\327\222")
+        << (int) QChar::DirR
+        << (QList<int>() << 0 << 1 << 2 << 3);
+    QTest::newRow("Hebrew text after Latin text")
+        << QString::fromUtf8("abc\327\220\327\221\327\222")
+        << (int) QChar::DirL
+        << (QList<int>() << 0 << 1 << 2 << 6 << 5 << 4 << 3);
+    QTest::newRow("Latin text after Hebrew text")
+        << QString::fromUtf8("\327\220\327\221\327\222abc")
+        << (int) QChar::DirR
+        << (QList<int>() << 0 << 1 << 2 << 6 << 5 << 4 << 3);
+    QTest::newRow("LTR, 3 items")
+        << QString::fromUtf8("abc\327\220\327\221\327\222abc")
+        << (int) QChar::DirL
+        << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 9);
+    QTest::newRow("RTL, 3 items")
+        << QString::fromUtf8("\327\220\327\221\327\222abc\327\220\327\221\327\222")
+        << (int) QChar::DirR
+        << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 9);
+    QTest::newRow("LTR, 4 items")
+        << QString::fromUtf8("abc\327\220\327\221\327\222abc\327\220\327\221\327\222")
+        << (int) QChar::DirL
+        << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 12 << 11 << 10 << 9);
+    QTest::newRow("RTL, 4 items")
+        << QString::fromUtf8("\327\220\327\221\327\222abc\327\220\327\221\327\222abc")
+        << (int) QChar::DirR
+        << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 12 << 11 << 10 << 9);
+}
+
+void tst_QTextEdit::bidiVisualMovement()
+{
+    QFETCH(QString,      logical);
+    QFETCH(int,          basicDir);
+    QFETCH(QList<int>,   positionList);
+
+    ed->setText(logical);
+
+    QTextOption option = ed->document()->defaultTextOption();
+    option.setTextDirection(basicDir == QChar::DirL ? Qt::LeftToRight : Qt::RightToLeft);
+    ed->document()->setDefaultTextOption(option);
+
+    ed->document()->setDefaultCursorMoveStyle(QTextCursor::Visual);
+    ed->moveCursor(QTextCursor::Start);
+    ed->show();
+
+    bool moved;
+    int i = 0, oldPos, newPos = 0;
+
+    do {
+        oldPos = newPos;
+        QVERIFY(oldPos == positionList[i]);
+        if (basicDir == QChar::DirL) {
+            ed->moveCursor(QTextCursor::Right);
+        } else
+        {
+            ed->moveCursor(QTextCursor::Left);
+        }
+        newPos = ed->textCursor().position();
+        moved = (oldPos != newPos);
+        i++;
+    } while (moved);
+
+    QVERIFY(i == positionList.size());
+
+    do {
+        i--;
+        oldPos = newPos;
+        QVERIFY(oldPos == positionList[i]);
+        if (basicDir == QChar::DirL) {
+            ed->moveCursor(QTextCursor::Left);
+        } else
+        {
+            ed->moveCursor(QTextCursor::Right);
+        }
+        newPos = ed->textCursor().position();
+        moved = (oldPos != newPos);
+    } while (moved && i >= 0);
+}
+
+void tst_QTextEdit::bidiLogicalMovement_data()
+{
+    bidiVisualMovement_data();
+}
+
+void tst_QTextEdit::bidiLogicalMovement()
+{
+    QFETCH(QString,      logical);
+    QFETCH(int,          basicDir);
+
+    ed->setText(logical);
+
+    QTextOption option = ed->document()->defaultTextOption();
+    option.setTextDirection(basicDir == QChar::DirL ? Qt::LeftToRight : Qt::RightToLeft);
+    ed->document()->setDefaultTextOption(option);
+
+    ed->document()->setDefaultCursorMoveStyle(QTextCursor::Logical);
+    ed->moveCursor(QTextCursor::Start);
+    ed->show();
+
+    bool moved;
+    int i = 0, oldPos, newPos = 0;
+
+    do {
+        oldPos = newPos;
+        QVERIFY(oldPos == i);
+        if (basicDir == QChar::DirL) {
+            ed->moveCursor(QTextCursor::Right);
+        } else
+        {
+            ed->moveCursor(QTextCursor::Left);
+        }
+        newPos = ed->textCursor().position();
+        moved = (oldPos != newPos);
+        i++;
+    } while (moved);
+
+    do {
+        i--;
+        oldPos = newPos;
+        QVERIFY(oldPos == i);
+        if (basicDir == QChar::DirL) {
+            ed->moveCursor(QTextCursor::Left);
+        } else
+        {
+            ed->moveCursor(QTextCursor::Right);
+        }
+        newPos = ed->textCursor().position();
+        moved = (oldPos != newPos);
+    } while (moved && i >= 0);
+}
+
 QTEST_MAIN(tst_QTextEdit)
 #include "tst_qtextedit.moc"