From eae8fb85997d82ecec0743ba3e470681129bff41 Mon Sep 17 00:00:00 2001 From: Qt by Nokia Date: Wed, 27 Apr 2011 14:13:26 +0200 Subject: [PATCH 01/27] Initial import from qtquick2. Branched from the monolithic repo, Qt qtquick2 branch, at commit a4a585d2ee907746682846ae6e8a48e19deef469 --- mkspecs/features/qt.prf | 4 + src/corelib/animation/qabstractanimation.cpp | 56 ++++- src/corelib/animation/qabstractanimation.h | 3 + src/corelib/animation/qabstractanimation_p.h | 5 + src/corelib/io/qprocess_unix.cpp | 30 ++- src/corelib/kernel/qcoreapplication.cpp | 18 +- src/corelib/kernel/qcoreapplication.h | 1 + src/corelib/kernel/qcoreapplication_p.h | 2 + src/gui/kernel/qcocoaview_mac.mm | 1 - src/gui/kernel/qsessionmanager_qpa.cpp | 2 + src/gui/painting/qpaintengine_mac.cpp | 4 +- src/gui/text/qfontengine_ft_p.h | 9 +- src/gui/text/qfontengine_p.h | 8 + src/gui/text/qrawfont_p.h | 2 +- src/gui/text/qstatictext.cpp | 10 +- src/opengl/gl2paintengineex/qtriangulator.cpp | 17 +- src/opengl/gl2paintengineex/qtriangulator_p.h | 12 +- src/opengl/qgl.cpp | 31 +++ src/opengl/qgl.h | 10 + src/opengl/qgl_p.h | 6 +- src/opengl/qglfunctions.cpp | 198 +++++++++--------- src/opengl/qglfunctions.h | 7 + src/opengl/qglpaintdevice_p.h | 2 +- .../wayland_egl/qwaylandeglwindow.h | 1 - .../wayland_egl/wayland_egl.pri | 9 +- .../platforms/wayland/qwaylandbuffer.h | 1 + .../platforms/wayland/qwaylandinputdevice.cpp | 21 +- .../platforms/wayland/qwaylandintegration.cpp | 7 + .../platforms/wayland/qwaylandintegration.h | 3 + .../wayland/qwaylandnativeinterface.cpp | 72 +++++++ .../wayland/qwaylandnativeinterface.h | 60 ++++++ .../platforms/wayland/qwaylandwindow.h | 3 + src/plugins/platforms/wayland/wayland.pro | 2 + 33 files changed, 465 insertions(+), 152 deletions(-) create mode 100644 src/plugins/platforms/wayland/qwaylandnativeinterface.cpp create mode 100644 src/plugins/platforms/wayland/qwaylandnativeinterface.h diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index 191a4497194..e4a5ef71629 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -35,6 +35,9 @@ plugin { #Qt plugins INCLUDEPATH = $$QMAKE_INCDIR_QT $$INCLUDEPATH #prepending prevents us from picking up "stale" includes win32:INCLUDEPATH += $$QMAKE_INCDIR_QT/ActiveQt +# As declarative now uses OpenGL in the API, force include it to avoid having to update all projects +contains(QT, declarative): QT += opengl + # As order does matter for static libs, we reorder the QT variable here TMPLIBS = declarative webkit phonon multimedia dbus testlib script scripttools svg qt3support sql xmlpatterns xml egl opengl openvg gui network core meegographicssystemhelper for(QTLIB, $$list($$TMPLIBS)) { @@ -48,6 +51,7 @@ for(QTLIB, $$list($$QT_UNKNOWN)) { !contains(TMPLIBS, $$QTLIB):message("Warning: unknown QT: $$QTLIB") } + QT_PLUGIN_VERIFY = QTPLUGIN DEPLOYMENT_PLUGIN for(QT_CURRENT_VERIFY, $$list($$QT_PLUGIN_VERIFY)) { for(QTPLUG, $$list($$lower($$unique($$QT_CURRENT_VERIFY)))) { diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index 602cf8a6fdd..f399d7c4cff 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -260,7 +260,8 @@ void QUnifiedTimer::restartAnimationTimer() } else if (!driver->isRunning() || isPauseTimerActive) { driver->start(); isPauseTimerActive = false; - } + } else if (runningLeafAnimations == 0) + driver->stop(); } void QUnifiedTimer::setTimingInterval(int interval) @@ -389,19 +390,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,6 +455,12 @@ 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 @@ -453,6 +490,15 @@ void QAnimationDriver::install() 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; diff --git a/src/corelib/animation/qabstractanimation.h b/src/corelib/animation/qabstractanimation.h index 0900870ce2e..a0cb0f93d0b 100644 --- a/src/corelib/animation/qabstractanimation.h +++ b/src/corelib/animation/qabstractanimation.h @@ -141,9 +141,12 @@ class Q_CORE_EXPORT QAnimationDriver : public QObject public: QAnimationDriver(QObject *parent = 0); + ~QAnimationDriver(); void advance(); + void install(); + void uninstall(); bool isRunning() const; diff --git a/src/corelib/animation/qabstractanimation_p.h b/src/corelib/animation/qabstractanimation_p.h index ba92960f6b0..1cba4644a87 100644 --- a/src/corelib/animation/qabstractanimation_p.h +++ b/src/corelib/animation/qabstractanimation_p.h @@ -180,10 +180,15 @@ public: static void updateAnimationTimer(); void installAnimationDriver(QAnimationDriver *driver); + void uninstallAnimationDriver(QAnimationDriver *driver); + bool canUninstallAnimationDriver(QAnimationDriver *driver); void restartAnimationTimer(); void updateAnimationsTime(); + //useful for profiling/debugging + int runningAnimationCount() { return animations.count(); } + protected: void timerEvent(QTimerEvent *); diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index 3af9b46df83..f53742b8150 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -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 diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index be86c58d472..e0841cbadca 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -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" diff --git a/src/corelib/kernel/qcoreapplication.h b/src/corelib/kernel/qcoreapplication.h index 3957158d839..024c5096c98 100644 --- a/src/corelib/kernel/qcoreapplication.h +++ b/src/corelib/kernel/qcoreapplication.h @@ -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); diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h index add2a3553e1..fdceab4724a 100644 --- a/src/corelib/kernel/qcoreapplication_p.h +++ b/src/corelib/kernel/qcoreapplication_p.h @@ -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 *); diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index b5e5d186b86..e885d1552c0 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -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()); } } diff --git a/src/gui/kernel/qsessionmanager_qpa.cpp b/src/gui/kernel/qsessionmanager_qpa.cpp index ef532d79812..68685b4fed0 100644 --- a/src/gui/kernel/qsessionmanager_qpa.cpp +++ b/src/gui/kernel/qsessionmanager_qpa.cpp @@ -42,6 +42,8 @@ #include #include +#include + #ifndef QT_NO_SESSIONMANAGER QT_BEGIN_NAMESPACE diff --git a/src/gui/painting/qpaintengine_mac.cpp b/src/gui/painting/qpaintengine_mac.cpp index 8aab7c7a4b7..c6d061dea87 100644 --- a/src/gui/painting/qpaintengine_mac.cpp +++ b/src/gui/painting/qpaintengine_mac.cpp @@ -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()); diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h index 887efed8437..8733498cb76 100644 --- a/src/gui/text/qfontengine_ft_p.h +++ b/src/gui/text/qfontengine_ft_p.h @@ -311,14 +311,7 @@ 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); HintStyle defaultHintStyle() const { return default_hint_style; } protected: diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index 5b39fd39ad3..30277b5156f 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -248,6 +248,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 diff --git a/src/gui/text/qrawfont_p.h b/src/gui/text/qrawfont_p.h index f9a9ab55cdd..18f3e7d0069 100644 --- a/src/gui/text/qrawfont_p.h +++ b/src/gui/text/qrawfont_p.h @@ -62,7 +62,7 @@ QT_BEGIN_NAMESPACE namespace { class CustomFontFileLoader; } -class Q_AUTOTEST_EXPORT QRawFontPrivate +class Q_GUI_EXPORT QRawFontPrivate { public: QRawFontPrivate() diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp index 1cfb4b61f9b..5bee497a3e4 100644 --- a/src/gui/text/qstatictext.cpp +++ b/src/gui/text/qstatictext.cpp @@ -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(); diff --git a/src/opengl/gl2paintengineex/qtriangulator.cpp b/src/opengl/gl2paintengineex/qtriangulator.cpp index 94024f3d74f..a5faa36b4a4 100644 --- a/src/opengl/gl2paintengineex/qtriangulator.cpp +++ b/src/opengl/gl2paintengineex/qtriangulator.cpp @@ -1564,6 +1564,19 @@ QVertexSet QTriangulator::triangulate() template QVertexSet QTriangulator::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 result; result.indices = m_indices; result.vertices.resize(2 * m_vertices.size()); @@ -3084,7 +3097,7 @@ QPolylineSet qPolyline(const QVectorPath &path, } else { QTriangulator triangulator; triangulator.initialize(path, matrix, lod); - QVertexSet vertexSet = triangulator.triangulate(); + QVertexSet vertexSet = triangulator.polyline(); polyLineSet.vertices = vertexSet.vertices; polyLineSet.indices.setDataUshort(vertexSet.indices); } @@ -3104,7 +3117,7 @@ QPolylineSet qPolyline(const QPainterPath &path, } else { QTriangulator triangulator; triangulator.initialize(path, matrix, lod); - QVertexSet vertexSet = triangulator.triangulate(); + QVertexSet vertexSet = triangulator.polyline(); polyLineSet.vertices = vertexSet.vertices; polyLineSet.indices.setDataUshort(vertexSet.indices); } diff --git a/src/opengl/gl2paintengineex/qtriangulator_p.h b/src/opengl/gl2paintengineex/qtriangulator_p.h index a205b923e9f..081738addfd 100644 --- a/src/opengl/gl2paintengineex/qtriangulator_p.h +++ b/src/opengl/gl2paintengineex/qtriangulator_p.h @@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE -class QVertexIndexVector +class Q_OPENGL_EXPORT QVertexIndexVector { public: enum Type { @@ -111,7 +111,7 @@ private: QVector 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 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 diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 057fb55e2c1..7ce35f8d1c8 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -43,6 +43,7 @@ #include "qplatformdefs.h" #include "qgl.h" #include +#include #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; @@ -2710,6 +2714,19 @@ int QGLContextPrivate::maxTextureSize() #endif } +/*! + Returns a QGLFunctions object that is initialized for this context. + */ +QGLFunctions *QGLContext::functions() const +{ + QGLContextPrivate *d = const_cast(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 @@ -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. diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h index c57995d8d03..dfd1ae18248 100644 --- a/src/opengl/qgl.h +++ b/src/opengl/qgl.h @@ -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) diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 50d13c9540b..6a503fab900 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -159,7 +159,7 @@ public: QGLFormat::OpenGLContextProfile profile; }; -class QGLWidgetPrivate : public QWidgetPrivate +class Q_OPENGL_EXPORT QGLWidgetPrivate : public QWidgetPrivate { Q_DECLARE_PUBLIC(QGLWidget) public: @@ -441,6 +441,8 @@ public: QHash 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 +501,7 @@ private: QGLContext *m_ctx; }; -class QGLTextureDestroyer : public QObject +class Q_OPENGL_EXPORT QGLTextureDestroyer : public QObject { Q_OBJECT public: diff --git a/src/opengl/qglfunctions.cpp b/src/opengl/qglfunctions.cpp index be8219a07fc..80270815435 100644 --- a/src/opengl/qglfunctions.cpp +++ b/src/opengl/qglfunctions.cpp @@ -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); diff --git a/src/opengl/qglfunctions.h b/src/opengl/qglfunctions.h index 44d9bad9fa9..759af4f939f 100644 --- a/src/opengl/qglfunctions.h +++ b/src/opengl/qglfunctions.h @@ -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 diff --git a/src/opengl/qglpaintdevice_p.h b/src/opengl/qglpaintdevice_p.h index f4176fb2e7d..241e3091c64 100644 --- a/src/opengl/qglpaintdevice_p.h +++ b/src/opengl/qglpaintdevice_p.h @@ -90,7 +90,7 @@ protected: // Wraps a QGLWidget class QGLWidget; -class QGLWidgetGLPaintDevice : public QGLPaintDevice +class Q_OPENGL_EXPORT QGLWidgetGLPaintDevice : public QGLPaintDevice { public: QGLWidgetGLPaintDevice(); diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h index 549d039bf8b..856321dec82 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h @@ -63,7 +63,6 @@ private: QWaylandEglIntegration *mEglIntegration; QWaylandGLContext *mGLContext; struct wl_egl_window *mWaylandEglWindow; - EGLConfig mConfig; const QWaylandWindow *mParentWindow; }; diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri b/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri index bc978645c4a..cd0701150fe 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri @@ -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 diff --git a/src/plugins/platforms/wayland/qwaylandbuffer.h b/src/plugins/platforms/wayland/qwaylandbuffer.h index 8779d5fda0d..faeb3e85b13 100644 --- a/src/plugins/platforms/wayland/qwaylandbuffer.h +++ b/src/plugins/platforms/wayland/qwaylandbuffer.h @@ -44,6 +44,7 @@ #include +#include #include class QWaylandBuffer { diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp index 6c2f341f642..2d7df1d6135 100644 --- a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp +++ b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp @@ -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, diff --git a/src/plugins/platforms/wayland/qwaylandintegration.cpp b/src/plugins/platforms/wayland/qwaylandintegration.cpp index 3f3ee5e5714..b6401f6d06f 100644 --- a/src/plugins/platforms/wayland/qwaylandintegration.cpp +++ b/src/plugins/platforms/wayland/qwaylandintegration.cpp @@ -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 QWaylandIntegration::screens() const { diff --git a/src/plugins/platforms/wayland/qwaylandintegration.h b/src/plugins/platforms/wayland/qwaylandintegration.h index fc9b8d6a6e0..71f6d9c7b3b 100644 --- a/src/plugins/platforms/wayland/qwaylandintegration.h +++ b/src/plugins/platforms/wayland/qwaylandintegration.h @@ -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 index 00000000000..c3bfba03cc2 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandnativeinterface.cpp @@ -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 + +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(QPlatformScreen::platformScreenForWidget(widget)); + } else { + screen = static_cast(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 index 00000000000..ac4cdb9a228 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandnativeinterface.h @@ -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 + +class QWaylandNativeInterface : public QPlatformNativeInterface +{ +public: + void *nativeResourceForWidget(const QByteArray &resourceString, + QWidget *widget); + +private: + static QWaylandScreen *qPlatformScreenForWidget(QWidget *widget); +}; + + +#endif // QWAYLANDNATIVEINTERFACE_H diff --git a/src/plugins/platforms/wayland/qwaylandwindow.h b/src/plugins/platforms/wayland/qwaylandwindow.h index 1e605088ad1..47d49a70d9e 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.h +++ b/src/plugins/platforms/wayland/qwaylandwindow.h @@ -74,6 +74,9 @@ public: void damage(const QRegion ®ion); void waitForFrameSync(); + + struct wl_surface *wl_surface() const { return mSurface; } + protected: struct wl_surface *mSurface; virtual void newSurfaceCreated(); diff --git a/src/plugins/platforms/wayland/wayland.pro b/src/plugins/platforms/wayland/wayland.pro index 59454384c24..8d2d4b50afa 100644 --- a/src/plugins/platforms/wayland/wayland.pro +++ b/src/plugins/platforms/wayland/wayland.pro @@ -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 \ From 07fa0ccfc458c217ba1c071784e980f65f404f84 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 27 Apr 2011 14:21:54 +0200 Subject: [PATCH 02/27] Make QtQuick2 compile on QPA Moved the logic to set pixel size into the font engines to avoid making the platform plugin interface too complex, and added a function in QPA to make an isolated font engine based on font data. Currently none of the QPA back-ends supports it, but it compiles and spits out a warning if you try to create a QRawFont from data there. This isn't used in QtQuick2 anyway. Reviewed-by: Jiang Jiang --- src/corelib/global/qglobal.h | 3 +- src/gui/text/qfontengine_coretext.mm | 9 +++ src/gui/text/qfontengine_coretext_p.h | 2 + src/gui/text/qfontengine_ft.cpp | 35 +++++++++++ src/gui/text/qfontengine_ft_p.h | 7 ++- src/gui/text/qfontengine_p.h | 2 + src/gui/text/qfontengine_win.cpp | 17 ++++++ src/gui/text/qfontengine_win_p.h | 3 + src/gui/text/qfontengine_x11.cpp | 14 +++++ src/gui/text/qfontengine_x11_p.h | 2 + src/gui/text/qfontenginedirectwrite.cpp | 11 ++++ src/gui/text/qfontenginedirectwrite_p.h | 2 + src/gui/text/qplatformfontdatabase_qpa.cpp | 10 ++++ src/gui/text/qplatformfontdatabase_qpa.h | 2 + src/gui/text/qrawfont.cpp | 13 +++- src/gui/text/qrawfont_ft.cpp | 51 ---------------- src/gui/text/qrawfont_mac.cpp | 22 ------- src/gui/text/qrawfont_p.h | 4 -- src/gui/text/qrawfont_qpa.cpp | 69 ++++++++++++++++++++++ src/gui/text/qrawfont_win.cpp | 47 +-------------- src/gui/text/text.pri | 3 +- 21 files changed, 202 insertions(+), 126 deletions(-) create mode 100644 src/gui/text/qrawfont_qpa.cpp diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 9434eb29f7a..49f5f989fb2 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -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 diff --git a/src/gui/text/qfontengine_coretext.mm b/src/gui/text/qfontengine_coretext.mm index 20b37300fa7..ff440de4925 100644 --- a/src/gui/text/qfontengine_coretext.mm +++ b/src/gui/text/qfontengine_coretext.mm @@ -837,6 +837,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) diff --git a/src/gui/text/qfontengine_coretext_p.h b/src/gui/text/qfontengine_coretext_p.h index 1503c3f73fe..aa5f91a20cd 100644 --- a/src/gui/text/qfontengine_coretext_p.h +++ b/src/gui/text/qfontengine_coretext_p.h @@ -91,6 +91,8 @@ public: virtual qreal minLeftBearing() const; virtual QFixed emSquareSize() const; + virtual QFontEngine *cloneWithSize(qreal pixelSize) const; + private: friend class QRawFontPrivate; diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 8f2da9b7130..58bcca87b71 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -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 diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h index 8733498cb76..2c335f3cd3a 100644 --- a/src/gui/text/qfontengine_ft_p.h +++ b/src/gui/text/qfontengine_ft_p.h @@ -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() : _lock(QMutex::Recursive) {} ~QFreetypeFace() {} @@ -311,7 +311,12 @@ private: virtual HB_Error getPointInOutline(HB_Glyph glyph, int flags, hb_uint32 point, HB_Fixed *xpos, HB_Fixed *ypos, hb_uint32 *nPoints); + virtual void setDefaultHintStyle(HintStyle style); + + virtual QFontEngine *cloneWithSize(qreal pixelSize) const; + bool initFromFontEngine(const QFontEngineFT *fontEngine); + HintStyle defaultHintStyle() const { return default_hint_style; } protected: diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index 30277b5156f..b74371c7a8e 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -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; diff --git a/src/gui/text/qfontengine_win.cpp b/src/gui/text/qfontengine_win.cpp index 82d9da0be94..54d7ec29804 100644 --- a/src/gui/text/qfontengine_win.cpp +++ b/src/gui/text/qfontengine_win.cpp @@ -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) diff --git a/src/gui/text/qfontengine_win_p.h b/src/gui/text/qfontengine_win_p.h index 28d80008e47..114149d61f2 100644 --- a/src/gui/text/qfontengine_win_p.h +++ b/src/gui/text/qfontengine_win_p.h @@ -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; diff --git a/src/gui/text/qfontengine_x11.cpp b/src/gui/text/qfontengine_x11.cpp index 9f3f8d3d9d8..4260b85b117 100644 --- a/src/gui/text/qfontengine_x11.cpp +++ b/src/gui/text/qfontengine_x11.cpp @@ -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 diff --git a/src/gui/text/qfontengine_x11_p.h b/src/gui/text/qfontengine_x11_p.h index ad68fac1670..d7eb39daaa9 100644 --- a/src/gui/text/qfontengine_x11_p.h +++ b/src/gui/text/qfontengine_x11_p.h @@ -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 diff --git a/src/gui/text/qfontenginedirectwrite.cpp b/src/gui/text/qfontenginedirectwrite.cpp index f0a36448653..aab00c0db82 100644 --- a/src/gui/text/qfontenginedirectwrite.cpp +++ b/src/gui/text/qfontenginedirectwrite.cpp @@ -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 diff --git a/src/gui/text/qfontenginedirectwrite_p.h b/src/gui/text/qfontenginedirectwrite_p.h index c440a6ca65b..53a4b0a53d4 100644 --- a/src/gui/text/qfontenginedirectwrite_p.h +++ b/src/gui/text/qfontenginedirectwrite_p.h @@ -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; diff --git a/src/gui/text/qplatformfontdatabase_qpa.cpp b/src/gui/text/qplatformfontdatabase_qpa.cpp index 6fa25e7ea2c..82ec2793b98 100644 --- a/src/gui/text/qplatformfontdatabase_qpa.cpp +++ b/src/gui/text/qplatformfontdatabase_qpa.cpp @@ -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; +} + /*! */ diff --git a/src/gui/text/qplatformfontdatabase_qpa.h b/src/gui/text/qplatformfontdatabase_qpa.h index e0e4f04d892..046311f471d 100644 --- a/src/gui/text/qplatformfontdatabase_qpa.h +++ b/src/gui/text/qplatformfontdatabase_qpa.h @@ -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 diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp index 4a715c27cc2..6ac2677c024 100644 --- a/src/gui/text/qrawfont.cpp +++ b/src/gui/text/qrawfont.cpp @@ -579,8 +579,19 @@ QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writ */ void QRawFont::setPixelSize(int 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; } /*! diff --git a/src/gui/text/qrawfont_ft.cpp b/src/gui/text/qrawfont_ft.cpp index eefbd921180..23d47ebfb67 100644 --- a/src/gui/text/qrawfont_ft.cpp +++ b/src/gui/text/qrawfont_ft.cpp @@ -90,32 +90,6 @@ public: return init(faceId, true, Format_None, fontData); } - - bool initFromFontEngine(QFontEngine *oldFontEngine) - { - QFontEngineFT *fe = static_cast(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(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 diff --git a/src/gui/text/qrawfont_mac.cpp b/src/gui/text/qrawfont_mac.cpp index 56005c61f58..1ed4185a5d1 100644 --- a/src/gui/text/qrawfont_mac.cpp +++ b/src/gui/text/qrawfont_mac.cpp @@ -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(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 diff --git a/src/gui/text/qrawfont_p.h b/src/gui/text/qrawfont_p.h index 18f3e7d0069..6c84be2d970 100644 --- a/src/gui/text/qrawfont_p.h +++ b/src/gui/text/qrawfont_p.h @@ -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 index 00000000000..103619c37d0 --- /dev/null +++ b/src/gui/text/qrawfont_qpa.cpp @@ -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 + +#if !defined(QT_NO_RAWFONT) + +#include "qrawfont_p.h" +#include +#include + +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 diff --git a/src/gui/text/qrawfont_win.cpp b/src/gui/text/qrawfont_win.cpp index fb5c6f46b64..d8acf57431a 100644 --- a/src/gui/text/qrawfont_win.cpp +++ b/src/gui/text/qrawfont_win.cpp @@ -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(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(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 diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri index df9398ce597..2e0c6dea5d9 100644 --- a/src/gui/text/text.pri +++ b/src/gui/text/text.pri @@ -136,7 +136,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 From 514641bed524337acbad3d386b913b0c795f4c47 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Thu, 28 Apr 2011 15:07:51 +0200 Subject: [PATCH 03/27] QT += declarative implies += opengl too, so hardcode it to make stuff work --- mkspecs/features/qt.prf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index 21fdd38e702..e30a2fdd270 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -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..depends variable QT = $$resolve_depends($$QT, "QT.") + QT_DEPENDS= for(QTLIB, $$list($$lower($$unique(QT)))) { From 064d54b2b08e6b897689cf2f938ce50c7bc6ee0a Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 22 Apr 2011 11:20:37 +0200 Subject: [PATCH 04/27] doc: Simplify language in QGlyphs docs Mainly to trigger CI. Reviewed-by: TrustMe (cherry picked from commit 1a1683c2d57debbb3e7f3ae6001eb2c8685dca02) --- src/gui/text/qglyphs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/text/qglyphs.cpp b/src/gui/text/qglyphs.cpp index b8a418de44d..8b92b732754 100644 --- a/src/gui/text/qglyphs.cpp +++ b/src/gui/text/qglyphs.cpp @@ -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. From 544babaaf9d84bc52de1b8e4a7e5e55043125eb7 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 21 Apr 2011 11:50:11 +0200 Subject: [PATCH 05/27] doc: Minor cleanup in QGlyphs docs Just a minor clean-up in the QGlyphs docs. Mainly to try to trigger CI. Reviewed-by: TrustMe (cherry picked from commit 774b5b8c6a627fc90fb7382bc907db5d2e8193bf) --- src/gui/text/qglyphs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/text/qglyphs.cpp b/src/gui/text/qglyphs.cpp index 8b92b732754..cfea6ece93f 100644 --- a/src/gui/text/qglyphs.cpp +++ b/src/gui/text/qglyphs.cpp @@ -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 From b2db259a32576ac3c6f03f7834920157ea827567 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 28 Apr 2011 15:05:08 +0200 Subject: [PATCH 06/27] Fix crash in raster on X11 when text contains unsupported characters We would assume the font engine was a FT engine and do a static cast here, which would cause a crash if the box engine was in use instead. Task-number: QTBUG-17443 Reviewed-by: Samuel (cherry picked from commit c9c54682bcd23598ac7a8db3b10e9f18c978e268) --- src/gui/painting/qtextureglyphcache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp index 53f025f8196..e9e56a2d585 100644 --- a/src/gui/painting/qtextureglyphcache.cpp +++ b/src/gui/painting/qtextureglyphcache.cpp @@ -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) { From 8c90fb22c4032198870d5cc349dc8a09abcb0728 Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Fri, 29 Apr 2011 09:58:30 +0200 Subject: [PATCH 07/27] Fix glyph position issue with fallback fonts Task-number: QTBUG-18933 Reviewed-by: Eskil (cherry picked from commit 18fcbf7ae41504324cd453ba9b9655f3e94f6495) --- src/gui/text/qtextlayout.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 93f71d3dbb6..fe0c53a480e 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -2317,6 +2317,9 @@ QList 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; From e99aa8b20c25812746c2e2ce55296d678724fa7a Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 29 Apr 2011 10:07:12 +0200 Subject: [PATCH 08/27] Make sure QFont's resolve mask is copied on compilers with C++0x support The QFont consists of a d pointer and a resolve mask, and they should both be copied in the assignment operator. Task-number: QTBUG-18921 Done-by: Friedemann Kleint (cherry picked from commit cb5e526c6023237c36aac3446a0a18288f39f3a9) --- src/gui/text/qfont.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/text/qfont.h b/src/gui/text/qfont.h index 8dbc7468130..0c7b6f8de80 100644 --- a/src/gui/text/qfont.h +++ b/src/gui/text/qfont.h @@ -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 From 028aa80d700ad8d6799202f1fa1beb919e6ee531 Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Mon, 18 Apr 2011 11:21:16 +0200 Subject: [PATCH 09/27] Disable tst_QPixmap::onlyNullPixmapsOutsideGuiThread on Mac No need to check it anymore after the switch to raster engine. Reviewed-by: Eskil (cherry picked from commit e004701bd7ba9e4a7cd5ac1bf784829feae16cae) --- tests/auto/qpixmap/tst_qpixmap.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/qpixmap/tst_qpixmap.cpp b/tests/auto/qpixmap/tst_qpixmap.cpp index 4d032e8f3c7..4ba51de7e56 100644 --- a/tests/auto/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/qpixmap/tst_qpixmap.cpp @@ -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() From 0f7cba14f612885151a95c590b23c5fe25efdd05 Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Wed, 15 Dec 2010 15:11:45 +0100 Subject: [PATCH 10/27] Support visual cursor movement for BIDI text Bidi input can in some contexts be more intuitive if the cursor works in visual way: pressing left arrow key always make cursor move one character to the left regardless the language of text, pressing right arrow key always make cursor move to the right. It is also the behavior of Mac OS X. Based on the above reason and requests from Symbian we implemented this support for visual movement in BIDI text. 3 public properties are added to QTextDocument, QTextLayout and QLineEdit respectively: - QTextDocument::defaultCursorMoveStyle can be used to control the cursor behavior in all widgets based on QTextDocument, like QTextEdit, QPlainTextEdit, etc. When set to QTextCursor:: Visual, it will enable visual movement for all the cursors in the corresponding text edit. Default is QTextCursor::Logical. - QTextLayout::cursorMoveStyle is used for low-level cursor manipulation. When set to Visual, it will enable visual movement behavior for all the cursor related methods, including cursorToX, xToCursor and drawCursor. Default is Logical. - QLineEdit::cursorMoveStyle is used to control cursor movement behavior in QLineEdit. Default is Logical.: Task-number: QTBUG-13859 Reviewed-by: Eskil (cherry picked from commit c480dd641f5d22d1ee72cb27bf39e24c6df65658) --- src/gui/text/qtextcursor.cpp | 42 +- src/gui/text/qtextcursor.h | 4 + src/gui/text/qtextdocument.cpp | 23 ++ src/gui/text/qtextdocument.h | 5 +- src/gui/text/qtextdocument_p.cpp | 15 + src/gui/text/qtextdocument_p.h | 4 + src/gui/text/qtextengine.cpp | 297 ++++++++++++++ src/gui/text/qtextengine_p.h | 60 +++ src/gui/text/qtextlayout.cpp | 394 +++++++------------ src/gui/text/qtextlayout.h | 6 + src/gui/widgets/qlinecontrol.cpp | 9 +- src/gui/widgets/qlinecontrol_p.h | 8 +- src/gui/widgets/qlineedit.cpp | 28 ++ src/gui/widgets/qlineedit.h | 4 + tests/auto/qcomplextext/tst_qcomplextext.cpp | 87 ++++ tests/auto/qlineedit/tst_qlineedit.cpp | 136 +++++++ tests/auto/qtextedit/tst_qtextedit.cpp | 149 ++++++- 17 files changed, 998 insertions(+), 273 deletions(-) diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp index 6ddfdb00e1c..4f6857a201b 100644 --- a/src/gui/text/qtextcursor.cpp +++ b/src/gui/text/qtextcursor.cpp @@ -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 diff --git a/src/gui/text/qtextcursor.h b/src/gui/text/qtextcursor.h index 4eaeb41ee9f..30f827298b4 100644 --- a/src/gui/text/qtextcursor.h +++ b/src/gui/text/qtextcursor.h @@ -86,6 +86,10 @@ public: MoveAnchor, KeepAnchor }; + enum MoveStyle { + Logical, + Visual, + }; void setPosition(int pos, MoveMode mode = MoveAnchor); int position() const; diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 6dbd755d938..36f3c6cb4f2 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -585,6 +585,29 @@ void QTextDocument::setDefaultTextOption(const QTextOption &option) d->lout->documentChanged(0, 0, d->length()); } +/*! + \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) diff --git a/src/gui/text/qtextdocument.h b/src/gui/text/qtextdocument.h index f87ccc91e8b..e515b36cc07 100644 --- a/src/gui/text/qtextdocument.h +++ b/src/gui/text/qtextdocument.h @@ -46,6 +46,7 @@ #include #include #include +#include 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(); diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp index a997720c125..779b1fff350 100644 --- a/src/gui/text/qtextdocument_p.cpp +++ b/src/gui/text/qtextdocument_p.cpp @@ -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(); diff --git a/src/gui/text/qtextdocument_p.h b/src/gui/text/qtextdocument_p.h index b464f2ee404..6563920c954 100644 --- a/src/gui/text/qtextdocument_p.h +++ b/src/gui/text/qtextdocument_p.h @@ -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 diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 08d0eca7aca..0e649f0c2d0 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1304,6 +1304,7 @@ static void init(QTextEngine *e) e->ignoreBidi = false; e->cacheGlyphs = false; e->forceJustification = false; + e->visualMovement = false; e->layoutData = 0; @@ -2737,6 +2738,180 @@ 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::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)/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 &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 insertionPoints; + insertionPointsForLine(lineNum, insertionPoints); + + if (insertionPoints.size() > 0) + return insertionPoints.last(); + return 0; +} + +int QTextEngine::beginningOfLine(int lineNum) +{ + QVector 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 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 +3016,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 diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index 366c5c32071..c476485c1dd 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -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 &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 visualOrder; + QVarLengthArray levels; + + const QTextLayout::FormatRange *selection; +}; Q_DECLARE_OPERATORS_FOR_FLAGS(QTextEngine::ShaperFlags) diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index fe0c53a480e..9fc4e7f470b 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -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 @@ -595,6 +578,30 @@ bool QTextLayout::cacheEnabled() const return d->cacheGlyphs; } +/*! + 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. @@ -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 visualOrder; - QVarLengthArray 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) { @@ -1382,18 +1214,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 +1225,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 +1343,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) @@ -2635,9 +2466,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; @@ -2723,21 +2555,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; @@ -2756,6 +2596,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(); @@ -2773,7 +2615,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 visualOrder(nItems); @@ -2782,6 +2624,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; @@ -2798,8 +2641,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 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]; @@ -2829,6 +2677,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const if (pos + item_width < x) { pos += item_width; + nchars += end; continue; } // qDebug(" inside run"); @@ -2873,27 +2722,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; diff --git a/src/gui/text/qtextlayout.h b/src/gui/text/qtextlayout.h index 9dd8ebd28fa..6aa81f9e7c0 100644 --- a/src/gui/text/qtextlayout.h +++ b/src/gui/text/qtextlayout.h @@ -50,6 +50,7 @@ #include #include #include +#include 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 &selections = QVector(), const QRectF &clip = QRectF()) const; diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp index 289faa9b027..eb4e142328e 100644 --- a/src/gui/widgets/qlinecontrol.cpp +++ b/src/gui/widgets/qlinecontrol.cpp @@ -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) diff --git a/src/gui/widgets/qlinecontrol_p.h b/src/gui/widgets/qlinecontrol_p.h index 3c505c86965..0042f17261b 100644 --- a/src/gui/widgets/qlinecontrol_p.h +++ b/src/gui/widgets/qlinecontrol_p.h @@ -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); } diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp index 07bd2733f22..43c3f52d2bc 100644 --- a/src/gui/widgets/qlineedit.cpp +++ b/src/gui/widgets/qlineedit.cpp @@ -1111,6 +1111,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 diff --git a/src/gui/widgets/qlineedit.h b/src/gui/widgets/qlineedit.h index 636cee7bb03..73a736c690c 100644 --- a/src/gui/widgets/qlineedit.h +++ b/src/gui/widgets/qlineedit.h @@ -43,6 +43,7 @@ #define QLINEEDIT_H #include +#include #include #include @@ -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; diff --git a/tests/auto/qcomplextext/tst_qcomplextext.cpp b/tests/auto/qcomplextext/tst_qcomplextext.cpp index 3d8e29057d8..04943c5ceb4 100644 --- a/tests/auto/qcomplextext/tst_qcomplextext.cpp +++ b/tests/auto/qcomplextext/tst_qcomplextext.cpp @@ -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,89 @@ void tst_QComplexText::bidiCursor_qtbug2795() QVERIFY(x1 == x2); } +void tst_QComplexText::bidiCursorMovement_data() +{ + QTest::addColumn("logical"); + QTest::addColumn("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); + 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"); diff --git a/tests/auto/qlineedit/tst_qlineedit.cpp b/tests/auto/qlineedit/tst_qlineedit.cpp index 9176174cd88..f45481ca8ac 100644 --- a/tests/auto/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/qlineedit/tst_qlineedit.cpp @@ -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("logical"); + QTest::addColumn("basicDir"); + QTest::addColumn("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() << 0 << 1 << 2 << 3); + QTest::newRow("Hebrew text after Latin text") + << QString::fromUtf8("abc\327\220\327\221\327\222") + << (int) QChar::DirL + << (QList() << 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() << 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() << 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() << 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() << 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() << 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" diff --git a/tests/auto/qtextedit/tst_qtextedit.cpp b/tests/auto/qtextedit/tst_qtextedit.cpp index 9ca17b9f5f5..5a645937d7a 100644 --- a/tests/auto/qtextedit/tst_qtextedit.cpp +++ b/tests/auto/qtextedit/tst_qtextedit.cpp @@ -42,7 +42,6 @@ #include - #include #include #include @@ -69,6 +68,7 @@ typedef QList pairListType; Q_DECLARE_METATYPE(pairListType); Q_DECLARE_METATYPE(keyPairType); Q_DECLARE_METATYPE(QList); +Q_DECLARE_METATYPE(QList); #ifdef Q_WS_MAC #include @@ -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("logical"); + QTest::addColumn("basicDir"); + QTest::addColumn >("positionList"); + + QTest::newRow("Latin text") + << QString::fromUtf8("abc") + << (int) QChar::DirL + << (QList() << 0 << 1 << 2 << 3); + QTest::newRow("Hebrew text, one item") + << QString::fromUtf8("\327\220\327\221\327\222") + << (int) QChar::DirR + << (QList() << 0 << 1 << 2 << 3); + QTest::newRow("Hebrew text after Latin text") + << QString::fromUtf8("abc\327\220\327\221\327\222") + << (int) QChar::DirL + << (QList() << 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() << 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() << 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() << 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() << 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() << 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, 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" From a7b6f4c8a532df62ba053f30f23dfaecc148351a Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Mon, 18 Apr 2011 17:08:30 +0200 Subject: [PATCH 11/27] Turn on HarfBuzz support for Mac/Cocoa It's possible to enable HarfBuzz text layout on Mac by either: - Set QT_ENABLE_HARFBUZZ environment variable when running a Qt app. - configure with -harfbuzz to build Qt, then HarfBuzz support will be turned on by default. HarfBuzz will only be used when the font explicitly requested is supported by HarfBuzz (aka. TrueType/OpenType font), other fonts (AAT fonts) will still be handled by Core Text. Using HarfBuzz for text layout will hopefully solve most tricky complex text shaping bugs on Mac. Task-number: QTBUG-17728 Reviewed-by: Eskil --- configure | 16 +++++++++++++++- src/gui/text/qtextengine.cpp | 34 +++++++++++++++++++++++++++++++++- src/gui/text/text.pri | 3 +++ 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 60e1ec12163..b0cafbcab7a 100755 --- 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 ......... Build Qt using Apple provided 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" diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 0e649f0c2d0..dab4bb75ec7 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -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(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 diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri index 2e0c6dea5d9..e5d57d069d5 100644 --- a/src/gui/text/text.pri +++ b/src/gui/text/text.pri @@ -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 { From 0d32728af23cd307c84d8c98dcd6d6d78908e5bf Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Tue, 19 Apr 2011 12:48:19 +0200 Subject: [PATCH 12/27] Don't transform glyph positions for Core Graphics paint engine Since it already transformed text positions based on transform matrix on QPainter. Reviewed-by: Eskil (cherry picked from commit b86c9120710bf1481df5f6541618169a82fd65b8) --- src/gui/painting/qpainter.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 9fafba5f4ff..b7686fa7feb 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -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 Date: Wed, 20 Apr 2011 10:19:02 +0200 Subject: [PATCH 13/27] Remove extra comma at the end of enum list It fails compilerwarnings test. Reviewed-by: TrustMe (cherry picked from commit 1e847c00dcf4948b8892d0a552576e1d3ea554b9) --- src/gui/text/qtextcursor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/text/qtextcursor.h b/src/gui/text/qtextcursor.h index 30f827298b4..9e4c0b82df4 100644 --- a/src/gui/text/qtextcursor.h +++ b/src/gui/text/qtextcursor.h @@ -88,7 +88,7 @@ public: }; enum MoveStyle { Logical, - Visual, + Visual }; void setPosition(int pos, MoveMode mode = MoveAnchor); From 044e7602ae72889f363d688dbe0d73cec5f0636a Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Tue, 19 Apr 2011 14:40:19 +0200 Subject: [PATCH 14/27] Take leading space width into account for painting and selection When painting horizontally centered RTL text and selection with trailing spaces, we need to take that space width into account because line.textAdvance doesn't include it. Task-number: QTBUG-18612 Reviewed-by: Eskil (cherry picked from commit 224226727f07e8940e0d3131fe7587b11cc4a6ca) --- src/gui/text/qtextengine.cpp | 4 +++- src/gui/text/qtextlayout.cpp | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index dab4bb75ec7..ce012a818fc 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -2777,12 +2777,14 @@ QFixed QTextEngine::alignLine(const QScriptLine &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)/2; + x = (line.width - (line.textAdvance + leadingSpaceWidth(line)))/2; } return x; } diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 9fc4e7f470b..cb5ba0e6725 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -1060,6 +1060,7 @@ void QTextLayout::draw(QPainter *p, const QPointF &pos, const QVectorleadingSpaceWidth(sl).toReal(), 0); bool isLastLineInBlock = (line == d->lines.size()-1); int sl_length = sl.length + (isLastLineInBlock? 1 : 0); // the infamous newline From d64460fffb488eb2e7b90df58d3891338bad7948 Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Wed, 27 Apr 2011 08:47:46 +0200 Subject: [PATCH 15/27] Make sure layoutData exist before checking for string direction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise accessing that through QTextEngine::alignLine may cause crash. Reviewed-by: Samuel Rødal (cherry picked from commit dcdb62c3d1a76d951c4b65bc1b1bd930e2ad14ec) --- src/gui/text/qtextengine.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index ce012a818fc..cc150c59650 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1598,6 +1598,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; From bbbfc9b0eb373054aa4df7928c6472acc8f49c81 Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Wed, 27 Apr 2011 11:39:09 +0200 Subject: [PATCH 16/27] Another ugly hack to make bidi cursor work with Core Text If the text is wrapped with LRE/LRO/RLE/RLO override/embed marks, Core Text in Mac OS X 10.5 doesn't produce an empty glyph at the beginning of the glyphs (while it does in Mac OS X 10.6), thus we need to prepend an empty glyph here, otherwise cursor position calculation will consider the first two characters as a ligature of the same glyph. Reviewed-by: Eskil (cherry picked from commit a36ac6c34bafa801c2c30d76f59e4a3594efc4d5) --- src/gui/text/qfontengine_coretext.mm | 27 +++++++++++++++++--- tests/auto/qcomplextext/tst_qcomplextext.cpp | 1 + 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/gui/text/qfontengine_coretext.mm b/src/gui/text/qfontengine_coretext.mm index ff440de4925..c4d2d47f595 100644 --- a/src/gui/text/qfontengine_coretext.mm +++ b/src/gui/text/qfontengine_coretext.mm @@ -180,6 +180,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 +221,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) @@ -271,9 +292,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 +329,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; diff --git a/tests/auto/qcomplextext/tst_qcomplextext.cpp b/tests/auto/qcomplextext/tst_qcomplextext.cpp index 04943c5ceb4..58b31b4aa44 100644 --- a/tests/auto/qcomplextext/tst_qcomplextext.cpp +++ b/tests/auto/qcomplextext/tst_qcomplextext.cpp @@ -214,6 +214,7 @@ void tst_QComplexText::bidiCursorMovement() 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; From 774527dd1e85da6ab91cba9b0e5897ba90f4c828 Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Wed, 27 Apr 2011 16:05:09 +0200 Subject: [PATCH 17/27] Use maximum ascent/descent/leading from fallback fonts in shaping When shaping a QScriptItem with a multi font engine, currently we only take the ascent/descent/leading from the primary (first) font engine in that multi font engine, however, subsequent engines used during shaping may have larger ascent/descent/leading, disregarding them may cause clipping issues in some cases. It's fixed by checking each font engine used in the shaping process and take the maximum value instead of the first one. On ATSUI we merely make it compile. Task-number: QTBUG-16719 Reviewed-by: Eskil (cherry picked from commit c501403cb5a0c9ec21b00e0c2f640ae85566e0cf) --- src/gui/text/qfontengine_coretext.mm | 13 ++++++++++--- src/gui/text/qfontengine_coretext_p.h | 3 ++- src/gui/text/qfontengine_mac.mm | 2 +- src/gui/text/qfontengine_mac_p.h | 2 +- src/gui/text/qtextengine.cpp | 4 ++++ src/gui/text/qtextengine_mac.cpp | 4 ++-- 6 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/gui/text/qfontengine_coretext.mm b/src/gui/text/qfontengine_coretext.mm index c4d2d47f595..d4df2183ed8 100644 --- a/src/gui/text/qfontengine_coretext.mm +++ b/src/gui/text/qfontengine_coretext.mm @@ -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 cfstring = CFStringCreateWithCharactersNoCopy(0, reinterpret_cast(str), @@ -254,7 +256,12 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay if (!runAttribs) runAttribs = attributeDict; CTFontRef runFont = static_cast(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--; diff --git a/src/gui/text/qfontengine_coretext_p.h b/src/gui/text/qfontengine_coretext_p.h index aa5f91a20cd..bb80a9b2f3f 100644 --- a/src/gui/text/qfontengine_coretext_p.h +++ b/src/gui/text/qfontengine_coretext_p.h @@ -120,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: diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm index 673a7c86fa4..9f094ad7d12 100644 --- a/src/gui/text/qfontengine_mac.mm +++ b/src/gui/text/qfontengine_mac.mm @@ -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; diff --git a/src/gui/text/qfontengine_mac_p.h b/src/gui/text/qfontengine_mac_p.h index 385fa83fe9b..292ea98d9af 100644 --- a/src/gui/text/qfontengine_mac_p.h +++ b/src/gui/text/qfontengine_mac_p.h @@ -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; diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index cc150c59650..ff27bc673f0 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1274,6 +1274,10 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const actualFontEngine = static_cast(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(); diff --git a/src/gui/text/qtextengine_mac.cpp b/src/gui/text/qtextengine_mac.cpp index 97e8c5b0f8a..2c6e579b454 100644 --- a/src/gui/text/qtextengine_mac.cpp +++ b/src/gui/text/qtextengine_mac.cpp @@ -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) { From f26c4ba80dd927a705f5af03b915dcf1af8f351a Mon Sep 17 00:00:00 2001 From: Dmitry Zelenkovsky Date: Thu, 28 Apr 2011 11:49:13 +0200 Subject: [PATCH 18/27] Support more items for QTextCharFormat::VerticalAlignment enum for custom text objects. * QTextCharFormat::AlignNormal - support text format descent, place text object bottom on (baseline - descent). * QTextCharFormat::AlignBottom - place text object bottom on baseline. * QTextCharFormat::AlignTop - Still not supported. * Any other vertical alignment is mapped QTextCharFormat::AlignBottom. Add new enum AlignBaseline for custom inline objects to take into account font baseline. Merge-request: 2578 Reviewed-by: Eskil Abrahamsen Blomfeldt (cherry picked from commit ee9455ed2a83084692d969c398ecb91bcd4fc33a) --- src/gui/text/qtextdocumentlayout.cpp | 13 +++++++++++-- src/gui/text/qtextformat.h | 3 ++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp index ce157be2544..130f0126391 100644 --- a/src/gui/text/qtextdocumentlayout.cpp +++ b/src/gui/text/qtextdocumentlayout.cpp @@ -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); } diff --git a/src/gui/text/qtextformat.h b/src/gui/text/qtextformat.h index ff28eaa1b29..4f4752a26ad 100644 --- a/src/gui/text/qtextformat.h +++ b/src/gui/text/qtextformat.h @@ -378,7 +378,8 @@ public: AlignSubScript, AlignMiddle, AlignTop, - AlignBottom + AlignBottom, + AlignBaseline }; enum UnderlineStyle { // keep in sync with Qt::PenStyle! NoUnderline, From ac4af55972291db96cc6bfa322dc7d35b67f7775 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 2 May 2011 10:06:44 +0200 Subject: [PATCH 19/27] Make pixel size a qreal in QRawFont The pixel size in the font engines is already a floating point value. For maximum flexibility, we should expose this in the public API. Task-number: QTBUG-18817 Reviewed-by: Jiang Jiang (cherry picked from commit ac9e63b58533a3215106ed9da82cff3a3e3dda3a) --- src/gui/text/qrawfont.cpp | 6 +++--- src/gui/text/qrawfont.h | 4 ++-- tests/auto/qrawfont/tst_qrawfont.cpp | 32 ++++++++++++++-------------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp index 6ac2677c024..1bce909b0e4 100644 --- a/src/gui/text/qrawfont.cpp +++ b/src/gui/text/qrawfont.cpp @@ -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,7 +577,7 @@ 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; diff --git a/src/gui/text/qrawfont.h b/src/gui/text/qrawfont.h index 96dc838ede0..56aeefc8ffc 100644 --- a/src/gui/text/qrawfont.h +++ b/src/gui/text/qrawfont.h @@ -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; diff --git a/tests/auto/qrawfont/tst_qrawfont.cpp b/tests/auto/qrawfont/tst_qrawfont.cpp index 3aa4006b68b..4b42c74bb72 100644 --- a/tests/auto/qrawfont/tst_qrawfont.cpp +++ b/tests/auto/qrawfont/tst_qrawfont.cpp @@ -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("weight"); QTest::addColumn("hintingPreference"); QTest::addColumn("unitsPerEm"); - QTest::addColumn("pixelSize"); + QTest::addColumn("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 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); } From e443d8850105549eb1d72f54d3bf0d3d72cf90c2 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 3 May 2011 15:06:13 +0200 Subject: [PATCH 20/27] Support gamma correction of text on GL If the SRGB framebuffer extension in GL is available, we can support gamma correction of text with a gamma of 2.1. On Mac this is sufficient for gamma correcting subpixel antialiased text. Gray antialiasing should not be gamma corrected on Mac. On Windows, the user can potentially set the gamma value to anything between 1.0 and 2.2 (or something like that). We support anything that resembles 1.0 closely enough by pushing the text out without any correction (like before). We also support anything that resembles 2.1 (the gamma hardcoded in GL's SRGB extension) by turning on the extension before blending the text. In between the two, we'll use gray antialiasing to avoid differing too much from the raster engine (which is our reference in this.) For gray antialiasing on Windows, we use a constant gamma of 2.3 which has been determined by experimentation. Since this is close enough to 2.1 we do gamma correction with SRGB extension. The distance limit of 0.2 is determined by some experimentation. Reviewed-by: Samuel (cherry picked from commit 79ba7cceca5e4029876ace2121edd25b08ae14ce) --- src/gui/kernel/qapplication_win.cpp | 13 +++++++- src/gui/painting/qdrawhelper.cpp | 10 ++---- .../qpaintengineex_opengl2.cpp | 31 +++++++++++++++++-- src/opengl/qgl.cpp | 7 +++++ src/opengl/qgl_p.h | 3 +- src/opengl/qglextensions_p.h | 8 +++++ 6 files changed, 60 insertions(+), 12 deletions(-) diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index 0a033972510..1a490c9979b 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -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(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() { diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 5e75e4a8844..3553b6064dd 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -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 diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 18c684ff1b3..673f614c0d1 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -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) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 7ce35f8d1c8..4cb976f3c2e 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -5521,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; } diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 6a503fab900..46683c742ea 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -288,7 +288,8 @@ public: PVRTCTextureCompression = 0x00020000, FragmentShader = 0x00040000, ElementIndexUint = 0x00080000, - Depth24 = 0x00100000 + Depth24 = 0x00100000, + SRGBFrameBuffer = 0x00200000 }; Q_DECLARE_FLAGS(Extensions, Extension) diff --git a/src/opengl/qglextensions_p.h b/src/opengl/qglextensions_p.h index 529c7a1b4e3..ac80ce8b968 100644 --- a/src/opengl/qglextensions_p.h +++ b/src/opengl/qglextensions_p.h @@ -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 From 64fa65df74e25f97bacc63db2019eaf7e08caff2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Wed, 20 Apr 2011 09:17:13 +0200 Subject: [PATCH 21/27] Lighthouse: Fix virtual desktopwidget (cherry picked from commit 69c759f5b84c2f6a44377e5f72cfe9d5bf7344c6) --- src/gui/kernel/qdesktopwidget_qpa.cpp | 12 ++++-------- src/gui/kernel/qdesktopwidget_qpa_p.h | 1 - 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/gui/kernel/qdesktopwidget_qpa.cpp b/src/gui/kernel/qdesktopwidget_qpa.cpp index cff05f58368..6257a8bc06c 100644 --- a/src/gui/kernel/qdesktopwidget_qpa.cpp +++ b/src/gui/kernel/qdesktopwidget_qpa.cpp @@ -51,6 +51,8 @@ QT_USE_NAMESPACE void QDesktopWidgetPrivate::updateScreenList() { + Q_Q(QDesktopWidget); + QList 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); diff --git a/src/gui/kernel/qdesktopwidget_qpa_p.h b/src/gui/kernel/qdesktopwidget_qpa_p.h index abee8a101e3..d6ed686a3fb 100644 --- a/src/gui/kernel/qdesktopwidget_qpa_p.h +++ b/src/gui/kernel/qdesktopwidget_qpa_p.h @@ -76,7 +76,6 @@ public: void updateScreenList(); QList screens; - QDesktopScreenWidget virtualScreen; }; #endif // QDESKTOPWIDGET_QPA_P_H From 95bbf56ff076d003eddf7a7f9f1030d2c683ca01 Mon Sep 17 00:00:00 2001 From: con Date: Tue, 19 Apr 2011 16:15:09 +0200 Subject: [PATCH 22/27] Support GL ES 2 with uikit. For GL ES 2 teach the paint device about the fact that it is doing rendering backed by a framebuffer object, not a system framebuffer (which doesn't exist). (cherry picked from commit 3b437a7706efbaaafdc4861393cbe21354cf4ee2) --- .../platforms/uikit/quikiteventloop.mm | 7 +- .../platforms/uikit/quikitintegration.mm | 2 +- src/plugins/platforms/uikit/quikitscreen.mm | 4 +- src/plugins/platforms/uikit/quikitwindow.h | 11 ++- src/plugins/platforms/uikit/quikitwindow.mm | 71 ++++++++++++------- .../platforms/uikit/quikitwindowsurface.mm | 43 ++++++++++- 6 files changed, 98 insertions(+), 40 deletions(-) diff --git a/src/plugins/platforms/uikit/quikiteventloop.mm b/src/plugins/platforms/uikit/quikiteventloop.mm index 8d2603c60df..2b9728cea5a 100644 --- a/src/plugins/platforms/uikit/quikiteventloop.mm +++ b/src/plugins/platforms/uikit/quikiteventloop.mm @@ -69,13 +69,8 @@ - (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(widget->platformWindow()); platformWindow->ensureNativeWindow(); } diff --git a/src/plugins/platforms/uikit/quikitintegration.mm b/src/plugins/platforms/uikit/quikitintegration.mm index d4b4192b608..3a432d11a46 100644 --- a/src/plugins/platforms/uikit/quikitintegration.mm +++ b/src/plugins/platforms/uikit/quikitintegration.mm @@ -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 diff --git a/src/plugins/platforms/uikit/quikitscreen.mm b/src/plugins/platforms/uikit/quikitscreen.mm index 21494c9385f..78389f21fde 100644 --- a/src/plugins/platforms/uikit/quikitscreen.mm +++ b/src/plugins/platforms/uikit/quikitscreen.mm @@ -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; diff --git a/src/plugins/platforms/uikit/quikitwindow.h b/src/plugins/platforms/uikit/quikitwindow.h index 9e73754fc8c..5c6496a2ce0 100644 --- a/src/plugins/platforms/uikit/quikitwindow.h +++ b/src/plugins/platforms/uikit/quikitwindow.h @@ -47,6 +47,8 @@ #import #import #import +#import +#import #import @interface EAGLView : UIView @@ -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 ---------- @@ -90,6 +95,10 @@ @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(); diff --git a/src/plugins/platforms/uikit/quikitwindow.mm b/src/plugins/platforms/uikit/quikitwindow.mm index 52d184636e5..1f57baad690 100644 --- a/src/plugins/platforms/uikit/quikitwindow.mm +++ b/src/plugins/platforms/uikit/quikitwindow.mm @@ -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); + glGenFramebuffers(1, &mFramebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, 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); + 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); - 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); + 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 (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) - NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)); + 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]; diff --git a/src/plugins/platforms/uikit/quikitwindowsurface.mm b/src/plugins/platforms/uikit/quikitwindowsurface.mm index bb7dcd794b7..8caa15fbbe9 100644 --- a/src/plugins/platforms/uikit/quikitwindowsurface.mm +++ b/src/plugins/platforms/uikit/quikitwindowsurface.mm @@ -47,27 +47,64 @@ #include +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(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) From 1e3e3980da02ae32f71e845e13c877e9ca1ac9af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 21 Apr 2011 21:14:43 -0400 Subject: [PATCH 23/27] wayland: Track wayland changes Pass version number when creating proxies, use wl_ prefix when looking up interfaces and drop wl_egl_display. (cherry picked from commit c2adf9395214d711a3a40516c6c2afa64b3b4ca3) --- .../wayland_egl/qwaylandeglintegration.cpp | 8 +------- .../wayland_egl/qwaylandeglintegration.h | 3 --- .../wayland_egl/qwaylandeglwindow.cpp | 2 +- .../platforms/wayland/qwaylanddisplay.cpp | 18 +++++++++--------- .../platforms/wayland/qwaylandinputdevice.cpp | 2 +- 5 files changed, 12 insertions(+), 21 deletions(-) diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp index 39e7be5ac61..ddd17636c1d 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp @@ -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()); diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h index bf4c3fe45cb..3a26f97b320 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h @@ -65,9 +65,6 @@ private: struct wl_display *mWaylandDisplay; EGLDisplay mEglDisplay; - struct wl_egl_display *mNativeEglDisplay; - - }; #endif // QWAYLANDEGLINTEGRATION_H diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp index d7cf0a55e1c..cf52f39d15f 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp @@ -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(mWaylandEglWindow)); EGLSurface surface = eglCreateWindowSurface(mEglIntegration->eglDisplay(),mGLContext->eglConfig(),window,NULL); diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp index 1c56561904d..bd50e6454a3 100644 --- a/src/plugins/platforms/wayland/qwaylanddisplay.cpp +++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp @@ -252,17 +252,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); diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp index 2d7df1d6135..f9e7c958611 100644 --- a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp +++ b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp @@ -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) From 03aafc9d48300ba75da4bf4a8710783bc63ad53c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Tue, 3 May 2011 08:57:49 +0200 Subject: [PATCH 24/27] Fix Wayland plugin so it works with the wayland bind api This is mostly for the xcomposite api, but also we needed to readEvents after doing a connect (cherry picked from commit 16c054125949b8f8ceec9626156d8790254a63a2) --- .../qwaylandxcompositeeglintegration.cpp | 4 +- .../qwaylandxcompositeglxintegration.cpp | 4 +- .../wayland-xcomposite-client-protocol.h | 54 ++++++------------- .../wayland-xcomposite-protocol.c | 10 ++-- .../platforms/wayland/qwaylanddisplay.cpp | 4 +- 5 files changed, 26 insertions(+), 50 deletions(-) diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp index 95b4112cdcd..7537b52d598 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp @@ -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(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); } diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp index 43c0135c6e7..5cb6ef336bc 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp @@ -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(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); } diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-client-protocol.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-client-protocol.h index 72376e1dcb1..85da7a95212 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-client-protocol.h +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-client-protocol.h @@ -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; diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-protocol.c b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-protocol.c index 5c966fda46f..a1b63254cbc 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-protocol.c +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-protocol.c @@ -43,17 +43,17 @@ #include #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, }; diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp index bd50e6454a3..876b46ae9a7 100644 --- a/src/plugins/platforms/wayland/qwaylanddisplay.cpp +++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp @@ -126,6 +126,7 @@ QWaylandDisplay::QWaylandDisplay(void) #ifdef QT_WAYLAND_GL_SUPPORT mEglIntegration = QWaylandGLIntegration::createGLIntegration(this); #endif + blockingReadEvents(); qRegisterMetaType("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(data); QRect outputRect = QRect(x, y, width, height); waylandDisplay->createNewScreen(output,outputRect); From d8c6e2773f2161b3070809254c3fb9f9768bcc09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Tue, 3 May 2011 13:00:50 +0200 Subject: [PATCH 25/27] Remove warnings (cherry picked from commit 9625c564877414695a9706acf34bc8719018ef06) --- src/gui/kernel/qplatformintegration_qpa.cpp | 1 + src/gui/kernel/qplatformwindow_qpa.cpp | 2 +- src/plugins/platforms/wayland/qwaylandwindow.cpp | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qplatformintegration_qpa.cpp b/src/gui/kernel/qplatformintegration_qpa.cpp index d559c53355b..8ff12ebf9cf 100644 --- a/src/gui/kernel/qplatformintegration_qpa.cpp +++ b/src/gui/kernel/qplatformintegration_qpa.cpp @@ -214,6 +214,7 @@ QPlatformNativeInterface * QPlatformIntegration::nativeInterface() const bool QPlatformIntegration::hasCapability(Capability cap) const { + Q_UNUSED(cap); return false; } diff --git a/src/gui/kernel/qplatformwindow_qpa.cpp b/src/gui/kernel/qplatformwindow_qpa.cpp index 19bf7a9f294..f3654b676d6 100644 --- a/src/gui/kernel/qplatformwindow_qpa.cpp +++ b/src/gui/kernel/qplatformwindow_qpa.cpp @@ -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 diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp index 6f522911d78..53f2f483e95 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp @@ -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(data); self->mWaitingForFrameSync = false; } From 5bf2f85953a1df33ec942e49a9f72e0d9742bd54 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 4 May 2011 09:10:45 +0200 Subject: [PATCH 26/27] Compile on Windows The SPI_FONTSMOOTHINGCONTRAST macro is not defined everywhere. When the code was refactored, the workaround for this was lost. This resubmits the work-around to make it compile. Reviewed-by: Samuel (cherry picked from commit 4c3630c1fcd2b3008f540a8906a19c533604f36a) --- src/gui/kernel/qapplication_win.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index 1a490c9979b..72a05afbd08 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -656,7 +656,7 @@ static void qt_win_read_cleartype_settings() #endif int winSmooth; - if (SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0, &winSmooth, 0)) { + if (SystemParametersInfo(0x200C /* SPI_GETFONTSMOOTHINGCONTRAST */, 0, &winSmooth, 0)) { qt_fontsmoothing_gamma = winSmooth / qreal(1000.0); } else { qt_fontsmoothing_gamma = 1.0; From 539602d43a7214d4dbd182a629c5142af658129f Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 4 May 2011 10:00:42 +0200 Subject: [PATCH 27/27] Make it possible for animation driver to specify the advance time delta --- src/corelib/animation/qabstractanimation.cpp | 68 ++++++++++++++------ src/corelib/animation/qabstractanimation.h | 15 +++-- src/corelib/animation/qabstractanimation_p.h | 3 +- 3 files changed, 62 insertions(+), 24 deletions(-) diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index f399d7c4cff..7d74de8e44b 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -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; @@ -303,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(); } } @@ -462,37 +463,56 @@ QAnimationDriver::~QAnimationDriver() uninstall(); } -/*! - Advances the animation based on the current time. This function should - be continuously called by the driver while the animation is running. - \internal + +/*! + Advances the animation based to the specified \a timeStep. This function should + be continuously called by the driver subclasses while the animation is running. + + 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); @@ -509,7 +529,7 @@ void QAnimationDriver::start() { Q_D(QAnimationDriver); if (!d->running) { - started(); + emit started(); d->running = true; } } @@ -519,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 */ @@ -536,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 */ diff --git a/src/corelib/animation/qabstractanimation.h b/src/corelib/animation/qabstractanimation.h index a0cb0f93d0b..91282066a69 100644 --- a/src/corelib/animation/qabstractanimation.h +++ b/src/corelib/animation/qabstractanimation.h @@ -143,24 +143,29 @@ public: QAnimationDriver(QObject *parent = 0); ~QAnimationDriver(); - void advance(); + virtual 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(); }; diff --git a/src/corelib/animation/qabstractanimation_p.h b/src/corelib/animation/qabstractanimation_p.h index 1cba4644a87..de269877211 100644 --- a/src/corelib/animation/qabstractanimation_p.h +++ b/src/corelib/animation/qabstractanimation_p.h @@ -184,7 +184,7 @@ public: bool canUninstallAnimationDriver(QAnimationDriver *driver); void restartAnimationTimer(); - void updateAnimationsTime(); + void updateAnimationsTime(qint64 timeStep); //useful for profiling/debugging int runningAnimationCount() { return animations.count(); } @@ -194,6 +194,7 @@ protected: private: friend class QDefaultAnimationDriver; + friend class QAnimationDriver; QAnimationDriver *driver; QDefaultAnimationDriver defaultDriver;