Merge branch 'qtquick2'

This commit is contained in:
Gunnar Sletta 2011-05-04 10:01:37 +02:00
commit 72395bc540
104 changed files with 2075 additions and 752 deletions

16
configure vendored
View File

@ -804,6 +804,7 @@ CFG_MAC_XARCH=auto
CFG_MAC_CARBON=no
CFG_MAC_COCOA=yes
COMMANDLINE_MAC_CARBON=no
CFG_MAC_HARFBUZZ=no
CFG_SXE=no
CFG_PREFIX_INSTALL=yes
CFG_SDK=
@ -1041,7 +1042,7 @@ while [ "$#" -gt 0 ]; do
VAL=no
;;
#Qt style yes options
-incremental|-qvfb|-profile|-shared|-static|-sm|-xinerama|-xshape|-xsync|-xinput|-egl|-reduce-exports|-pch|-separate-debug-info|-stl|-freetype|-xcursor|-xfixes|-xrandr|-xrender|-mitshm|-fontconfig|-xkb|-nis|-qdbus|-dbus|-dbus-linked|-glib|-gstreamer|-gtkstyle|-cups|-iconv|-largefile|-h|-help|-v|-verbose|-debug|-release|-fast|-accessibility|-confirm-license|-gnumake|-framework|-qt3support|-debug-and-release|-exceptions|-cocoa|-carbon|-universal|-prefix-install|-silent|-armfpa|-optimized-qmake|-dwarf2|-reduce-relocations|-sse|-openssl|-openssl-linked|-ptmalloc|-xmlpatterns|-phonon|-phonon-backend|-multimedia|-audio-backend|-svg|-declarative|-declarative-debug|-javascript-jit|-script|-scripttools|-rpath|-force-pkg-config|-s60|-usedeffiles|-icu)
-incremental|-qvfb|-profile|-shared|-static|-sm|-xinerama|-xshape|-xsync|-xinput|-egl|-reduce-exports|-pch|-separate-debug-info|-stl|-freetype|-xcursor|-xfixes|-xrandr|-xrender|-mitshm|-fontconfig|-xkb|-nis|-qdbus|-dbus|-dbus-linked|-glib|-gstreamer|-gtkstyle|-cups|-iconv|-largefile|-h|-help|-v|-verbose|-debug|-release|-fast|-accessibility|-confirm-license|-gnumake|-framework|-qt3support|-debug-and-release|-exceptions|-cocoa|-carbon|-universal|-harfbuzz|-prefix-install|-silent|-armfpa|-optimized-qmake|-dwarf2|-reduce-relocations|-sse|-openssl|-openssl-linked|-ptmalloc|-xmlpatterns|-phonon|-phonon-backend|-multimedia|-audio-backend|-svg|-declarative|-declarative-debug|-javascript-jit|-script|-scripttools|-rpath|-force-pkg-config|-s60|-usedeffiles|-icu)
VAR=`echo $1 | sed "s,^-\(.*\),\1,"`
VAL=yes
;;
@ -1499,6 +1500,13 @@ while [ "$#" -gt 0 ]; do
UNKNOWN_OPT=yes
fi
;;
harfbuzz)
if [ "$PLATFORM_MAC" = "yes" ] && [ "$CFG_MAC_CARBON" != "yes" ] && [ "$VAL" = "yes" ]; then
CFG_MAC_HARFBUZZ="$VAL"
else
UNKNOWN_OPT=yes
fi
;;
framework)
if [ "$PLATFORM_MAC" = "yes" ] || [ "$PLATFORM_QPA" = "yes" ]; then
@ -4257,6 +4265,11 @@ Qt/Mac only:
-sdk <sdk> ......... Build Qt using Apple provided SDK <sdk>. This option requires gcc 4.
To use a different SDK with gcc 3.3, set the SDKROOT environment variable.
-harfbuzz .......... Use HarfBuzz to do text layout instead of Core Text when possible.
It is only available to Cocoa builds.
* -no-harfbuzz ....... Disable HarfBuzz on Mac. It can still be enabled by setting
QT_ENABLE_HARFBUZZ environment variable.
EOF
fi
@ -7251,6 +7264,7 @@ fi
[ "$CFG_NAS" = "system" ] && QT_CONFIG="$QT_CONFIG nas"
[ "$CFG_OPENSSL" = "yes" ] && QT_CONFIG="$QT_CONFIG openssl"
[ "$CFG_OPENSSL" = "linked" ] && QT_CONFIG="$QT_CONFIG openssl-linked"
[ "$CFG_MAC_HARFBUZZ" = "yes" ] && QT_CONFIG="$QT_CONFIG harfbuzz"
if [ "$PLATFORM_X11" = "yes" ]; then
[ "$CFG_SM" = "yes" ] && QT_CONFIG="$QT_CONFIG x11sm"

View File

@ -1,5 +1,7 @@
CONFIG *= moc thread
contains(QT, declarative): QT += opengl
#handle defines
win32 {
qt_static:DEFINES += QT_NODLL
@ -129,6 +131,7 @@ QMAKE_LIBDIR += $$QMAKE_LIBDIR_QT
# Topological ordering of modules based on their QT.<module>.depends variable
QT = $$resolve_depends($$QT, "QT.")
QT_DEPENDS=
for(QTLIB, $$list($$lower($$unique(QT)))) {

View File

@ -201,16 +201,17 @@ void QUnifiedTimer::ensureTimerUpdate()
{
QUnifiedTimer *inst = QUnifiedTimer::instance(false);
if (inst && inst->isPauseTimerActive)
inst->updateAnimationsTime();
inst->updateAnimationsTime(-1);
}
void QUnifiedTimer::updateAnimationsTime()
void QUnifiedTimer::updateAnimationsTime(qint64 timeStep)
{
//setCurrentTime can get this called again while we're the for loop. At least with pauseAnimations
if(insideTick)
return;
qint64 totalElapsed = time.elapsed();
qint64 totalElapsed = timeStep >= 0 ? timeStep : time.elapsed();
// ignore consistentTiming in case the pause timer is active
int delta = (consistentTiming && !isPauseTimerActive) ?
timingInterval : totalElapsed - lastTick;
@ -260,7 +261,8 @@ void QUnifiedTimer::restartAnimationTimer()
} else if (!driver->isRunning() || isPauseTimerActive) {
driver->start();
isPauseTimerActive = false;
}
} else if (runningLeafAnimations == 0)
driver->stop();
}
void QUnifiedTimer::setTimingInterval(int interval)
@ -302,7 +304,7 @@ void QUnifiedTimer::timerEvent(QTimerEvent *event)
if (event->timerId() == animationTimer.timerId()) {
// update current time on all top level animations
updateAnimationsTime();
updateAnimationsTime(-1);
restartAnimationTimer();
}
}
@ -389,19 +391,49 @@ int QUnifiedTimer::closestPauseAnimationTimeToFinish()
return closestTimeToFinish;
}
void QUnifiedTimer::installAnimationDriver(QAnimationDriver *d)
{
if (driver->isRunning()) {
qWarning("QUnifiedTimer: Cannot change animation driver while animations are running");
if (driver != &defaultDriver) {
qWarning("QUnifiedTimer: animation driver already installed...");
return;
}
if (driver && driver != &defaultDriver)
delete driver;
if (driver->isRunning()) {
driver->stop();
d->start();
}
driver = d;
}
void QUnifiedTimer::uninstallAnimationDriver(QAnimationDriver *d)
{
if (driver != d) {
qWarning("QUnifiedTimer: trying to uninstall a driver that is not installed...");
return;
}
driver = &defaultDriver;
if (d->isRunning()) {
d->stop();
driver->start();
}
}
/*!
Returns true if \a d is the currently installed animation driver
and is not the default animation driver (which can never be uninstalled).
*/
bool QUnifiedTimer::canUninstallAnimationDriver(QAnimationDriver *d)
{
return d == driver && driver != &defaultDriver;
}
/*!
\class QAnimationDriver
@ -424,35 +456,69 @@ QAnimationDriver::QAnimationDriver(QAnimationDriverPrivate &dd, QObject *parent)
{
}
QAnimationDriver::~QAnimationDriver()
{
QUnifiedTimer *timer = QUnifiedTimer::instance(true);
if (timer->canUninstallAnimationDriver(this))
uninstall();
}
/*!
Advances the animation based on the current time. This function should
be continuously called by the driver while the animation is running.
Advances the animation based to the specified \a timeStep. This function should
be continuously called by the driver subclasses while the animation is running.
\internal
If \a timeStep is positive, it will be used as the current time in the
calculations; otherwise, the current clock time will be used.
*/
void QAnimationDriver::advance()
void QAnimationDriver::advanceAnimation(qint64 timeStep)
{
QUnifiedTimer *instance = QUnifiedTimer::instance();
// update current time on all top level animations
instance->updateAnimationsTime();
instance->updateAnimationsTime(timeStep);
instance->restartAnimationTimer();
}
/*!
Advances the animation. This function should be continously called
by the driver while the animation is running.
*/
void QAnimationDriver::advance()
{
advanceAnimation(-1);
}
/*!
Installs this animation driver. The animation driver is thread local and
will only apply for the thread its installed in.
\internal
*/
void QAnimationDriver::install()
{
QUnifiedTimer *timer = QUnifiedTimer::instance(true);
timer->installAnimationDriver(this);
}
/*!
Uninstalls this animation driver.
*/
void QAnimationDriver::uninstall()
{
QUnifiedTimer *timer = QUnifiedTimer::instance(true);
timer->uninstallAnimationDriver(this);
}
bool QAnimationDriver::isRunning() const
{
return d_func()->running;
@ -463,7 +529,7 @@ void QAnimationDriver::start()
{
Q_D(QAnimationDriver);
if (!d->running) {
started();
emit started();
d->running = true;
}
}
@ -473,16 +539,28 @@ void QAnimationDriver::stop()
{
Q_D(QAnimationDriver);
if (d->running) {
stopped();
emit stopped();
d->running = false;
}
}
/*!
\fn qint64 QAnimationDriver::elapsed() const
Returns the number of milliseconds since the animations was started.
*/
qint64 QAnimationDriver::elapsed() const
{
return QUnifiedTimer::instance()->time.elapsed();
}
/*!
\fn QAnimationDriver::started()
This function is called by the animation framework to notify the driver
that it should start running.
This signal is emitted by the animation framework to notify the driver
that continous animation has started.
\internal
*/
@ -490,8 +568,8 @@ void QAnimationDriver::stop()
/*!
\fn QAnimationDriver::stopped()
This function is called by the animation framework to notify the driver
that it should stop running.
This signal is emitted by the animation framework to notify the driver
that continous animation has stopped.
\internal
*/

View File

@ -141,23 +141,31 @@ class Q_CORE_EXPORT QAnimationDriver : public QObject
public:
QAnimationDriver(QObject *parent = 0);
~QAnimationDriver();
virtual void advance();
void advance();
void install();
void uninstall();
bool isRunning() const;
qint64 elapsed() const;
Q_SIGNALS:
void started();
void stopped();
protected:
virtual void started() {};
virtual void stopped() {};
void advanceAnimation(qint64 timeStep = -1);
virtual void start();
virtual void stop();
QAnimationDriver(QAnimationDriverPrivate &dd, QObject *parent = 0);
private:
friend class QUnifiedTimer;
void start();
void stop();
};

View File

@ -180,15 +180,21 @@ public:
static void updateAnimationTimer();
void installAnimationDriver(QAnimationDriver *driver);
void uninstallAnimationDriver(QAnimationDriver *driver);
bool canUninstallAnimationDriver(QAnimationDriver *driver);
void restartAnimationTimer();
void updateAnimationsTime();
void updateAnimationsTime(qint64 timeStep);
//useful for profiling/debugging
int runningAnimationCount() { return animations.count(); }
protected:
void timerEvent(QTimerEvent *);
private:
friend class QDefaultAnimationDriver;
friend class QAnimationDriver;
QAnimationDriver *driver;
QDefaultAnimationDriver defaultDriver;

View File

@ -2755,7 +2755,8 @@ QT_LICENSED_MODULE(DBus)
#if !(defined(Q_WS_WIN) && !defined(Q_WS_WINCE)) \
&& !(defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)) \
&& !(defined(Q_WS_X11) && !defined(QT_NO_FREETYPE))
&& !(defined(Q_WS_X11) && !defined(QT_NO_FREETYPE)) \
&& !(defined(Q_WS_QPA))
# define QT_NO_RAWFONT
#endif

View File

@ -171,17 +171,27 @@ private:
Q_GLOBAL_STATIC(QMutex, processManagerGlobalMutex)
static QProcessManager *processManager() {
static QProcessManager *processManagerInstance = 0;
static QProcessManager *processManager()
{
// The constructor of QProcessManager should be called only once
// so we cannot use Q_GLOBAL_STATIC directly for QProcessManager
QMutex *mutex = processManagerGlobalMutex();
QMutexLocker locker(mutex);
static QProcessManager processManager;
return &processManager;
if (!processManagerInstance)
QProcessPrivate::initializeProcessManager();
Q_ASSERT(processManagerInstance);
return processManagerInstance;
}
QProcessManager::QProcessManager()
{
// can only be called from main thread
Q_ASSERT(!qApp || qApp->thread() == QThread::currentThread());
#if defined (QPROCESS_DEBUG)
qDebug() << "QProcessManager::QProcessManager()";
#endif
@ -197,6 +207,8 @@ QProcessManager::QProcessManager()
action.sa_handler = qt_sa_sigchld_handler;
action.sa_flags = SA_NOCLDSTOP;
::sigaction(SIGCHLD, &action, &qt_sa_old_sigchld_handler);
processManagerInstance = this;
}
QProcessManager::~QProcessManager()
@ -221,6 +233,8 @@ QProcessManager::~QProcessManager()
if (currentAction.sa_handler == qt_sa_sigchld_handler) {
::sigaction(SIGCHLD, &qt_sa_old_sigchld_handler, 0);
}
processManagerInstance = 0;
}
void QProcessManager::run()
@ -1287,7 +1301,15 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a
void QProcessPrivate::initializeProcessManager()
{
(void) processManager();
if (qApp && qApp->thread() != QThread::currentThread()) {
// The process manager must be initialized in the main thread
// Note: The call below will re-enter this function, but in the right thread,
// so the else statement below will be executed.
QMetaObject::invokeMethod(qApp, "_q_initializeProcessManager", Qt::BlockingQueuedConnection);
} else {
static QProcessManager processManager;
Q_UNUSED(processManager);
}
}
QT_END_NAMESPACE

View File

@ -392,6 +392,16 @@ void QCoreApplicationPrivate::createEventDispatcher()
#endif
}
void QCoreApplicationPrivate::_q_initializeProcessManager()
{
#ifndef QT_NO_PROCESS
# ifdef Q_OS_UNIX
QProcessPrivate::initializeProcessManager();
# endif
#endif
}
QThread *QCoreApplicationPrivate::theMainThread = 0;
QThread *QCoreApplicationPrivate::mainThread()
{
@ -656,12 +666,6 @@ void QCoreApplication::init()
}
#endif
#if defined(Q_OS_UNIX) && !(defined(QT_NO_PROCESS))
// Make sure the process manager thread object is created in the main
// thread.
QProcessPrivate::initializeProcessManager();
#endif
#ifdef QT_EVAL
extern void qt_core_eval_init(uint);
qt_core_eval_init(d->application_type);
@ -2728,3 +2732,5 @@ int QCoreApplication::loopLevel()
*/
QT_END_NAMESPACE
#include "moc_qcoreapplication.cpp"

View File

@ -205,6 +205,7 @@ protected:
QCoreApplication(QCoreApplicationPrivate &p);
private:
Q_PRIVATE_SLOT(d_func(), void _q_initializeProcessManager())
static bool sendSpontaneousEvent(QObject *receiver, QEvent *event);
bool notifyInternal(QObject *receiver, QEvent *event);

View File

@ -85,6 +85,8 @@ public:
bool sendThroughObjectEventFilters(QObject *, QEvent *);
bool notify_helper(QObject *, QEvent *);
void _q_initializeProcessManager();
virtual QString appName() const;
virtual void createEventDispatcher();
static void removePostedEvent(QEvent *);

View File

@ -237,6 +237,7 @@ static void resolveAygLibs()
# define FE_FONTSMOOTHINGCLEARTYPE 0x0002
#endif
Q_GUI_EXPORT qreal qt_fontsmoothing_gamma;
Q_GUI_EXPORT bool qt_cleartype_enabled;
Q_GUI_EXPORT bool qt_win_owndc_required; // CS_OWNDC is required if we use the GL graphicssystem as default
@ -653,8 +654,18 @@ static void qt_win_read_cleartype_settings()
if (SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &result, 0))
qt_cleartype_enabled = (result == FE_FONTSMOOTHINGCLEARTYPE);
#endif
int winSmooth;
if (SystemParametersInfo(0x200C /* SPI_GETFONTSMOOTHINGCONTRAST */, 0, &winSmooth, 0)) {
qt_fontsmoothing_gamma = winSmooth / qreal(1000.0);
} else {
qt_fontsmoothing_gamma = 1.0;
}
// Safeguard ourselves against corrupt registry values...
if (qt_fontsmoothing_gamma > 5 || qt_fontsmoothing_gamma < 1)
qt_fontsmoothing_gamma = qreal(1.4);
}
static void qt_set_windows_resources()
{

View File

@ -334,7 +334,6 @@ static int qCocoaViewCount = 0;
//
// Qt will then forward the update to the children.
if (qwidget->isWindow()) {
qwidget->update(qwidget->rect());
qwidgetprivate->syncBackingStore(qwidget->rect());
}
}

View File

@ -51,6 +51,8 @@ QT_USE_NAMESPACE
void QDesktopWidgetPrivate::updateScreenList()
{
Q_Q(QDesktopWidget);
QList<QPlatformScreen *> screenList = QApplicationPrivate::platformIntegration()->screens();
int targetLength = screenList.length();
int currentLength = screens.length();
@ -72,19 +74,15 @@ void QDesktopWidgetPrivate::updateScreenList()
}
QRegion virtualGeometry;
bool doVirtualGeometry = QApplicationPrivate::platformIntegration()->isVirtualDesktop();
// update the geometry of each screen widget
for (int i = 0; i < screens.length(); i++) {
QRect screenGeometry = screenList.at(i)->geometry();
screens.at(i)->setGeometry(screenGeometry);
if (doVirtualGeometry)
virtualGeometry += screenGeometry;
}
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);

View File

@ -76,7 +76,6 @@ public:
void updateScreenList();
QList<QDesktopScreenWidget *> screens;
QDesktopScreenWidget virtualScreen;
};
#endif // QDESKTOPWIDGET_QPA_P_H

View File

@ -214,6 +214,7 @@ QPlatformNativeInterface * QPlatformIntegration::nativeInterface() const
bool QPlatformIntegration::hasCapability(Capability cap) const
{
Q_UNUSED(cap);
return false;
}

View File

@ -150,7 +150,7 @@ void QPlatformWindow::setParent(const QPlatformWindow *parent)
/*!
Reimplement to set the window title to \a title
*/
void QPlatformWindow::setWindowTitle(const QString &title) {}
void QPlatformWindow::setWindowTitle(const QString &) {}
/*!
Reimplement to be able to let Qt rais windows to the top of the desktop

View File

@ -42,6 +42,8 @@
#include <qsessionmanager.h>
#include <private/qobject_p.h>
#include <qapplication.h>
#ifndef QT_NO_SESSIONMANAGER
QT_BEGIN_NAMESPACE

View File

@ -7198,14 +7198,8 @@ void qt_build_pow_tables() {
#endif
#ifdef Q_WS_WIN
int winSmooth;
if (SystemParametersInfo(0x200C /* SPI_GETFONTSMOOTHINGCONTRAST */, 0, &winSmooth, 0))
smoothing = winSmooth / qreal(1000.0);
// Safeguard ourselves against corrupt registry values...
if (smoothing > 5 || smoothing < 1)
smoothing = qreal(1.4);
extern qreal qt_fontsmoothing_gamma; // qapplication_win.cpp
smoothing = qt_fontsmoothing_gamma;
#endif
#ifdef Q_WS_X11

View File

@ -100,7 +100,9 @@ QMacCGContext::QMacCGContext(QPainter *p)
int devType = p->device()->devType();
if (pe->type() == QPaintEngine::Raster
&& (devType == QInternal::Widget || devType == QInternal::Pixmap)) {
&& (devType == QInternal::Widget ||
devType == QInternal::Pixmap ||
devType == QInternal::Image)) {
extern CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice);
CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(pe->paintDevice());

View File

@ -156,7 +156,8 @@ static bool qt_paintengine_supports_transformations(QPaintEngine::Type type)
{
return type == QPaintEngine::OpenGL2
|| type == QPaintEngine::OpenVG
|| type == QPaintEngine::OpenGL;
|| type == QPaintEngine::OpenGL
|| type == QPaintEngine::CoreGraphics;
}
#ifndef QT_NO_DEBUG
@ -5809,7 +5810,7 @@ void QPainter::drawGlyphs(const QPointF &position, const QGlyphs &glyphs)
bool paintEngineSupportsTransformations =
d->extended != 0
? qt_paintengine_supports_transformations(d->extended->type())
: false;
: qt_paintengine_supports_transformations(d->engine->type());
for (int i=0; i<count; ++i) {
QPointF processedPosition = position + glyphPositions.at(i);
if (!paintEngineSupportsTransformations)

View File

@ -296,7 +296,7 @@ void QTextureGlyphCache::fillInPendingGlyphs()
QImage QTextureGlyphCache::textureMapForGlyph(glyph_t g, QFixed subPixelPosition) const
{
#if defined(Q_WS_X11)
if (m_transform.type() > QTransform::TxTranslate) {
if (m_transform.type() > QTransform::TxTranslate && m_current_fontengine->type() == QFontEngine::Freetype) {
QFontEngineFT::GlyphFormat format = QFontEngineFT::Format_None;
QImage::Format imageFormat = QImage::Format_Invalid;
switch (m_type) {

View File

@ -239,7 +239,7 @@ public:
bool isCopyOf(const QFont &) const;
#ifdef Q_COMPILER_RVALUE_REFS
inline QFont &operator=(QFont &&other)
{ qSwap(d, other.d); return *this; }
{ qSwap(d, other.d); qSwap(resolve_mask, other.resolve_mask); return *this; }
#endif
#ifdef Q_WS_WIN

View File

@ -162,8 +162,10 @@ uint QCoreTextFontEngineMulti::fontIndexForFont(CTFontRef font) const
return engines.count() - 1;
}
bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags,
unsigned short *logClusters, const HB_CharAttributes *) const
bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs,
int *nglyphs, QTextEngine::ShaperFlags flags,
unsigned short *logClusters, const HB_CharAttributes *,
QScriptItem *si) const
{
QCFType<CFStringRef> cfstring = CFStringCreateWithCharactersNoCopy(0,
reinterpret_cast<const UniChar *>(str),
@ -180,6 +182,8 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay
&kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
typeSetter = CTTypesetterCreateWithAttributedStringAndOptions(attributedString, options);
} else
#else
Q_UNUSED(flags);
#endif
typeSetter = CTTypesetterCreateWithAttributedString(attributedString);
@ -219,6 +223,25 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay
Q_ASSERT((CTRunGetStatus(run) & kCTRunStatusRightToLeft) == rtl);
CFRange stringRange = CTRunGetStringRange(run);
int prepend = 0;
#if MAC_OS_X_VERSION_MAX_ALLOWED == MAC_OS_X_VERSION_10_5
UniChar beginGlyph = CFStringGetCharacterAtIndex(cfstring, stringRange.location);
QChar dir = QChar::direction(beginGlyph);
bool beginWithOverride = dir == QChar::DirLRO || dir == QChar::DirRLO || dir == QChar::DirLRE || dir == QChar::DirRLE;
if (beginWithOverride) {
logClusters[stringRange.location] = 0;
outGlyphs[0] = 0xFFFF;
outAdvances_x[0] = 0;
outAdvances_y[0] = 0;
outAttributes[0].clusterStart = true;
outAttributes[0].dontPrint = true;
outGlyphs++;
outAdvances_x++;
outAdvances_y++;
outAttributes++;
prepend = 1;
}
#endif
UniChar endGlyph = CFStringGetCharacterAtIndex(cfstring, stringRange.location + stringRange.length - 1);
bool endWithPDF = QChar::direction(endGlyph) == QChar::DirPDF;
if (endWithPDF)
@ -233,7 +256,12 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay
if (!runAttribs)
runAttribs = attributeDict;
CTFontRef runFont = static_cast<CTFontRef>(CFDictionaryGetValue(runAttribs, NSFontAttributeName));
const uint fontIndex = (fontIndexForFont(runFont) << 24);
uint fontIndex = fontIndexForFont(runFont);
const QFontEngine *engine = engineAt(fontIndex);
fontIndex <<= 24;
si->ascent = qMax(engine->ascent(), si->ascent);
si->descent = qMax(engine->descent(), si->descent);
si->leading = qMax(engine->leading(), si->leading);
//NSLog(@"Run Font Name = %@", CTFontCopyFamilyName(runFont));
if (endWithPDF)
glyphCount--;
@ -271,9 +299,9 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay
CFIndex k = 0;
CFIndex i = 0;
for (i = stringRange.location;
for (i = stringRange.location + prepend;
(i < stringRange.location + stringRange.length) && (k < glyphCount); ++i) {
if (tmpIndices[k * rtlSign + rtlOffset] == i || i == stringRange.location) {
if (tmpIndices[k * rtlSign + rtlOffset] == i || i == stringRange.location + prepend) {
logClusters[i] = k + firstGlyphIndex;
outAttributes[k].clusterStart = true;
++k;
@ -308,7 +336,7 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay
: QFixed::fromReal(lastGlyphAdvance.width);
if (endWithPDF) {
logClusters[stringRange.location + stringRange.length - 1] = glyphCount;
logClusters[stringRange.location + stringRange.length - 1] = glyphCount + prepend;
outGlyphs[glyphCount] = 0xFFFF;
outAdvances_x[glyphCount] = 0;
outAdvances_y[glyphCount] = 0;
@ -837,6 +865,15 @@ QFixed QCoreTextFontEngine::emSquareSize() const
return QFixed::QFixed(int(CTFontGetUnitsPerEm(ctfont)));
}
QFontEngine *QCoreTextFontEngine::cloneWithSize(qreal pixelSize) const
{
QFontDef newFontDef = fontDef;
newFontDef.pixelSize = pixelSize;
newFontDef.pointSize = pixelSize * 72.0 / qt_defaultDpi();
return new QCoreTextFontEngine(cgFont, fontDef);
}
QT_END_NAMESPACE
#endif// !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)

View File

@ -91,6 +91,8 @@ public:
virtual qreal minLeftBearing() const;
virtual QFixed emSquareSize() const;
virtual QFontEngine *cloneWithSize(qreal pixelSize) const;
private:
friend class QRawFontPrivate;
@ -118,7 +120,8 @@ public:
QTextEngine::ShaperFlags flags) const;
bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs,
QTextEngine::ShaperFlags flags,
unsigned short *logClusters, const HB_CharAttributes *charAttributes) const;
unsigned short *logClusters, const HB_CharAttributes *charAttributes,
QScriptItem *si) const;
virtual const char *name() const { return "CoreText"; }
protected:

View File

@ -2069,6 +2069,41 @@ HB_Error QFontEngineFT::getPointInOutline(HB_Glyph glyph, int flags, hb_uint32 p
return result;
}
bool QFontEngineFT::initFromFontEngine(const QFontEngineFT *fe)
{
if (!init(fe->faceId(), fe->antialias, fe->defaultFormat, fe->freetype))
return false;
// Increase the reference of this QFreetypeFace since one more QFontEngineFT
// will be using it
freetype->ref.ref();
default_load_flags = fe->default_load_flags;
default_hint_style = fe->default_hint_style;
antialias = fe->antialias;
transform = fe->transform;
embolden = fe->embolden;
subpixelType = fe->subpixelType;
lcdFilterType = fe->lcdFilterType;
canUploadGlyphsToServer = fe->canUploadGlyphsToServer;
embeddedbitmap = fe->embeddedbitmap;
return true;
}
QFontEngine *QFontEngineFT::cloneWithSize(qreal pixelSize) const
{
QFontDef fontDef;
fontDef.pixelSize = pixelSize;
QFontEngineFT *fe = new QFontEngineFT(fontDef);
if (!fe->initFromFontEngine(this)) {
delete fe;
return 0;
} else {
return fe;
}
}
QT_END_NAMESPACE
#endif // QT_NO_FREETYPE

View File

@ -122,7 +122,7 @@ struct QFreetypeFace
static void addBitmapToPath(FT_GlyphSlot slot, const QFixedPoint &point, QPainterPath *path, bool = false);
private:
friend class QFontEngineFTRawFont;
friend class QFontEngineFT;
friend class QScopedPointerDeleter<QFreetypeFace>;
QFreetypeFace() : _lock(QMutex::Recursive) {}
~QFreetypeFace() {}
@ -311,14 +311,12 @@ private:
virtual HB_Error getPointInOutline(HB_Glyph glyph, int flags, hb_uint32 point, HB_Fixed *xpos, HB_Fixed *ypos, hb_uint32 *nPoints);
enum HintStyle {
HintNone,
HintLight,
HintMedium,
HintFull
};
void setDefaultHintStyle(HintStyle style);
virtual void setDefaultHintStyle(HintStyle style);
virtual QFontEngine *cloneWithSize(qreal pixelSize) const;
bool initFromFontEngine(const QFontEngineFT *fontEngine);
HintStyle defaultHintStyle() const { return default_hint_style; }
protected:

View File

@ -377,7 +377,7 @@ bool QFontEngineMacMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *
}
bool QFontEngineMacMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags,
unsigned short *logClusters, const HB_CharAttributes *charAttributes) const
unsigned short *logClusters, const HB_CharAttributes *charAttributes, QScriptItem *) const
{
if (*nglyphs < len) {
*nglyphs = len;

View File

@ -131,7 +131,7 @@ public:
virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const;
bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags,
unsigned short *logClusters, const HB_CharAttributes *charAttributes) const;
unsigned short *logClusters, const HB_CharAttributes *charAttributes, QScriptItem *) const;
virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const;
virtual void doKerning(QGlyphLayout *, QTextEngine::ShaperFlags) const;

View File

@ -235,6 +235,8 @@ public:
virtual int glyphCount() const;
virtual QFontEngine *cloneWithSize(qreal /*pixelSize*/) const { return 0; }
HB_Font harfbuzzFont() const;
HB_Face harfbuzzFace() const;
@ -248,6 +250,14 @@ public:
static QByteArray convertToPostscriptFontFamilyName(const QByteArray &fontFamily);
enum HintStyle {
HintNone,
HintLight,
HintMedium,
HintFull
};
virtual void setDefaultHintStyle(HintStyle) { }
QAtomicInt ref;
QFontDef fontDef;
uint cache_cost; // amount of mem used in kb by the font

View File

@ -1284,6 +1284,23 @@ QImage QFontEngineWin::alphaRGBMapForGlyph(glyph_t glyph, QFixed, int margin, co
return rgbMask;
}
// From qfontdatabase_win.cpp
extern QFontEngine *qt_load_font_engine_win(const QFontDef &request);
QFontEngine *QFontEngineWin::cloneWithSize(qreal pixelSize) const
{
QFontDef request = fontDef;
QString actualFontName = request.family;
if (!uniqueFamilyName.isEmpty())
request.family = uniqueFamilyName;
request.pixelSize = pixelSize;
QFontEngine *fontEngine = qt_load_font_engine_win(request);
if (fontEngine != NULL)
fontEngine->fontDef.family = actualFontName;
return fontEngine;
}
// -------------------------------------- Multi font engine
QFontEngineMultiWin::QFontEngineMultiWin(QFontEngine *first, const QStringList &fallbacks)

View File

@ -106,6 +106,8 @@ public:
virtual QImage alphaMapForGlyph(glyph_t, const QTransform &xform);
virtual QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform);
virtual QFontEngine *cloneWithSize(qreal pixelSize) const;
#ifndef Q_CC_MINGW
virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0);
#endif
@ -118,6 +120,7 @@ public:
#endif
QString _name;
QString uniqueFamilyName;
HFONT hfont;
LOGFONT logfont;
uint stockFont : 1;

View File

@ -1196,6 +1196,20 @@ bool QFontEngineX11FT::uploadGlyphToServer(QGlyphSet *set, uint glyphid, Glyph *
#endif
}
QFontEngine *QFontEngineX11FT::cloneWithSize(qreal pixelSize) const
{
QFontDef fontDef;
fontDef.pixelSize = pixelSize;
QFontEngineX11FT *fe = new QFontEngineX11FT(fontDef);
if (!fe->initFromFontEngine(this)) {
delete fe;
return 0;
} else {
fe->xglyph_format = xglyph_format;
return fe;
}
}
#endif // QT_NO_FONTCONFIG
QT_END_NAMESPACE

View File

@ -161,6 +161,8 @@ public:
explicit QFontEngineX11FT(FcPattern *pattern, const QFontDef &fd, int screen);
~QFontEngineX11FT();
QFontEngine *cloneWithSize(qreal pixelSize) const;
#ifndef QT_NO_XRENDER
int xglyph_format;
#endif

View File

@ -630,6 +630,17 @@ QFontEngine::Type QFontEngineDirectWrite::type() const
return QFontEngine::DirectWrite;
}
QFontEngine *QFontEngineDirectWrite::cloneWithSize(qreal pixelSize) const
{
QFontEngine *fontEngine = new QFontEngineDirectWrite(m_directWriteFactory, m_directWriteFontFace,
pixelSize);
fontEngine->fontDef = fontDef;
fontEngine->fontDef.pixelSize = pixelSize;
return fontEngine;
}
QT_END_NAMESPACE
#endif // QT_NO_DIRECTWRITE

View File

@ -101,6 +101,8 @@ public:
QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, int margin,
const QTransform &xform);
QFontEngine *cloneWithSize(qreal pixelSize) const;
bool canRender(const QChar *string, int len);
Type type() const;

View File

@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QGlyphs
\brief the QGlyphs class provides direct access to the internal glyphs in a font
\brief The QGlyphs class provides direct access to the internal glyphs in a font.
\since 4.8
\ingroup text
@ -76,8 +76,8 @@ QT_BEGIN_NAMESPACE
QTextLayout::glyphs() or QTextFragment::glyphs() can be used to convert unicode encoded text
into a list of QGlyphs objects, and QPainter::drawGlyphs() can be used to draw the glyphs.
\note Please note that QRawFont is considered local to the thread in which it is constructed,
which in turn means that a new QRawFont will have to be created and set on the QGlyphs if it is
\note Please note that QRawFont is considered local to the thread in which it is constructed.
This in turn means that a new QRawFont will have to be created and set on the QGlyphs if it is
moved to a different thread. If the QGlyphs contains a reference to a QRawFont from a different
thread than the current, it will not be possible to draw the glyphs using a QPainter, as the
QRawFont is considered invalid and inaccessible in this case.

View File

@ -218,6 +218,16 @@ QFontEngine *QPlatformFontDatabase::fontEngine(const QFontDef &fontDef, QUnicode
return engine;
}
QFontEngine *QPlatformFontDatabase::fontEngine(const QByteArray &fontData, qreal pixelSize,
QFont::HintingPreference hintingPreference)
{
Q_UNUSED(fontData);
Q_UNUSED(pixelSize);
Q_UNUSED(hintingPreference);
qWarning("This plugin does not support font engines created directly from font data");
return 0;
}
/*!
*/

View File

@ -92,6 +92,8 @@ public:
virtual QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName);
virtual void releaseHandle(void *handle);
virtual QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference);
virtual QString fontDir() const;
//callback

View File

@ -308,10 +308,10 @@ qreal QRawFont::descent() const
\sa setPixelSize()
*/
int QRawFont::pixelSize() const
qreal QRawFont::pixelSize() const
{
if (!isValid())
return -1;
return 0.0;
return d->fontEngine->fontDef.pixelSize;
}
@ -577,10 +577,21 @@ QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writ
/*!
Sets the pixel size with which this font should be rendered to \a pixelSize.
*/
void QRawFont::setPixelSize(int pixelSize)
void QRawFont::setPixelSize(qreal pixelSize)
{
if (d->fontEngine == 0)
return;
detach();
d->platformSetPixelSize(pixelSize);
QFontEngine *oldFontEngine = d->fontEngine;
d->fontEngine = d->fontEngine->cloneWithSize(pixelSize);
if (d->fontEngine != 0)
d->fontEngine->ref.ref();
oldFontEngine->ref.deref();
if (oldFontEngine->cache_count == 0 && oldFontEngine->ref == 0)
delete oldFontEngine;
}
/*!

View File

@ -96,8 +96,8 @@ public:
const QTransform &transform = QTransform()) const;
QPainterPath pathForGlyph(quint32 glyphIndex) const;
void setPixelSize(int pixelSize);
int pixelSize() const;
void setPixelSize(qreal pixelSize);
qreal pixelSize() const;
QFont::HintingPreference hintingPreference() const;

View File

@ -90,32 +90,6 @@ public:
return init(faceId, true, Format_None, fontData);
}
bool initFromFontEngine(QFontEngine *oldFontEngine)
{
QFontEngineFT *fe = static_cast<QFontEngineFT *>(oldFontEngine);
// Increase the reference of this QFreetypeFace since one more QFontEngineFT
// will be using it
fe->freetype->ref.ref();
if (!init(fe->faceId(), fe->antialias, fe->defaultFormat, fe->freetype))
return false;
default_load_flags = fe->default_load_flags;
default_hint_style = fe->default_hint_style;
antialias = fe->antialias;
transform = fe->transform;
embolden = fe->embolden;
subpixelType = fe->subpixelType;
lcdFilterType = fe->lcdFilterType;
canUploadGlyphsToServer = fe->canUploadGlyphsToServer;
embeddedbitmap = fe->embeddedbitmap;
#if defined(Q_WS_X11)
xglyph_format = static_cast<QFontEngineX11FT *>(fe)->xglyph_format;
#endif
return true;
}
};
@ -159,31 +133,6 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, int pixel
fontEngine->ref.ref();
}
void QRawFontPrivate::platformSetPixelSize(int pixelSize)
{
if (fontEngine == NULL)
return;
QFontEngine *oldFontEngine = fontEngine;
QFontDef fontDef;
fontDef.pixelSize = pixelSize;
QFontEngineFTRawFont *fe = new QFontEngineFTRawFont(fontDef);
if (!fe->initFromFontEngine(oldFontEngine)) {
delete fe;
return;
}
fontEngine = fe;
fontEngine->fontDef = oldFontEngine->fontDef;
fontEngine->fontDef.pixelSize = pixelSize;
fontEngine->ref.ref();
Q_ASSERT(fontEngine != oldFontEngine);
oldFontEngine->ref.deref();
if (oldFontEngine->cache_count == 0 && oldFontEngine->ref == 0)
delete oldFontEngine;
}
QT_END_NAMESPACE
#endif // QT_NO_RAWFONT

View File

@ -78,28 +78,6 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData,
}
}
void QRawFontPrivate::platformSetPixelSize(int pixelSize)
{
if (fontEngine == NULL)
return;
QFontEngine *oldFontEngine = fontEngine;
QFontDef fontDef = oldFontEngine->fontDef;
fontDef.pixelSize = pixelSize;
fontDef.pointSize = pixelSize * 72.0 / qt_defaultDpi();
QCoreTextFontEngine *ctFontEngine = static_cast<QCoreTextFontEngine *>(oldFontEngine);
Q_ASSERT(ctFontEngine->cgFont);
fontEngine = new QCoreTextFontEngine(ctFontEngine->cgFont, fontDef);
fontEngine->ref.ref();
Q_ASSERT(fontEngine != oldFontEngine);
oldFontEngine->ref.deref();
if (oldFontEngine->cache_count == 0 && oldFontEngine->ref == 0)
delete oldFontEngine;
}
QT_END_NAMESPACE
#endif // QT_NO_RAWFONT

View File

@ -62,7 +62,7 @@
QT_BEGIN_NAMESPACE
namespace { class CustomFontFileLoader; }
class Q_AUTOTEST_EXPORT QRawFontPrivate
class Q_GUI_EXPORT QRawFontPrivate
{
public:
QRawFontPrivate()
@ -83,7 +83,6 @@ public:
, fontHandle(NULL)
, ptrAddFontMemResourceEx(other.ptrAddFontMemResourceEx)
, ptrRemoveFontMemResourceEx(other.ptrRemoveFontMemResourceEx)
, uniqueFamilyName(other.uniqueFamilyName)
#endif
{
fontEngine = other.fontEngine;
@ -102,7 +101,6 @@ public:
void platformLoadFromData(const QByteArray &fontData,
int pixelSize,
QFont::HintingPreference hintingPreference);
void platformSetPixelSize(int pixelSize);
static QRawFontPrivate *get(const QRawFont &font) { return font.d.data(); }
@ -120,8 +118,6 @@ public:
PtrAddFontMemResourceEx ptrAddFontMemResourceEx;
PtrRemoveFontMemResourceEx ptrRemoveFontMemResourceEx;
QString uniqueFamilyName;
#endif // Q_WS_WIN
};

View File

@ -0,0 +1,69 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtCore/qglobal.h>
#if !defined(QT_NO_RAWFONT)
#include "qrawfont_p.h"
#include <QtGui/qplatformfontdatabase_qpa.h>
#include <private/qapplication_p.h>
QT_BEGIN_NAMESPACE
void QRawFontPrivate::platformCleanUp()
{
}
void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, int pixelSize,
QFont::HintingPreference hintingPreference)
{
Q_ASSERT(fontEngine == 0);
QPlatformFontDatabase *pfdb = QApplicationPrivate::platformIntegration()->fontDatabase();
fontEngine = pfdb->fontEngine(fontData, pixelSize, hintingPreference);
if (fontEngine != 0)
fontEngine->ref.ref();
}
QT_END_NAMESPACE
#endif // QT_NO_RAWFONT

View File

@ -559,7 +559,7 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &_fontData,
GUID guid;
CoCreateGuid(&guid);
uniqueFamilyName = QString::fromLatin1("f")
QString uniqueFamilyName = QString::fromLatin1("f")
+ QString::number(guid.Data1, 36) + QLatin1Char('-')
+ QString::number(guid.Data2, 36) + QLatin1Char('-')
+ QString::number(guid.Data3, 36) + QLatin1Char('-')
@ -613,6 +613,7 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &_fontData,
Q_ASSERT(fontEngine->cache_count == 0 && fontEngine->ref == 0);
// Override the generated font name
static_cast<QFontEngineWin *>(fontEngine)->uniqueFamilyName = uniqueFamilyName;
fontEngine->fontDef.family = actualFontName;
fontEngine->ref.ref();
}
@ -701,50 +702,6 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &_fontData,
}
}
void QRawFontPrivate::platformSetPixelSize(int pixelSize)
{
if (fontEngine == NULL)
return;
QFontEngine *oldFontEngine = fontEngine;
#if !defined(QT_NO_DIRECTWRITE)
if (fontEngine->type() == QFontEngine::Win)
#endif
{
QFontDef request = fontEngine->fontDef;
QString actualFontName = request.family;
if (!uniqueFamilyName.isEmpty())
request.family = uniqueFamilyName;
request.pixelSize = pixelSize;
fontEngine = qt_load_font_engine_win(request);
if (fontEngine != NULL) {
fontEngine->fontDef.family = actualFontName;
fontEngine->ref.ref();
}
}
#if !defined(QT_NO_DIRECTWRITE)
else {
QFontEngineDirectWrite *dWriteFE = static_cast<QFontEngineDirectWrite *>(fontEngine);
fontEngine = new QFontEngineDirectWrite(dWriteFE->m_directWriteFactory,
dWriteFE->m_directWriteFontFace,
pixelSize);
fontEngine->fontDef = dWriteFE->fontDef;
fontEngine->fontDef.pixelSize = pixelSize;
fontEngine->ref.ref();
}
#endif
Q_ASSERT(fontEngine != oldFontEngine);
oldFontEngine->ref.deref();
if (oldFontEngine->cache_count == 0 && oldFontEngine->ref == 0)
delete oldFontEngine;
}
QT_END_NAMESPACE
#endif // QT_NO_RAWFONT

View File

@ -714,17 +714,13 @@ QStaticTextItem::~QStaticTextItem()
{
if (m_userData != 0 && !m_userData->ref.deref())
delete m_userData;
if (!m_fontEngine->ref.deref())
delete m_fontEngine;
m_fontEngine->ref.deref();
}
void QStaticTextItem::setFontEngine(QFontEngine *fe)
{
if (m_fontEngine != 0) {
if (!m_fontEngine->ref.deref())
delete m_fontEngine;
}
if (m_fontEngine != 0)
m_fontEngine->ref.deref();
m_fontEngine = fe;
if (m_fontEngine != 0)
m_fontEngine->ref.ref();

View File

@ -362,20 +362,23 @@ bool QTextCursorPrivate::movePosition(QTextCursor::MoveOperation op, QTextCursor
currentCharFormat = -1;
bool adjustX = true;
QTextBlock blockIt = block();
bool visualMovement = priv->defaultCursorMoveStyle == QTextCursor::Visual;
if (!blockIt.isValid())
return false;
if (op >= QTextCursor::Left && op <= QTextCursor::WordRight
&& blockIt.textDirection() == Qt::RightToLeft) {
if (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;
else if (op == QTextCursor::WordLeft)
op = QTextCursor::NextWord;
else if (op == QTextCursor::WordRight)
op = QTextCursor::PreviousWord;
}
}
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

View File

@ -86,6 +86,10 @@ public:
MoveAnchor,
KeepAnchor
};
enum MoveStyle {
Logical,
Visual
};
void setPosition(int pos, MoveMode mode = MoveAnchor);
int position() const;

View File

@ -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)

View File

@ -46,6 +46,7 @@
#include <QtCore/qsize.h>
#include <QtCore/qrect.h>
#include <QtGui/qfont.h>
#include <QtGui/qtextcursor.h>
QT_BEGIN_HEADER
@ -60,7 +61,6 @@ class QPainter;
class QPrinter;
class QAbstractTextDocumentLayout;
class QPoint;
class QTextCursor;
class QTextObject;
class QTextFormat;
class QTextFrame;
@ -269,6 +269,9 @@ public:
QTextOption defaultTextOption() const;
void setDefaultTextOption(const QTextOption &option);
QTextCursor::MoveStyle defaultCursorMoveStyle() const;
void setDefaultCursorMoveStyle(QTextCursor::MoveStyle style);
Q_SIGNALS:
void contentsChange(int from, int charsRemoves, int charsAdded);
void contentsChanged();

View File

@ -209,6 +209,7 @@ QTextDocumentPrivate::QTextDocumentPrivate()
defaultTextOption.setTabStop(80); // same as in qtextengine.cpp
defaultTextOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
defaultCursorMoveStyle = QTextCursor::Logical;
indentWidth = 40;
documentMargin = 4;
@ -1382,6 +1383,20 @@ int QTextDocumentPrivate::previousCursorPosition(int position, QTextLayout::Curs
return it.layout()->previousCursorPosition(position-start, mode) + start;
}
int QTextDocumentPrivate::leftCursorPosition(int position) const
{
QTextBlock it = blocksFind(position);
int start = it.position();
return it.layout()->leftCursorPosition(position-start) + start;
}
int QTextDocumentPrivate::rightCursorPosition(int position) const
{
QTextBlock it = blocksFind(position);
int start = it.position();
return it.layout()->rightCursorPosition(position-start) + start;
}
void QTextDocumentPrivate::changeObjectFormat(QTextObject *obj, int format)
{
beginEditBlock();

View File

@ -64,6 +64,7 @@
#include "private/qtextformat_p.h"
#include "QtGui/qtextdocument.h"
#include "QtGui/qtextobject.h"
#include "QtGui/qtextcursor.h"
#include "QtCore/qmap.h"
#include "QtCore/qvariant.h"
#include "QtCore/qurl.h"
@ -244,6 +245,8 @@ public:
int nextCursorPosition(int position, QTextLayout::CursorMode mode) const;
int previousCursorPosition(int position, QTextLayout::CursorMode mode) const;
int leftCursorPosition(int position) const;
int rightCursorPosition(int position) const;
void changeObjectFormat(QTextObject *group, int format);
@ -339,6 +342,7 @@ private:
public:
QTextOption defaultTextOption;
QTextCursor::MoveStyle defaultCursorMoveStyle;
#ifndef QT_NO_CSSPARSER
QCss::StyleSheet parsedDefaultStyleSheet;
#endif

View File

@ -2996,10 +2996,19 @@ void QTextDocumentLayout::resizeInlineObject(QTextInlineObject item, int posInDo
QSizeF inlineSize = (pos == QTextFrameFormat::InFlow ? intrinsic : QSizeF(0, 0));
item.setWidth(inlineSize.width());
if (f.verticalAlignment() == QTextCharFormat::AlignMiddle) {
QFontMetrics m(f.font());
switch (f.verticalAlignment())
{
case QTextCharFormat::AlignMiddle:
item.setDescent(inlineSize.height() / 2);
item.setAscent(inlineSize.height() / 2 - 1);
} else {
break;
case QTextCharFormat::AlignBaseline:
item.setDescent(m.descent());
item.setAscent(inlineSize.height() - m.descent() - 1);
break;
default:
item.setDescent(0);
item.setAscent(inlineSize.height() - 1);
}

View File

@ -856,6 +856,21 @@ void QTextEngine::shapeLine(const QScriptLine &line)
}
}
#if !defined(QT_ENABLE_HARFBUZZ_FOR_MAC)
static bool enableHarfBuzz()
{
static enum { Yes, No, Unknown } status = Unknown;
if (status == Unknown) {
QByteArray v = qgetenv("QT_ENABLE_HARFBUZZ");
bool value = !v.isEmpty() && v != "0" && v != "false";
if (value) status = Yes;
else status = No;
}
return status == Yes;
}
#endif
void QTextEngine::shapeText(int item) const
{
Q_ASSERT(item < layoutData->items.size());
@ -865,7 +880,24 @@ void QTextEngine::shapeText(int item) const
return;
#if defined(Q_WS_MAC)
#if !defined(QT_ENABLE_HARFBUZZ_FOR_MAC)
if (enableHarfBuzz()) {
#endif
QFontEngine *actualFontEngine = fontEngine(si, &si.ascent, &si.descent, &si.leading);
if (actualFontEngine->type() == QFontEngine::Multi)
actualFontEngine = static_cast<QFontEngineMulti *>(actualFontEngine)->engine(0);
HB_Face face = actualFontEngine->harfbuzzFace();
HB_Script script = (HB_Script) si.analysis.script;
if (face->supported_scripts[script])
shapeTextWithHarfbuzz(item);
else
shapeTextMac(item);
#if !defined(QT_ENABLE_HARFBUZZ_FOR_MAC)
} else {
shapeTextMac(item);
}
#endif
#elif defined(Q_WS_WINCE)
shapeTextWithCE(item);
#else
@ -1242,6 +1274,10 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const
actualFontEngine = static_cast<QFontEngineMulti *>(font)->engine(engineIdx);
}
si.ascent = qMax(actualFontEngine->ascent(), si.ascent);
si.descent = qMax(actualFontEngine->descent(), si.descent);
si.leading = qMax(actualFontEngine->leading(), si.leading);
shaper_item.font = actualFontEngine->harfbuzzFont();
shaper_item.face = actualFontEngine->harfbuzzFace();
@ -1304,6 +1340,7 @@ static void init(QTextEngine *e)
e->ignoreBidi = false;
e->cacheGlyphs = false;
e->forceJustification = false;
e->visualMovement = false;
e->layoutData = 0;
@ -1565,6 +1602,8 @@ bool QTextEngine::isRightToLeft() const
default:
break;
}
if (!layoutData)
itemize();
// this places the cursor in the right position depending on the keyboard layout
if (layoutData->string.isEmpty())
return QApplication::keyboardInputDirection() == Qt::RightToLeft;
@ -2737,6 +2776,182 @@ QFixed QTextEngine::leadingSpaceWidth(const QScriptLine &line)
return width(line.from + pos, line.length - pos);
}
QFixed QTextEngine::alignLine(const QScriptLine &line)
{
QFixed x = 0;
justify(line);
// if width is QFIXED_MAX that means we used setNumColumns() and that implicitly makes this line left aligned.
if (!line.justified && line.width != QFIXED_MAX) {
int align = option.alignment();
if (align & Qt::AlignLeft)
x -= leadingSpaceWidth(line);
if (align & Qt::AlignJustify && isRightToLeft())
align = Qt::AlignRight;
if (align & Qt::AlignRight)
x = line.width - (line.textAdvance + leadingSpaceWidth(line));
else if (align & Qt::AlignHCenter)
x = (line.width - (line.textAdvance + leadingSpaceWidth(line)))/2;
}
return x;
}
QFixed QTextEngine::offsetInLigature(const QScriptItem *si, int pos, int max, int glyph_pos)
{
unsigned short *logClusters = this->logClusters(si);
const QGlyphLayout &glyphs = shapedGlyphs(si);
int offsetInCluster = 0;
for (int i = pos - 1; i >= 0; i--) {
if (logClusters[i] == glyph_pos)
offsetInCluster++;
else
break;
}
// in the case that the offset is inside a (multi-character) glyph,
// interpolate the position.
if (offsetInCluster > 0) {
int clusterLength = 0;
for (int i = pos - offsetInCluster; i < max; i++) {
if (logClusters[i] == glyph_pos)
clusterLength++;
else
break;
}
if (clusterLength)
return glyphs.advances_x[glyph_pos] * offsetInCluster / clusterLength;
}
return 0;
}
int QTextEngine::previousLogicalPosition(int oldPos) const
{
const HB_CharAttributes *attrs = attributes();
if (!attrs || oldPos < 0)
return oldPos;
if (oldPos <= 0)
return 0;
oldPos--;
while (oldPos && !attrs[oldPos].charStop)
oldPos--;
return oldPos;
}
int QTextEngine::nextLogicalPosition(int oldPos) const
{
const HB_CharAttributes *attrs = attributes();
int len = block.isValid() ? block.length() - 1
: layoutData->string.length();
Q_ASSERT(len <= layoutData->string.length());
if (!attrs || oldPos < 0 || oldPos >= len)
return oldPos;
oldPos++;
while (oldPos < len && !attrs[oldPos].charStop)
oldPos++;
return oldPos;
}
int QTextEngine::lineNumberForTextPosition(int pos)
{
if (!layoutData)
itemize();
if (pos == layoutData->string.length() && lines.size())
return lines.size() - 1;
for (int i = 0; i < lines.size(); ++i) {
const QScriptLine& line = lines[i];
if (line.from + line.length > pos)
return i;
}
return -1;
}
void QTextEngine::insertionPointsForLine(int lineNum, QVector<int> &insertionPoints)
{
QTextLineItemIterator iterator(this, lineNum);
bool rtl = isRightToLeft();
bool lastLine = lineNum >= lines.size() - 1;
while (!iterator.atEnd()) {
iterator.next();
const QScriptItem *si = &layoutData->items[iterator.item];
if (si->analysis.bidiLevel % 2) {
int i = iterator.itemEnd - 1, min = iterator.itemStart;
if (lastLine && (rtl ? iterator.atBeginning() : iterator.atEnd()))
i++;
for (; i >= min; i--)
insertionPoints.push_back(i);
} else {
int i = iterator.itemStart, max = iterator.itemEnd;
if (lastLine && (rtl ? iterator.atBeginning() : iterator.atEnd()))
max++;
for (; i < max; i++)
insertionPoints.push_back(i);
}
}
}
int QTextEngine::endOfLine(int lineNum)
{
QVector<int> insertionPoints;
insertionPointsForLine(lineNum, insertionPoints);
if (insertionPoints.size() > 0)
return insertionPoints.last();
return 0;
}
int QTextEngine::beginningOfLine(int lineNum)
{
QVector<int> insertionPoints;
insertionPointsForLine(lineNum, insertionPoints);
if (insertionPoints.size() > 0)
return insertionPoints.first();
return 0;
}
int QTextEngine::positionAfterVisualMovement(int pos, QTextCursor::MoveOperation op)
{
if (!layoutData)
itemize();
bool moveRight = (op == QTextCursor::Right);
bool alignRight = isRightToLeft();
if (!layoutData->hasBidi)
return moveRight ^ alignRight ? nextLogicalPosition(pos) : previousLogicalPosition(pos);
int lineNum = lineNumberForTextPosition(pos);
Q_ASSERT(lineNum >= 0);
QVector<int> insertionPoints;
insertionPointsForLine(lineNum, insertionPoints);
int i, max = insertionPoints.size();
for (i = 0; i < max; i++)
if (pos == insertionPoints[i]) {
if (moveRight) {
if (i + 1 < max)
return insertionPoints[i + 1];
} else {
if (i > 0)
return insertionPoints[i - 1];
}
if (moveRight ^ alignRight) {
if (lineNum + 1 < lines.size())
return alignRight ? endOfLine(lineNum + 1) : beginningOfLine(lineNum + 1);
}
else {
if (lineNum > 0)
return alignRight ? beginningOfLine(lineNum - 1) : endOfLine(lineNum - 1);
}
}
return pos;
}
QStackTextEngine::QStackTextEngine(const QString &string, const QFont &f)
: QTextEngine(string, f),
_layoutData(string, _memory, MemSize)
@ -2841,5 +3056,127 @@ glyph_metrics_t glyph_metrics_t::transformed(const QTransform &matrix) const
return m;
}
QTextLineItemIterator::QTextLineItemIterator(QTextEngine *_eng, int _lineNum, const QPointF &pos,
const QTextLayout::FormatRange *_selection)
: eng(_eng),
line(eng->lines[_lineNum]),
si(0),
lineNum(_lineNum),
lineEnd(line.from + line.length),
firstItem(eng->findItem(line.from)),
lastItem(eng->findItem(lineEnd - 1)),
nItems((firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0),
logicalItem(-1),
item(-1),
visualOrder(nItems),
levels(nItems),
selection(_selection)
{
pos_x = x = QFixed::fromReal(pos.x());
x += line.x;
x += eng->alignLine(line);
for (int i = 0; i < nItems; ++i)
levels[i] = eng->layoutData->items[i+firstItem].analysis.bidiLevel;
QTextEngine::bidiReorder(nItems, levels.data(), visualOrder.data());
eng->shapeLine(line);
}
QScriptItem &QTextLineItemIterator::next()
{
x += itemWidth;
++logicalItem;
item = visualOrder[logicalItem] + firstItem;
itemLength = eng->length(item);
si = &eng->layoutData->items[item];
if (!si->num_glyphs)
eng->shape(item);
if (si->analysis.flags >= QScriptAnalysis::TabOrObject) {
itemWidth = si->width;
return *si;
}
unsigned short *logClusters = eng->logClusters(si);
QGlyphLayout glyphs = eng->shapedGlyphs(si);
itemStart = qMax(line.from, si->position);
glyphsStart = logClusters[itemStart - si->position];
if (lineEnd < si->position + itemLength) {
itemEnd = lineEnd;
glyphsEnd = logClusters[itemEnd-si->position];
} else {
itemEnd = si->position + itemLength;
glyphsEnd = si->num_glyphs;
}
// show soft-hyphen at line-break
if (si->position + itemLength >= lineEnd
&& eng->layoutData->string.at(lineEnd - 1) == 0x00ad)
glyphs.attributes[glyphsEnd - 1].dontPrint = false;
itemWidth = 0;
for (int g = glyphsStart; g < glyphsEnd; ++g)
itemWidth += glyphs.effectiveAdvance(g);
return *si;
}
bool QTextLineItemIterator::getSelectionBounds(QFixed *selectionX, QFixed *selectionWidth) const
{
*selectionX = *selectionWidth = 0;
if (!selection)
return false;
if (si->analysis.flags >= QScriptAnalysis::TabOrObject) {
if (si->position >= selection->start + selection->length
|| si->position + itemLength <= selection->start)
return false;
*selectionX = x;
*selectionWidth = itemWidth;
} else {
unsigned short *logClusters = eng->logClusters(si);
QGlyphLayout glyphs = eng->shapedGlyphs(si);
int from = qMax(itemStart, selection->start) - si->position;
int to = qMin(itemEnd, selection->start + selection->length) - si->position;
if (from >= to)
return false;
int start_glyph = logClusters[from];
int end_glyph = (to == eng->length(item)) ? si->num_glyphs : logClusters[to];
QFixed soff;
QFixed swidth;
if (si->analysis.bidiLevel %2) {
for (int g = glyphsEnd - 1; g >= end_glyph; --g)
soff += glyphs.effectiveAdvance(g);
for (int g = end_glyph - 1; g >= start_glyph; --g)
swidth += glyphs.effectiveAdvance(g);
} else {
for (int g = glyphsStart; g < start_glyph; ++g)
soff += glyphs.effectiveAdvance(g);
for (int g = start_glyph; g < end_glyph; ++g)
swidth += glyphs.effectiveAdvance(g);
}
// If the starting character is in the middle of a ligature,
// selection should only contain the right part of that ligature
// glyph, so we need to get the width of the left part here and
// add it to *selectionX
QFixed leftOffsetInLigature = eng->offsetInLigature(si, from, to, start_glyph);
*selectionX = x + soff + leftOffsetInLigature;
*selectionWidth = swidth - leftOffsetInLigature;
// If the ending character is also part of a ligature, swidth does
// not contain that part yet, we also need to find out the width of
// that left part
*selectionWidth += eng->offsetInLigature(si, to, eng->length(item), end_glyph);
}
return true;
}
QT_END_NAMESPACE

View File

@ -605,11 +605,11 @@ void QTextEngine::shapeTextMac(int item) const
unsigned short *log_clusters = logClusters(&si);
bool stringToCMapFailed = false;
if (!fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters, attributes())) {
if (!fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters, attributes(), &si)) {
ensureSpace(num_glyphs);
g = availableGlyphs(&si);
stringToCMapFailed = !fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters,
attributes());
attributes(), &si);
}
if (!stringToCMapFailed) {

View File

@ -64,6 +64,7 @@
#include "QtGui/qpaintengine.h"
#include "QtGui/qtextobject.h"
#include "QtGui/qtextoption.h"
#include "QtGui/qtextcursor.h"
#include "QtCore/qset.h"
#include "QtCore/qdebug.h"
#ifndef QT_BUILD_COMPAT_LIB
@ -471,6 +472,7 @@ public:
void shape(int item) const;
void justify(const QScriptLine &si);
QFixed alignLine(const QScriptLine &line);
QFixed width(int charFrom, int numChars) const;
glyph_metrics_t boundingBox(int from, int len) const;
@ -586,12 +588,18 @@ public:
uint cacheGlyphs : 1;
uint stackEngine : 1;
uint forceJustification : 1;
uint visualMovement : 1;
int *underlinePositions;
mutable LayoutData *layoutData;
inline bool hasFormats() const { return (block.docHandle() || specialData); }
inline bool visualCursorMovement() const
{
return (visualMovement ||
(block.docHandle() ? block.docHandle()->defaultCursorMoveStyle == QTextCursor::Visual : false));
}
struct SpecialData {
int preeditPosition;
@ -611,6 +619,13 @@ public:
void shapeLine(const QScriptLine &line);
QFixed leadingSpaceWidth(const QScriptLine &line);
QFixed offsetInLigature(const QScriptItem *si, int pos, int max, int glyph_pos);
int previousLogicalPosition(int oldPos) const;
int nextLogicalPosition(int oldPos) const;
int lineNumberForTextPosition(int pos);
int positionAfterVisualMovement(int oldPos, QTextCursor::MoveOperation op);
void insertionPointsForLine(int lineNum, QVector<int> &insertionPoints);
private:
void setBoundary(int strPos) const;
void addRequiredBoundaries() const;
@ -625,6 +640,8 @@ private:
void splitItem(int item, int pos) const;
void resolveAdditionalFormats() const;
int endOfLine(int lineNum);
int beginningOfLine(int lineNum);
};
class QStackTextEngine : public QTextEngine {
@ -635,6 +652,49 @@ public:
void *_memory[MemSize];
};
struct QTextLineItemIterator
{
QTextLineItemIterator(QTextEngine *eng, int lineNum, const QPointF &pos = QPointF(),
const QTextLayout::FormatRange *_selection = 0);
inline bool atEnd() const { return logicalItem >= nItems - 1; }
inline bool atBeginning() const { return logicalItem <= 0; }
QScriptItem &next();
bool getSelectionBounds(QFixed *selectionX, QFixed *selectionWidth) const;
inline bool isOutsideSelection() const {
QFixed tmp1, tmp2;
return !getSelectionBounds(&tmp1, &tmp2);
}
QTextEngine *eng;
QFixed x;
QFixed pos_x;
const QScriptLine &line;
QScriptItem *si;
int lineNum;
int lineEnd;
int firstItem;
int lastItem;
int nItems;
int logicalItem;
int item;
int itemLength;
int glyphsStart;
int glyphsEnd;
int itemStart;
int itemEnd;
QFixed itemWidth;
QVarLengthArray<int> visualOrder;
QVarLengthArray<uchar> levels;
const QTextLayout::FormatRange *selection;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QTextEngine::ShaperFlags)

View File

@ -378,7 +378,8 @@ public:
AlignSubScript,
AlignMiddle,
AlignTop,
AlignBottom
AlignBottom,
AlignBaseline
};
enum UnderlineStyle { // keep in sync with Qt::PenStyle!
NoUnderline,

View File

@ -72,23 +72,6 @@ QT_BEGIN_NAMESPACE
#define SuppressText 0x5012
#define SuppressBackground 0x513
static QFixed alignLine(QTextEngine *eng, const QScriptLine &line)
{
QFixed x = 0;
eng->justify(line);
// if width is QFIXED_MAX that means we used setNumColumns() and that implicitly makes this line left aligned.
if (!line.justified && line.width != QFIXED_MAX) {
int align = eng->option.alignment();
if (align & Qt::AlignJustify && eng->isRightToLeft())
align = Qt::AlignRight;
if (align & Qt::AlignRight)
x = line.width - (line.textAdvance + eng->leadingSpaceWidth(line));
else if (align & Qt::AlignHCenter)
x = (line.width - line.textAdvance)/2;
}
return x;
}
/*!
\class QTextLayout::FormatRange
\reentrant
@ -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<int> visualOrder;
QVarLengthArray<uchar> levels;
const QTextLayout::FormatRange *selection;
};
QTextLineItemIterator::QTextLineItemIterator(QTextEngine *_eng, int lineNum, const QPointF &pos,
const QTextLayout::FormatRange *_selection)
: eng(_eng),
line(eng->lines[lineNum]),
si(0),
lineEnd(line.from + line.length),
firstItem(eng->findItem(line.from)),
lastItem(eng->findItem(lineEnd - 1)),
nItems((firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0),
logicalItem(-1),
item(-1),
visualOrder(nItems),
levels(nItems),
selection(_selection)
{
pos_x = x = QFixed::fromReal(pos.x());
x += line.x;
x += alignLine(eng, line);
for (int i = 0; i < nItems; ++i)
levels[i] = eng->layoutData->items[i+firstItem].analysis.bidiLevel;
QTextEngine::bidiReorder(nItems, levels.data(), visualOrder.data());
eng->shapeLine(line);
}
QScriptItem &QTextLineItemIterator::next()
{
x += itemWidth;
++logicalItem;
item = visualOrder[logicalItem] + firstItem;
itemLength = eng->length(item);
si = &eng->layoutData->items[item];
if (!si->num_glyphs)
eng->shape(item);
if (si->analysis.flags >= QScriptAnalysis::TabOrObject) {
itemWidth = si->width;
return *si;
}
unsigned short *logClusters = eng->logClusters(si);
QGlyphLayout glyphs = eng->shapedGlyphs(si);
itemStart = qMax(line.from, si->position);
glyphsStart = logClusters[itemStart - si->position];
if (lineEnd < si->position + itemLength) {
itemEnd = lineEnd;
glyphsEnd = logClusters[itemEnd-si->position];
} else {
itemEnd = si->position + itemLength;
glyphsEnd = si->num_glyphs;
}
// show soft-hyphen at line-break
if (si->position + itemLength >= lineEnd
&& eng->layoutData->string.at(lineEnd - 1) == 0x00ad)
glyphs.attributes[glyphsEnd - 1].dontPrint = false;
itemWidth = 0;
for (int g = glyphsStart; g < glyphsEnd; ++g)
itemWidth += glyphs.effectiveAdvance(g);
return *si;
}
static QFixed offsetInLigature(const unsigned short *logClusters,
const QGlyphLayout &glyphs,
int pos, int max, int glyph_pos)
{
int offsetInCluster = 0;
for (int i = pos - 1; i >= 0; i--) {
if (logClusters[i] == glyph_pos)
offsetInCluster++;
else
break;
}
// in the case that the offset is inside a (multi-character) glyph,
// interpolate the position.
if (offsetInCluster > 0) {
int clusterLength = 0;
for (int i = pos - offsetInCluster; i < max; i++) {
if (logClusters[i] == glyph_pos)
clusterLength++;
else
break;
}
if (clusterLength)
return glyphs.advances_x[glyph_pos] * offsetInCluster / clusterLength;
}
return 0;
}
bool QTextLineItemIterator::getSelectionBounds(QFixed *selectionX, QFixed *selectionWidth) const
{
*selectionX = *selectionWidth = 0;
if (!selection)
return false;
if (si->analysis.flags >= QScriptAnalysis::TabOrObject) {
if (si->position >= selection->start + selection->length
|| si->position + itemLength <= selection->start)
return false;
*selectionX = x;
*selectionWidth = itemWidth;
} else {
unsigned short *logClusters = eng->logClusters(si);
QGlyphLayout glyphs = eng->shapedGlyphs(si);
int from = qMax(itemStart, selection->start) - si->position;
int to = qMin(itemEnd, selection->start + selection->length) - si->position;
if (from >= to)
return false;
int start_glyph = logClusters[from];
int end_glyph = (to == eng->length(item)) ? si->num_glyphs : logClusters[to];
QFixed soff;
QFixed swidth;
if (si->analysis.bidiLevel %2) {
for (int g = glyphsEnd - 1; g >= end_glyph; --g)
soff += glyphs.effectiveAdvance(g);
for (int g = end_glyph - 1; g >= start_glyph; --g)
swidth += glyphs.effectiveAdvance(g);
} else {
for (int g = glyphsStart; g < start_glyph; ++g)
soff += glyphs.effectiveAdvance(g);
for (int g = start_glyph; g < end_glyph; ++g)
swidth += glyphs.effectiveAdvance(g);
}
// If the starting character is in the middle of a ligature,
// selection should only contain the right part of that ligature
// glyph, so we need to get the width of the left part here and
// add it to *selectionX
QFixed leftOffsetInLigature = offsetInLigature(logClusters, glyphs, from,
to, start_glyph);
*selectionX = x + soff + leftOffsetInLigature;
*selectionWidth = swidth - leftOffsetInLigature;
// If the ending character is also part of a ligature, swidth does
// not contain that part yet, we also need to find out the width of
// that left part
*selectionWidth += offsetInLigature(logClusters, glyphs, to,
eng->length(item), end_glyph);
}
return true;
}
static void addSelectedRegionsToPath(QTextEngine *eng, int lineNumber, const QPointF &pos, QTextLayout::FormatRange *selection,
QPainterPath *region, QRectF boundingRect)
{
@ -1228,6 +1060,7 @@ void QTextLayout::draw(QPainter *p, const QPointF &pos, const QVector<FormatRang
QRectF lineRect(tl.naturalTextRect());
lineRect.translate(position);
lineRect.adjust(0, 0, d->leadingSpaceWidth(sl).toReal(), 0);
bool isLastLineInBlock = (line == d->lines.size()-1);
int sl_length = sl.length + (isLastLineInBlock? 1 : 0); // the infamous newline
@ -1382,18 +1215,9 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition
QFixed pos_y = QFixed::fromReal(position.y());
cursorPosition = qBound(0, cursorPosition, d->layoutData->string.length());
int line = 0;
if (cursorPosition == d->layoutData->string.length()) {
line = d->lines.size() - 1;
} else {
// ### binary search
for (line = 0; line < d->lines.size(); line++) {
const QScriptLine &sl = d->lines[line];
if (sl.from <= cursorPosition && sl.from + (int)sl.length > cursorPosition)
break;
}
}
int line = d->lineNumberForTextPosition(cursorPosition);
if (line < 0)
line = 0;
if (line >= d->lines.size())
return;
@ -1402,7 +1226,15 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition
qreal x = position.x() + l.cursorToX(cursorPosition);
int itm = d->findItem(cursorPosition - 1);
int itm;
if (d->visualCursorMovement()) {
if (cursorPosition == sl.from + sl.length)
cursorPosition--;
itm = d->findItem(cursorPosition);
} else
itm = d->findItem(cursorPosition - 1);
QFixed base = sl.base();
QFixed descent = sl.descent;
bool rightToLeft = d->isRightToLeft();
@ -1512,7 +1344,7 @@ QRectF QTextLine::rect() const
QRectF QTextLine::naturalTextRect() const
{
const QScriptLine& sl = eng->lines[i];
QFixed x = sl.x + alignLine(eng, sl);
QFixed x = sl.x + eng->alignLine(sl);
QFixed width = sl.textWidth;
if (sl.justified)
@ -2317,6 +2149,9 @@ QList<QGlyphs> QTextLine::glyphs(int from, int length) const
QGlyphLayout subLayout = glyphLayout.mid(start, end - start);
glyphLayoutHash.insertMulti(multiFontEngine->engine(which),
GlyphInfo(subLayout, pos, flags));
for (int i = 0; i < subLayout.numGlyphs; i++)
pos += QPointF(subLayout.advances_x[i].toReal(),
subLayout.advances_y[i].toReal());
start = end;
which = e;
@ -2632,9 +2467,10 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
eng->itemize();
const QScriptLine &line = eng->lines[i];
bool lastLine = i >= eng->lines.size() - 1;
QFixed x = line.x;
x += alignLine(eng, line);
x += eng->alignLine(line);
if (!i && !eng->layoutData->items.size()) {
*cursorPos = 0;
@ -2720,21 +2556,29 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
logClusters = eng->logClusters(si);
glyphs = eng->shapedGlyphs(si);
if (si->analysis.flags >= QScriptAnalysis::TabOrObject) {
if(pos == l)
if (pos == (reverse ? 0 : l))
x += si->width;
} else {
bool rtl = eng->isRightToLeft();
bool visual = eng->visualCursorMovement();
if (reverse) {
int end = qMin(lineEnd, si->position + l) - si->position;
int glyph_end = end == l ? si->num_glyphs : logClusters[end];
for (int i = glyph_end - 1; i >= glyph_pos; i--)
int glyph_start = glyph_pos;
if (visual && !rtl && !(lastLine && itm == (visualOrder[nItems - 1] + firstItem)))
glyph_start++;
for (int i = glyph_end - 1; i >= glyph_start; i--)
x += glyphs.effectiveAdvance(i);
} else {
int start = qMax(line.from - si->position, 0);
int glyph_start = logClusters[start];
for (int i = glyph_start; i < glyph_pos; i++)
int glyph_end = glyph_pos;
if (!visual || !rtl || (lastLine && itm == visualOrder[0] + firstItem))
glyph_end--;
for (int i = glyph_start; i <= glyph_end; i++)
x += glyphs.effectiveAdvance(i);
}
x += offsetInLigature(logClusters, glyphs, pos, line.length, glyph_pos);
x += eng->offsetInLigature(si, pos, line.length, glyph_pos);
}
*cursorPos = pos + si->position;
@ -2753,6 +2597,8 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
{
QFixed x = QFixed::fromReal(_x);
const QScriptLine &line = eng->lines[i];
bool lastLine = i >= eng->lines.size() - 1;
int lineNum = i;
if (!eng->layoutData)
eng->itemize();
@ -2770,7 +2616,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
return 0;
x -= line.x;
x -= alignLine(eng, line);
x -= eng->alignLine(line);
// qDebug("xToCursor: x=%f, cpos=%d", x.toReal(), cpos);
QVarLengthArray<int> visualOrder(nItems);
@ -2779,6 +2625,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
levels[i] = eng->layoutData->items[i+firstItem].analysis.bidiLevel;
QTextEngine::bidiReorder(nItems, levels.data(), visualOrder.data());
bool visual = eng->visualCursorMovement();
if (x <= 0) {
// left of first item
int item = visualOrder[0]+firstItem;
@ -2795,8 +2642,13 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
|| (line.justified && x < line.width)) {
// has to be in one of the runs
QFixed pos;
bool rtl = eng->isRightToLeft();
eng->shapeLine(line);
QVector<int> insertionPoints;
if (visual && rtl)
eng->insertionPointsForLine(lineNum, insertionPoints);
int nchars = 0;
for (int i = 0; i < nItems; ++i) {
int item = visualOrder[i]+firstItem;
QScriptItem &si = eng->layoutData->items[item];
@ -2826,6 +2678,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
if (pos + item_width < x) {
pos += item_width;
nchars += end;
continue;
}
// qDebug(" inside run");
@ -2870,6 +2723,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
} else {
QFixed dist = INT_MAX/256;
if (si.analysis.bidiLevel % 2) {
if (!visual || rtl || (lastLine && i == nItems - 1)) {
pos += item_width;
while (gs <= ge) {
if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) {
@ -2880,6 +2734,17 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
++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;
}
}
} else {
if (!visual || !rtl || (lastLine && i == 0)) {
while (gs <= ge) {
if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) {
glyph_pos = gs;
@ -2888,10 +2753,31 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
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 (visual) {
if (!rtl && i < nItems - 1) {
nchars += end;
continue;
}
if (rtl && nchars > 0)
return insertionPoints[lastLine ? nchars : nchars - 1];
}
if (qAbs(x-pos) < dist)
return si.position + end;
}
}
Q_ASSERT(glyph_pos != -1);
int j;
for (j = 0; j < eng->length(item); ++j)

View File

@ -50,6 +50,7 @@
#include <QtGui/qevent.h>
#include <QtGui/qtextformat.h>
#include <QtGui/qglyphs.h>
#include <QtGui/qtextcursor.h>
QT_BEGIN_HEADER
@ -136,6 +137,9 @@ public:
void setCacheEnabled(bool enable);
bool cacheEnabled() const;
void setCursorMoveStyle(QTextCursor::MoveStyle style);
QTextCursor::MoveStyle cursorMoveStyle() const;
void beginLayout();
void endLayout();
void clearLayout();
@ -153,6 +157,8 @@ public:
bool isValidCursorPosition(int pos) const;
int nextCursorPosition(int oldPos, CursorMode mode = SkipCharacters) const;
int previousCursorPosition(int oldPos, CursorMode mode = SkipCharacters) const;
int leftCursorPosition(int oldPos) const;
int rightCursorPosition(int oldPos) const;
void draw(QPainter *p, const QPointF &pos, const QVector<FormatRange> &selections = QVector<FormatRange>(),
const QRectF &clip = QRectF()) const;

View File

@ -114,6 +114,9 @@ unix:x11 {
OBJECTIVE_SOURCES += \
text/qfontengine_coretext.mm \
text/qfontengine_mac.mm
contains(QT_CONFIG, harfbuzz) {
DEFINES += QT_ENABLE_HARFBUZZ_FOR_MAC
}
}
embedded {
@ -136,7 +139,8 @@ qpa {
SOURCES += \
text/qfont_qpa.cpp \
text/qfontengine_qpa.cpp \
text/qplatformfontdatabase_qpa.cpp
text/qplatformfontdatabase_qpa.cpp \
text/qrawfont_qpa.cpp
HEADERS += \
text/qplatformfontdatabase_qpa.h

View File

@ -1585,6 +1585,7 @@ void QLineControl::processKeyEvent(QKeyEvent* event)
}
bool unknown = false;
bool visual = cursorMoveStyle() == QTextCursor::Visual;
if (false) {
}
@ -1649,11 +1650,11 @@ void QLineControl::processKeyEvent(QKeyEvent* event)
#endif
moveCursor(selectionEnd(), false);
} else {
cursorForward(0, layoutDirection() == Qt::LeftToRight ? 1 : -1);
cursorForward(0, visual ? 1 : (layoutDirection() == Qt::LeftToRight ? 1 : -1));
}
}
else if (event == QKeySequence::SelectNextChar) {
cursorForward(1, layoutDirection() == Qt::LeftToRight ? 1 : -1);
cursorForward(1, visual ? 1 : (layoutDirection() == Qt::LeftToRight ? 1 : -1));
}
else if (event == QKeySequence::MoveToPreviousChar) {
#if !defined(Q_WS_WIN) || defined(QT_NO_COMPLETER)
@ -1664,11 +1665,11 @@ void QLineControl::processKeyEvent(QKeyEvent* event)
#endif
moveCursor(selectionStart(), false);
} else {
cursorForward(0, layoutDirection() == Qt::LeftToRight ? -1 : 1);
cursorForward(0, visual ? -1 : (layoutDirection() == Qt::LeftToRight ? -1 : 1));
}
}
else if (event == QKeySequence::SelectPreviousChar) {
cursorForward(1, layoutDirection() == Qt::LeftToRight ? -1 : 1);
cursorForward(1, visual ? -1 : (layoutDirection() == Qt::LeftToRight ? -1 : 1));
}
else if (event == QKeySequence::MoveToNextWord) {
if (echoMode() == QLineEdit::Normal)

View File

@ -160,6 +160,8 @@ public:
int cursorWidth() const { return m_cursorWidth; }
void setCursorWidth(int value) { m_cursorWidth = value; }
QTextCursor::MoveStyle cursorMoveStyle() const { return m_textLayout.cursorMoveStyle(); }
void setCursorMoveStyle(QTextCursor::MoveStyle style) { m_textLayout.setCursorMoveStyle(style); }
void moveCursor(int pos, bool mark = false);
void cursorForward(bool mark, int steps)
@ -167,10 +169,12 @@ public:
int c = m_cursor;
if (steps > 0) {
while (steps--)
c = m_textLayout.nextCursorPosition(c);
c = cursorMoveStyle() == QTextCursor::Visual ? m_textLayout.rightCursorPosition(c)
: m_textLayout.nextCursorPosition(c);
} else if (steps < 0) {
while (steps++)
c = m_textLayout.previousCursorPosition(c);
c = cursorMoveStyle() == QTextCursor::Visual ? m_textLayout.leftCursorPosition(c)
: m_textLayout.previousCursorPosition(c);
}
moveCursor(c, mark);
}

View File

@ -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

View File

@ -43,6 +43,7 @@
#define QLINEEDIT_H
#include <QtGui/qframe.h>
#include <QtGui/qtextcursor.h>
#include <QtCore/qstring.h>
#include <QtCore/qmargins.h>
@ -158,6 +159,9 @@ public:
void setDragEnabled(bool b);
bool dragEnabled() const;
void setCursorMoveStyle(QTextCursor::MoveStyle style);
QTextCursor::MoveStyle cursorMoveStyle() const;
QString inputMask() const;
void setInputMask(const QString &inputMask);
bool hasAcceptableInput() const;

View File

@ -1548,6 +1548,14 @@ namespace {
}
#if defined(Q_WS_WIN)
static bool fontSmoothingApproximately(qreal target)
{
extern Q_GUI_EXPORT qreal qt_fontsmoothing_gamma; // qapplication_win.cpp
return (qAbs(qt_fontsmoothing_gamma - target) < 0.2);
}
#endif
// #define QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO
void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyphType,
@ -1786,7 +1794,6 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp
shaderManager->setMaskType(QGLEngineShaderManager::PixelMask);
prepareForDraw(false); // Text always causes src pixels to be transparent
}
//### TODO: Gamma correction
QGLTextureGlyphCache::FilterMode filterMode = (s->matrix.type() > QTransform::TxTranslate)?QGLTextureGlyphCache::Linear:QGLTextureGlyphCache::Nearest;
if (lastMaskTextureUsed != cache->texture() || cache->filterMode() != filterMode) {
@ -1809,12 +1816,31 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp
}
}
bool srgbFrameBufferEnabled = false;
if (ctx->d_ptr->extension_flags & QGLExtensions::SRGBFrameBuffer) {
#if defined(Q_WS_MAC)
if (glyphType == QFontEngineGlyphCache::Raster_RGBMask)
#elif defined(Q_WS_WIN)
if (glyphType != QFontEngineGlyphCache::Raster_RGBMask || fontSmoothingApproximately(2.1))
#else
if (false)
#endif
{
glEnable(FRAMEBUFFER_SRGB_EXT);
srgbFrameBufferEnabled = true;
}
}
#if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO)
glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
#else
glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, elementIndices.data());
#endif
if (srgbFrameBufferEnabled)
glDisable(FRAMEBUFFER_SRGB_EXT);
}
void QGL2PaintEngineEx::drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap,
@ -1986,7 +2012,8 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
#if !defined(QT_OPENGL_ES_2)
#if defined(Q_WS_WIN)
if (qt_cleartype_enabled)
if (qt_cleartype_enabled
&& (fontSmoothingApproximately(1.0) || fontSmoothingApproximately(2.1)))
#endif
#if defined(Q_WS_MAC)
if (qt_applefontsmoothing_enabled)

View File

@ -1564,6 +1564,19 @@ QVertexSet<T> QTriangulator<T>::triangulate()
template <typename T>
QVertexSet<T> QTriangulator<T>::polyline()
{
for (int i = 0; i < m_vertices.size(); ++i) {
Q_ASSERT(qAbs(m_vertices.at(i).x) < (1 << 21));
Q_ASSERT(qAbs(m_vertices.at(i).y) < (1 << 21));
}
if (!(m_hint & (QVectorPath::OddEvenFill | QVectorPath::WindingFill)))
m_hint |= QVectorPath::OddEvenFill;
if (m_hint & QVectorPath::NonConvexShapeMask) {
ComplexToSimple c2s(this);
c2s.decompose();
}
QVertexSet<T> result;
result.indices = m_indices;
result.vertices.resize(2 * m_vertices.size());
@ -3084,7 +3097,7 @@ QPolylineSet qPolyline(const QVectorPath &path,
} else {
QTriangulator<quint16> triangulator;
triangulator.initialize(path, matrix, lod);
QVertexSet<quint16> vertexSet = triangulator.triangulate();
QVertexSet<quint16> vertexSet = triangulator.polyline();
polyLineSet.vertices = vertexSet.vertices;
polyLineSet.indices.setDataUshort(vertexSet.indices);
}
@ -3104,7 +3117,7 @@ QPolylineSet qPolyline(const QPainterPath &path,
} else {
QTriangulator<quint16> triangulator;
triangulator.initialize(path, matrix, lod);
QVertexSet<quint16> vertexSet = triangulator.triangulate();
QVertexSet<quint16> vertexSet = triangulator.polyline();
polyLineSet.vertices = vertexSet.vertices;
polyLineSet.indices.setDataUshort(vertexSet.indices);
}

View File

@ -58,7 +58,7 @@
QT_BEGIN_NAMESPACE
class QVertexIndexVector
class Q_OPENGL_EXPORT QVertexIndexVector
{
public:
enum Type {
@ -111,7 +111,7 @@ private:
QVector<quint16> indices16;
};
struct QTriangleSet
struct Q_OPENGL_EXPORT QTriangleSet
{
inline QTriangleSet() { }
inline QTriangleSet(const QTriangleSet &other) : vertices(other.vertices), indices(other.indices) { }
@ -122,14 +122,14 @@ struct QTriangleSet
QVertexIndexVector indices; // [i[0], j[0], k[0], i[1], j[1], k[1], i[2], ...]
};
struct QPolylineSet
struct Q_OPENGL_EXPORT QPolylineSet
{
inline QPolylineSet() { }
inline QPolylineSet(const QPolylineSet &other) : vertices(other.vertices), indices(other.indices) { }
QPolylineSet &operator = (const QPolylineSet &other) {vertices = other.vertices; indices = other.indices; return *this;}
QVector<qreal> vertices; // [x[0], y[0], x[1], y[1], x[2], ...]
QVertexIndexVector indices;
QVertexIndexVector indices; // End of polyline is marked with -1.
};
// The vertex coordinates of the returned triangle set will be rounded to a grid with a mesh size
@ -139,9 +139,9 @@ struct QPolylineSet
// 'lod' is the level of detail. Default is 1. Curves are split into more lines when 'lod' is higher.
QTriangleSet qTriangulate(const qreal *polygon, int count, uint hint = QVectorPath::PolygonHint | QVectorPath::OddEvenFill, const QTransform &matrix = QTransform());
QTriangleSet qTriangulate(const QVectorPath &path, const QTransform &matrix = QTransform(), qreal lod = 1);
QTriangleSet qTriangulate(const QPainterPath &path, const QTransform &matrix = QTransform(), qreal lod = 1);
QTriangleSet Q_OPENGL_EXPORT qTriangulate(const QPainterPath &path, const QTransform &matrix = QTransform(), qreal lod = 1);
QPolylineSet qPolyline(const QVectorPath &path, const QTransform &matrix = QTransform(), qreal lod = 1);
QPolylineSet qPolyline(const QPainterPath &path, const QTransform &matrix = QTransform(), qreal lod = 1);
QPolylineSet Q_OPENGL_EXPORT qPolyline(const QPainterPath &path, const QTransform &matrix = QTransform(), qreal lod = 1);
QT_END_NAMESPACE

View File

@ -43,6 +43,7 @@
#include "qplatformdefs.h"
#include "qgl.h"
#include <qdebug.h>
#include <qglfunctions.h>
#if defined(Q_WS_X11)
#include "private/qt_x11_p.h"
@ -1663,6 +1664,7 @@ const QGLContext *qt_gl_transfer_context(const QGLContext *ctx)
QGLContextPrivate::QGLContextPrivate(QGLContext *context)
: internal_context(false)
, q_ptr(context)
, functions(0)
{
group = new QGLContextGroup(context);
texture_destroyer = new QGLTextureDestroyer;
@ -1671,6 +1673,8 @@ QGLContextPrivate::QGLContextPrivate(QGLContext *context)
QGLContextPrivate::~QGLContextPrivate()
{
delete functions;
if (!group->m_refs.deref()) {
Q_ASSERT(group->context() == q_ptr);
delete group;
@ -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<QGLContextPrivate *>(d_func());
if (!d->functions) {
d->functions = new QGLFunctions(this);
d->functions->initializeGLFunctions(this);
}
return d->functions;
}
/*!
Generates and binds a 2D GL texture to the current context, based
on \a image. The generated texture id is returned and can be used in
@ -3792,6 +3809,20 @@ QGLWidget::QGLWidget(QWidget *parent, const QGLWidget* shareWidget, Qt::WindowFl
d->init(new QGLContext(QGLFormat::defaultFormat(), this), shareWidget);
}
/*!
\internal
*/
QGLWidget::QGLWidget(QGLWidgetPrivate &dd, const QGLFormat &format, QWidget *parent, const QGLWidget *shareWidget, Qt::WindowFlags f)
: QWidget(dd, parent, f | Qt::MSWindowsOwnDC)
{
Q_D(QGLWidget);
setAttribute(Qt::WA_PaintOnScreen);
setAttribute(Qt::WA_NoSystemBackground);
setAutoFillBackground(true); // for compatibility
d->init(new QGLContext(format, this), shareWidget);
}
/*!
Constructs an OpenGL widget with parent \a parent.
@ -5490,6 +5521,13 @@ QGLExtensions::Extensions QGLExtensions::currentContextExtensions()
if (extensions.match("GL_EXT_bgra"))
glExtensions |= BGRATextureFormat;
{
GLboolean srgbCapableFramebuffers;
glGetBooleanv(FRAMEBUFFER_SRGB_CAPABLE_EXT, &srgbCapableFramebuffers);
if (srgbCapableFramebuffers)
glExtensions |= SRGBFrameBuffer;
}
return glExtensions;
}

View File

@ -307,6 +307,8 @@ Q_OPENGL_EXPORT bool operator!=(const QGLFormat&, const QGLFormat&);
Q_OPENGL_EXPORT QDebug operator<<(QDebug, const QGLFormat &);
#endif
class QGLFunctions;
class Q_OPENGL_EXPORT QGLContext
{
Q_DECLARE_PRIVATE(QGLContext)
@ -332,6 +334,8 @@ public:
virtual void swapBuffers() const;
QGLFunctions *functions() const;
enum BindOption {
NoBindOption = 0x0000,
InvertedYBindOption = 0x0001,
@ -466,6 +470,7 @@ private:
friend class QX11GLPixmapData;
friend class QX11GLSharedContexts;
friend class QGLContextResourceBase;
friend class QSGDistanceFieldGlyphCache;
private:
Q_DISABLE_COPY(QGLContext)
};
@ -589,6 +594,11 @@ protected:
virtual void glDraw();
int fontDisplayListBase(const QFont & fnt, int listBase = 2000); // ### Qt 5: remove
QGLWidget(QGLWidgetPrivate &dd,
const QGLFormat &format = QGLFormat(),
QWidget *parent = 0,
const QGLWidget* shareWidget = 0,
Qt::WindowFlags f = 0);
private:
Q_DISABLE_COPY(QGLWidget)

View File

@ -159,7 +159,7 @@ public:
QGLFormat::OpenGLContextProfile profile;
};
class QGLWidgetPrivate : public QWidgetPrivate
class Q_OPENGL_EXPORT QGLWidgetPrivate : public QWidgetPrivate
{
Q_DECLARE_PUBLIC(QGLWidget)
public:
@ -288,7 +288,8 @@ public:
PVRTCTextureCompression = 0x00020000,
FragmentShader = 0x00040000,
ElementIndexUint = 0x00080000,
Depth24 = 0x00100000
Depth24 = 0x00100000,
SRGBFrameBuffer = 0x00200000
};
Q_DECLARE_FLAGS(Extensions, Extension)
@ -441,6 +442,8 @@ public:
QHash<QGLContextResourceBase *, void *> m_resources;
QGLTextureDestroyer *texture_destroyer;
QGLFunctions *functions;
bool vertexAttributeArraysEnabledState[QT_GL_VERTEX_ARRAY_TRACKED_COUNT];
static inline QGLContextGroup *contextGroup(const QGLContext *ctx) { return ctx->d_ptr->group; }
@ -499,7 +502,7 @@ private:
QGLContext *m_ctx;
};
class QGLTextureDestroyer : public QObject
class Q_OPENGL_EXPORT QGLTextureDestroyer : public QObject
{
Q_OBJECT
public:

View File

@ -477,6 +477,14 @@ struct QGLExtensionFuncs
// OpenGL constants
#ifndef FRAMEBUFFER_SRGB_CAPABLE_EXT
#define FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA
#endif
#ifndef FRAMEBUFFER_SRGB_EXT
#define FRAMEBUFFER_SRGB_EXT 0x8DB9
#endif
#ifndef GL_ARRAY_BUFFER
#define GL_ARRAY_BUFFER 0x8892
#endif

View File

@ -1348,7 +1348,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
#ifndef QT_OPENGL_ES_2
static void qglfResolveActiveTexture(GLenum texture)
static void QGLF_APIENTRY qglfResolveActiveTexture(GLenum texture)
{
typedef void (QGLF_APIENTRYP type_glActiveTexture)(GLenum texture);
@ -1368,7 +1368,7 @@ static void qglfResolveActiveTexture(GLenum texture)
funcs->activeTexture = qglfResolveActiveTexture;
}
static void qglfResolveAttachShader(GLuint program, GLuint shader)
static void QGLF_APIENTRY qglfResolveAttachShader(GLuint program, GLuint shader)
{
typedef void (QGLF_APIENTRYP type_glAttachShader)(GLuint program, GLuint shader);
@ -1388,7 +1388,7 @@ static void qglfResolveAttachShader(GLuint program, GLuint shader)
funcs->attachShader = qglfResolveAttachShader;
}
static void qglfResolveBindAttribLocation(GLuint program, GLuint index, const char* name)
static void QGLF_APIENTRY qglfResolveBindAttribLocation(GLuint program, GLuint index, const char* name)
{
typedef void (QGLF_APIENTRYP type_glBindAttribLocation)(GLuint program, GLuint index, const char* name);
@ -1408,7 +1408,7 @@ static void qglfResolveBindAttribLocation(GLuint program, GLuint index, const ch
funcs->bindAttribLocation = qglfResolveBindAttribLocation;
}
static void qglfResolveBindBuffer(GLenum target, GLuint buffer)
static void QGLF_APIENTRY qglfResolveBindBuffer(GLenum target, GLuint buffer)
{
typedef void (QGLF_APIENTRYP type_glBindBuffer)(GLenum target, GLuint buffer);
@ -1438,7 +1438,7 @@ static void qglfResolveBindBuffer(GLenum target, GLuint buffer)
funcs->bindBuffer = qglfResolveBindBuffer;
}
static void qglfResolveBindFramebuffer(GLenum target, GLuint framebuffer)
static void QGLF_APIENTRY qglfResolveBindFramebuffer(GLenum target, GLuint framebuffer)
{
typedef void (QGLF_APIENTRYP type_glBindFramebuffer)(GLenum target, GLuint framebuffer);
@ -1468,7 +1468,7 @@ static void qglfResolveBindFramebuffer(GLenum target, GLuint framebuffer)
funcs->bindFramebuffer = qglfResolveBindFramebuffer;
}
static void qglfResolveBindRenderbuffer(GLenum target, GLuint renderbuffer)
static void QGLF_APIENTRY qglfResolveBindRenderbuffer(GLenum target, GLuint renderbuffer)
{
typedef void (QGLF_APIENTRYP type_glBindRenderbuffer)(GLenum target, GLuint renderbuffer);
@ -1498,7 +1498,7 @@ static void qglfResolveBindRenderbuffer(GLenum target, GLuint renderbuffer)
funcs->bindRenderbuffer = qglfResolveBindRenderbuffer;
}
static void qglfResolveBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
static void QGLF_APIENTRY qglfResolveBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
{
typedef void (QGLF_APIENTRYP type_glBlendColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
@ -1528,7 +1528,7 @@ static void qglfResolveBlendColor(GLclampf red, GLclampf green, GLclampf blue, G
funcs->blendColor = qglfResolveBlendColor;
}
static void qglfResolveBlendEquation(GLenum mode)
static void QGLF_APIENTRY qglfResolveBlendEquation(GLenum mode)
{
typedef void (QGLF_APIENTRYP type_glBlendEquation)(GLenum mode);
@ -1558,7 +1558,7 @@ static void qglfResolveBlendEquation(GLenum mode)
funcs->blendEquation = qglfResolveBlendEquation;
}
static void qglfResolveBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
static void QGLF_APIENTRY qglfResolveBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
{
typedef void (QGLF_APIENTRYP type_glBlendEquationSeparate)(GLenum modeRGB, GLenum modeAlpha);
@ -1588,7 +1588,7 @@ static void qglfResolveBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
funcs->blendEquationSeparate = qglfResolveBlendEquationSeparate;
}
static void qglfResolveBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
static void QGLF_APIENTRY qglfResolveBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
{
typedef void (QGLF_APIENTRYP type_glBlendFuncSeparate)(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
@ -1618,7 +1618,7 @@ static void qglfResolveBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum sr
funcs->blendFuncSeparate = qglfResolveBlendFuncSeparate;
}
static void qglfResolveBufferData(GLenum target, qgl_GLsizeiptr size, const void* data, GLenum usage)
static void QGLF_APIENTRY qglfResolveBufferData(GLenum target, qgl_GLsizeiptr size, const void* data, GLenum usage)
{
typedef void (QGLF_APIENTRYP type_glBufferData)(GLenum target, qgl_GLsizeiptr size, const void* data, GLenum usage);
@ -1648,7 +1648,7 @@ static void qglfResolveBufferData(GLenum target, qgl_GLsizeiptr size, const void
funcs->bufferData = qglfResolveBufferData;
}
static void qglfResolveBufferSubData(GLenum target, qgl_GLintptr offset, qgl_GLsizeiptr size, const void* data)
static void QGLF_APIENTRY qglfResolveBufferSubData(GLenum target, qgl_GLintptr offset, qgl_GLsizeiptr size, const void* data)
{
typedef void (QGLF_APIENTRYP type_glBufferSubData)(GLenum target, qgl_GLintptr offset, qgl_GLsizeiptr size, const void* data);
@ -1678,7 +1678,7 @@ static void qglfResolveBufferSubData(GLenum target, qgl_GLintptr offset, qgl_GLs
funcs->bufferSubData = qglfResolveBufferSubData;
}
static GLenum qglfResolveCheckFramebufferStatus(GLenum target)
static GLenum QGLF_APIENTRY qglfResolveCheckFramebufferStatus(GLenum target)
{
typedef GLenum (QGLF_APIENTRYP type_glCheckFramebufferStatus)(GLenum target);
@ -1708,7 +1708,7 @@ static GLenum qglfResolveCheckFramebufferStatus(GLenum target)
return GLenum(0);
}
static void qglfResolveCompileShader(GLuint shader)
static void QGLF_APIENTRY qglfResolveCompileShader(GLuint shader)
{
typedef void (QGLF_APIENTRYP type_glCompileShader)(GLuint shader);
@ -1728,7 +1728,7 @@ static void qglfResolveCompileShader(GLuint shader)
funcs->compileShader = qglfResolveCompileShader;
}
static void qglfResolveCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data)
static void QGLF_APIENTRY qglfResolveCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data)
{
typedef void (QGLF_APIENTRYP type_glCompressedTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data);
@ -1758,7 +1758,7 @@ static void qglfResolveCompressedTexImage2D(GLenum target, GLint level, GLenum i
funcs->compressedTexImage2D = qglfResolveCompressedTexImage2D;
}
static void qglfResolveCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data)
static void QGLF_APIENTRY qglfResolveCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data)
{
typedef void (QGLF_APIENTRYP type_glCompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data);
@ -1788,7 +1788,7 @@ static void qglfResolveCompressedTexSubImage2D(GLenum target, GLint level, GLint
funcs->compressedTexSubImage2D = qglfResolveCompressedTexSubImage2D;
}
static GLuint qglfResolveCreateProgram()
static GLuint QGLF_APIENTRY qglfResolveCreateProgram()
{
typedef GLuint (QGLF_APIENTRYP type_glCreateProgram)();
@ -1808,7 +1808,7 @@ static GLuint qglfResolveCreateProgram()
return GLuint(0);
}
static GLuint qglfResolveCreateShader(GLenum type)
static GLuint QGLF_APIENTRY qglfResolveCreateShader(GLenum type)
{
typedef GLuint (QGLF_APIENTRYP type_glCreateShader)(GLenum type);
@ -1828,7 +1828,7 @@ static GLuint qglfResolveCreateShader(GLenum type)
return GLuint(0);
}
static void qglfResolveDeleteBuffers(GLsizei n, const GLuint* buffers)
static void QGLF_APIENTRY qglfResolveDeleteBuffers(GLsizei n, const GLuint* buffers)
{
typedef void (QGLF_APIENTRYP type_glDeleteBuffers)(GLsizei n, const GLuint* buffers);
@ -1858,7 +1858,7 @@ static void qglfResolveDeleteBuffers(GLsizei n, const GLuint* buffers)
funcs->deleteBuffers = qglfResolveDeleteBuffers;
}
static void qglfResolveDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
static void QGLF_APIENTRY qglfResolveDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
{
typedef void (QGLF_APIENTRYP type_glDeleteFramebuffers)(GLsizei n, const GLuint* framebuffers);
@ -1888,7 +1888,7 @@ static void qglfResolveDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
funcs->deleteFramebuffers = qglfResolveDeleteFramebuffers;
}
static void qglfResolveDeleteProgram(GLuint program)
static void QGLF_APIENTRY qglfResolveDeleteProgram(GLuint program)
{
typedef void (QGLF_APIENTRYP type_glDeleteProgram)(GLuint program);
@ -1908,7 +1908,7 @@ static void qglfResolveDeleteProgram(GLuint program)
funcs->deleteProgram = qglfResolveDeleteProgram;
}
static void qglfResolveDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
static void QGLF_APIENTRY qglfResolveDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
{
typedef void (QGLF_APIENTRYP type_glDeleteRenderbuffers)(GLsizei n, const GLuint* renderbuffers);
@ -1938,7 +1938,7 @@ static void qglfResolveDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffer
funcs->deleteRenderbuffers = qglfResolveDeleteRenderbuffers;
}
static void qglfResolveDeleteShader(GLuint shader)
static void QGLF_APIENTRY qglfResolveDeleteShader(GLuint shader)
{
typedef void (QGLF_APIENTRYP type_glDeleteShader)(GLuint shader);
@ -1958,7 +1958,7 @@ static void qglfResolveDeleteShader(GLuint shader)
funcs->deleteShader = qglfResolveDeleteShader;
}
static void qglfResolveDetachShader(GLuint program, GLuint shader)
static void QGLF_APIENTRY qglfResolveDetachShader(GLuint program, GLuint shader)
{
typedef void (QGLF_APIENTRYP type_glDetachShader)(GLuint program, GLuint shader);
@ -1978,7 +1978,7 @@ static void qglfResolveDetachShader(GLuint program, GLuint shader)
funcs->detachShader = qglfResolveDetachShader;
}
static void qglfResolveDisableVertexAttribArray(GLuint index)
static void QGLF_APIENTRY qglfResolveDisableVertexAttribArray(GLuint index)
{
typedef void (QGLF_APIENTRYP type_glDisableVertexAttribArray)(GLuint index);
@ -1998,7 +1998,7 @@ static void qglfResolveDisableVertexAttribArray(GLuint index)
funcs->disableVertexAttribArray = qglfResolveDisableVertexAttribArray;
}
static void qglfResolveEnableVertexAttribArray(GLuint index)
static void QGLF_APIENTRY qglfResolveEnableVertexAttribArray(GLuint index)
{
typedef void (QGLF_APIENTRYP type_glEnableVertexAttribArray)(GLuint index);
@ -2018,7 +2018,7 @@ static void qglfResolveEnableVertexAttribArray(GLuint index)
funcs->enableVertexAttribArray = qglfResolveEnableVertexAttribArray;
}
static void qglfResolveFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
static void QGLF_APIENTRY qglfResolveFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
{
typedef void (QGLF_APIENTRYP type_glFramebufferRenderbuffer)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
@ -2048,7 +2048,7 @@ static void qglfResolveFramebufferRenderbuffer(GLenum target, GLenum attachment,
funcs->framebufferRenderbuffer = qglfResolveFramebufferRenderbuffer;
}
static void qglfResolveFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
static void QGLF_APIENTRY qglfResolveFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
{
typedef void (QGLF_APIENTRYP type_glFramebufferTexture2D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
@ -2078,7 +2078,7 @@ static void qglfResolveFramebufferTexture2D(GLenum target, GLenum attachment, GL
funcs->framebufferTexture2D = qglfResolveFramebufferTexture2D;
}
static void qglfResolveGenBuffers(GLsizei n, GLuint* buffers)
static void QGLF_APIENTRY qglfResolveGenBuffers(GLsizei n, GLuint* buffers)
{
typedef void (QGLF_APIENTRYP type_glGenBuffers)(GLsizei n, GLuint* buffers);
@ -2108,7 +2108,7 @@ static void qglfResolveGenBuffers(GLsizei n, GLuint* buffers)
funcs->genBuffers = qglfResolveGenBuffers;
}
static void qglfResolveGenerateMipmap(GLenum target)
static void QGLF_APIENTRY qglfResolveGenerateMipmap(GLenum target)
{
typedef void (QGLF_APIENTRYP type_glGenerateMipmap)(GLenum target);
@ -2138,7 +2138,7 @@ static void qglfResolveGenerateMipmap(GLenum target)
funcs->generateMipmap = qglfResolveGenerateMipmap;
}
static void qglfResolveGenFramebuffers(GLsizei n, GLuint* framebuffers)
static void QGLF_APIENTRY qglfResolveGenFramebuffers(GLsizei n, GLuint* framebuffers)
{
typedef void (QGLF_APIENTRYP type_glGenFramebuffers)(GLsizei n, GLuint* framebuffers);
@ -2168,7 +2168,7 @@ static void qglfResolveGenFramebuffers(GLsizei n, GLuint* framebuffers)
funcs->genFramebuffers = qglfResolveGenFramebuffers;
}
static void qglfResolveGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
static void QGLF_APIENTRY qglfResolveGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
{
typedef void (QGLF_APIENTRYP type_glGenRenderbuffers)(GLsizei n, GLuint* renderbuffers);
@ -2198,7 +2198,7 @@ static void qglfResolveGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
funcs->genRenderbuffers = qglfResolveGenRenderbuffers;
}
static void qglfResolveGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name)
static void QGLF_APIENTRY qglfResolveGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name)
{
typedef void (QGLF_APIENTRYP type_glGetActiveAttrib)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name);
@ -2218,7 +2218,7 @@ static void qglfResolveGetActiveAttrib(GLuint program, GLuint index, GLsizei buf
funcs->getActiveAttrib = qglfResolveGetActiveAttrib;
}
static void qglfResolveGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name)
static void QGLF_APIENTRY qglfResolveGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name)
{
typedef void (QGLF_APIENTRYP type_glGetActiveUniform)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name);
@ -2238,7 +2238,7 @@ static void qglfResolveGetActiveUniform(GLuint program, GLuint index, GLsizei bu
funcs->getActiveUniform = qglfResolveGetActiveUniform;
}
static void qglfResolveGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
static void QGLF_APIENTRY qglfResolveGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
{
typedef void (QGLF_APIENTRYP type_glGetAttachedShaders)(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders);
@ -2258,7 +2258,7 @@ static void qglfResolveGetAttachedShaders(GLuint program, GLsizei maxcount, GLsi
funcs->getAttachedShaders = qglfResolveGetAttachedShaders;
}
static int qglfResolveGetAttribLocation(GLuint program, const char* name)
static int QGLF_APIENTRY qglfResolveGetAttribLocation(GLuint program, const char* name)
{
typedef int (QGLF_APIENTRYP type_glGetAttribLocation)(GLuint program, const char* name);
@ -2278,7 +2278,7 @@ static int qglfResolveGetAttribLocation(GLuint program, const char* name)
return int(0);
}
static void qglfResolveGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
static void QGLF_APIENTRY qglfResolveGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
{
typedef void (QGLF_APIENTRYP type_glGetBufferParameteriv)(GLenum target, GLenum pname, GLint* params);
@ -2308,7 +2308,7 @@ static void qglfResolveGetBufferParameteriv(GLenum target, GLenum pname, GLint*
funcs->getBufferParameteriv = qglfResolveGetBufferParameteriv;
}
static void qglfResolveGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
static void QGLF_APIENTRY qglfResolveGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
{
typedef void (QGLF_APIENTRYP type_glGetFramebufferAttachmentParameteriv)(GLenum target, GLenum attachment, GLenum pname, GLint* params);
@ -2338,7 +2338,7 @@ static void qglfResolveGetFramebufferAttachmentParameteriv(GLenum target, GLenum
funcs->getFramebufferAttachmentParameteriv = qglfResolveGetFramebufferAttachmentParameteriv;
}
static void qglfResolveGetProgramiv(GLuint program, GLenum pname, GLint* params)
static void QGLF_APIENTRY qglfResolveGetProgramiv(GLuint program, GLenum pname, GLint* params)
{
typedef void (QGLF_APIENTRYP type_glGetProgramiv)(GLuint program, GLenum pname, GLint* params);
@ -2358,7 +2358,7 @@ static void qglfResolveGetProgramiv(GLuint program, GLenum pname, GLint* params)
funcs->getProgramiv = qglfResolveGetProgramiv;
}
static void qglfResolveGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, char* infolog)
static void QGLF_APIENTRY qglfResolveGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, char* infolog)
{
typedef void (QGLF_APIENTRYP type_glGetProgramInfoLog)(GLuint program, GLsizei bufsize, GLsizei* length, char* infolog);
@ -2378,7 +2378,7 @@ static void qglfResolveGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsize
funcs->getProgramInfoLog = qglfResolveGetProgramInfoLog;
}
static void qglfResolveGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
static void QGLF_APIENTRY qglfResolveGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
{
typedef void (QGLF_APIENTRYP type_glGetRenderbufferParameteriv)(GLenum target, GLenum pname, GLint* params);
@ -2408,7 +2408,7 @@ static void qglfResolveGetRenderbufferParameteriv(GLenum target, GLenum pname, G
funcs->getRenderbufferParameteriv = qglfResolveGetRenderbufferParameteriv;
}
static void qglfResolveGetShaderiv(GLuint shader, GLenum pname, GLint* params)
static void QGLF_APIENTRY qglfResolveGetShaderiv(GLuint shader, GLenum pname, GLint* params)
{
typedef void (QGLF_APIENTRYP type_glGetShaderiv)(GLuint shader, GLenum pname, GLint* params);
@ -2428,7 +2428,7 @@ static void qglfResolveGetShaderiv(GLuint shader, GLenum pname, GLint* params)
funcs->getShaderiv = qglfResolveGetShaderiv;
}
static void qglfResolveGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog)
static void QGLF_APIENTRY qglfResolveGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog)
{
typedef void (QGLF_APIENTRYP type_glGetShaderInfoLog)(GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog);
@ -2448,14 +2448,14 @@ static void qglfResolveGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei*
funcs->getShaderInfoLog = qglfResolveGetShaderInfoLog;
}
static void qglfSpecialGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
static void QGLF_APIENTRY qglfSpecialGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
{
Q_UNUSED(shadertype);
Q_UNUSED(precisiontype);
range[0] = range[1] = precision[0] = 0;
}
static void qglfResolveGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
static void QGLF_APIENTRY qglfResolveGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
{
typedef void (QGLF_APIENTRYP type_glGetShaderPrecisionFormat)(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
@ -2485,7 +2485,7 @@ static void qglfResolveGetShaderPrecisionFormat(GLenum shadertype, GLenum precis
funcs->getShaderPrecisionFormat(shadertype, precisiontype, range, precision);
}
static void qglfResolveGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, char* source)
static void QGLF_APIENTRY qglfResolveGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, char* source)
{
typedef void (QGLF_APIENTRYP type_glGetShaderSource)(GLuint shader, GLsizei bufsize, GLsizei* length, char* source);
@ -2505,7 +2505,7 @@ static void qglfResolveGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei*
funcs->getShaderSource = qglfResolveGetShaderSource;
}
static void qglfResolveGetUniformfv(GLuint program, GLint location, GLfloat* params)
static void QGLF_APIENTRY qglfResolveGetUniformfv(GLuint program, GLint location, GLfloat* params)
{
typedef void (QGLF_APIENTRYP type_glGetUniformfv)(GLuint program, GLint location, GLfloat* params);
@ -2525,7 +2525,7 @@ static void qglfResolveGetUniformfv(GLuint program, GLint location, GLfloat* par
funcs->getUniformfv = qglfResolveGetUniformfv;
}
static void qglfResolveGetUniformiv(GLuint program, GLint location, GLint* params)
static void QGLF_APIENTRY qglfResolveGetUniformiv(GLuint program, GLint location, GLint* params)
{
typedef void (QGLF_APIENTRYP type_glGetUniformiv)(GLuint program, GLint location, GLint* params);
@ -2545,7 +2545,7 @@ static void qglfResolveGetUniformiv(GLuint program, GLint location, GLint* param
funcs->getUniformiv = qglfResolveGetUniformiv;
}
static int qglfResolveGetUniformLocation(GLuint program, const char* name)
static int QGLF_APIENTRY qglfResolveGetUniformLocation(GLuint program, const char* name)
{
typedef int (QGLF_APIENTRYP type_glGetUniformLocation)(GLuint program, const char* name);
@ -2565,7 +2565,7 @@ static int qglfResolveGetUniformLocation(GLuint program, const char* name)
return int(0);
}
static void qglfResolveGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
static void QGLF_APIENTRY qglfResolveGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
{
typedef void (QGLF_APIENTRYP type_glGetVertexAttribfv)(GLuint index, GLenum pname, GLfloat* params);
@ -2585,7 +2585,7 @@ static void qglfResolveGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* pa
funcs->getVertexAttribfv = qglfResolveGetVertexAttribfv;
}
static void qglfResolveGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
static void QGLF_APIENTRY qglfResolveGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
{
typedef void (QGLF_APIENTRYP type_glGetVertexAttribiv)(GLuint index, GLenum pname, GLint* params);
@ -2605,7 +2605,7 @@ static void qglfResolveGetVertexAttribiv(GLuint index, GLenum pname, GLint* para
funcs->getVertexAttribiv = qglfResolveGetVertexAttribiv;
}
static void qglfResolveGetVertexAttribPointerv(GLuint index, GLenum pname, void** pointer)
static void QGLF_APIENTRY qglfResolveGetVertexAttribPointerv(GLuint index, GLenum pname, void** pointer)
{
typedef void (QGLF_APIENTRYP type_glGetVertexAttribPointerv)(GLuint index, GLenum pname, void** pointer);
@ -2625,7 +2625,7 @@ static void qglfResolveGetVertexAttribPointerv(GLuint index, GLenum pname, void*
funcs->getVertexAttribPointerv = qglfResolveGetVertexAttribPointerv;
}
static GLboolean qglfResolveIsBuffer(GLuint buffer)
static GLboolean QGLF_APIENTRY qglfResolveIsBuffer(GLuint buffer)
{
typedef GLboolean (QGLF_APIENTRYP type_glIsBuffer)(GLuint buffer);
@ -2655,7 +2655,7 @@ static GLboolean qglfResolveIsBuffer(GLuint buffer)
return GLboolean(0);
}
static GLboolean qglfResolveIsFramebuffer(GLuint framebuffer)
static GLboolean QGLF_APIENTRY qglfResolveIsFramebuffer(GLuint framebuffer)
{
typedef GLboolean (QGLF_APIENTRYP type_glIsFramebuffer)(GLuint framebuffer);
@ -2685,12 +2685,12 @@ static GLboolean qglfResolveIsFramebuffer(GLuint framebuffer)
return GLboolean(0);
}
static GLboolean qglfSpecialIsProgram(GLuint program)
static GLboolean QGLF_APIENTRY qglfSpecialIsProgram(GLuint program)
{
return program != 0;
}
static GLboolean qglfResolveIsProgram(GLuint program)
static GLboolean QGLF_APIENTRY qglfResolveIsProgram(GLuint program)
{
typedef GLboolean (QGLF_APIENTRYP type_glIsProgram)(GLuint program);
@ -2710,7 +2710,7 @@ static GLboolean qglfResolveIsProgram(GLuint program)
return funcs->isProgram(program);
}
static GLboolean qglfResolveIsRenderbuffer(GLuint renderbuffer)
static GLboolean QGLF_APIENTRY qglfResolveIsRenderbuffer(GLuint renderbuffer)
{
typedef GLboolean (QGLF_APIENTRYP type_glIsRenderbuffer)(GLuint renderbuffer);
@ -2740,12 +2740,12 @@ static GLboolean qglfResolveIsRenderbuffer(GLuint renderbuffer)
return GLboolean(0);
}
static GLboolean qglfSpecialIsShader(GLuint shader)
static GLboolean QGLF_APIENTRY qglfSpecialIsShader(GLuint shader)
{
return shader != 0;
}
static GLboolean qglfResolveIsShader(GLuint shader)
static GLboolean QGLF_APIENTRY qglfResolveIsShader(GLuint shader)
{
typedef GLboolean (QGLF_APIENTRYP type_glIsShader)(GLuint shader);
@ -2765,7 +2765,7 @@ static GLboolean qglfResolveIsShader(GLuint shader)
return funcs->isShader(shader);
}
static void qglfResolveLinkProgram(GLuint program)
static void QGLF_APIENTRY qglfResolveLinkProgram(GLuint program)
{
typedef void (QGLF_APIENTRYP type_glLinkProgram)(GLuint program);
@ -2785,11 +2785,11 @@ static void qglfResolveLinkProgram(GLuint program)
funcs->linkProgram = qglfResolveLinkProgram;
}
static void qglfSpecialReleaseShaderCompiler()
static void QGLF_APIENTRY qglfSpecialReleaseShaderCompiler()
{
}
static void qglfResolveReleaseShaderCompiler()
static void QGLF_APIENTRY qglfResolveReleaseShaderCompiler()
{
typedef void (QGLF_APIENTRYP type_glReleaseShaderCompiler)();
@ -2809,7 +2809,7 @@ static void qglfResolveReleaseShaderCompiler()
funcs->releaseShaderCompiler();
}
static void qglfResolveRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
static void QGLF_APIENTRY qglfResolveRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
{
typedef void (QGLF_APIENTRYP type_glRenderbufferStorage)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
@ -2839,7 +2839,7 @@ static void qglfResolveRenderbufferStorage(GLenum target, GLenum internalformat,
funcs->renderbufferStorage = qglfResolveRenderbufferStorage;
}
static void qglfResolveSampleCoverage(GLclampf value, GLboolean invert)
static void QGLF_APIENTRY qglfResolveSampleCoverage(GLclampf value, GLboolean invert)
{
typedef void (QGLF_APIENTRYP type_glSampleCoverage)(GLclampf value, GLboolean invert);
@ -2869,7 +2869,7 @@ static void qglfResolveSampleCoverage(GLclampf value, GLboolean invert)
funcs->sampleCoverage = qglfResolveSampleCoverage;
}
static void qglfResolveShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLint length)
static void QGLF_APIENTRY qglfResolveShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLint length)
{
typedef void (QGLF_APIENTRYP type_glShaderBinary)(GLint n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLint length);
@ -2889,7 +2889,7 @@ static void qglfResolveShaderBinary(GLint n, const GLuint* shaders, GLenum binar
funcs->shaderBinary = qglfResolveShaderBinary;
}
static void qglfResolveShaderSource(GLuint shader, GLsizei count, const char** string, const GLint* length)
static void QGLF_APIENTRY qglfResolveShaderSource(GLuint shader, GLsizei count, const char** string, const GLint* length)
{
typedef void (QGLF_APIENTRYP type_glShaderSource)(GLuint shader, GLsizei count, const char** string, const GLint* length);
@ -2909,7 +2909,7 @@ static void qglfResolveShaderSource(GLuint shader, GLsizei count, const char** s
funcs->shaderSource = qglfResolveShaderSource;
}
static void qglfResolveStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
static void QGLF_APIENTRY qglfResolveStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
{
typedef void (QGLF_APIENTRYP type_glStencilFuncSeparate)(GLenum face, GLenum func, GLint ref, GLuint mask);
@ -2939,7 +2939,7 @@ static void qglfResolveStencilFuncSeparate(GLenum face, GLenum func, GLint ref,
funcs->stencilFuncSeparate = qglfResolveStencilFuncSeparate;
}
static void qglfResolveStencilMaskSeparate(GLenum face, GLuint mask)
static void QGLF_APIENTRY qglfResolveStencilMaskSeparate(GLenum face, GLuint mask)
{
typedef void (QGLF_APIENTRYP type_glStencilMaskSeparate)(GLenum face, GLuint mask);
@ -2969,7 +2969,7 @@ static void qglfResolveStencilMaskSeparate(GLenum face, GLuint mask)
funcs->stencilMaskSeparate = qglfResolveStencilMaskSeparate;
}
static void qglfResolveStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
static void QGLF_APIENTRY qglfResolveStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
{
typedef void (QGLF_APIENTRYP type_glStencilOpSeparate)(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
@ -2999,7 +2999,7 @@ static void qglfResolveStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail,
funcs->stencilOpSeparate = qglfResolveStencilOpSeparate;
}
static void qglfResolveUniform1f(GLint location, GLfloat x)
static void QGLF_APIENTRY qglfResolveUniform1f(GLint location, GLfloat x)
{
typedef void (QGLF_APIENTRYP type_glUniform1f)(GLint location, GLfloat x);
@ -3019,7 +3019,7 @@ static void qglfResolveUniform1f(GLint location, GLfloat x)
funcs->uniform1f = qglfResolveUniform1f;
}
static void qglfResolveUniform1fv(GLint location, GLsizei count, const GLfloat* v)
static void QGLF_APIENTRY qglfResolveUniform1fv(GLint location, GLsizei count, const GLfloat* v)
{
typedef void (QGLF_APIENTRYP type_glUniform1fv)(GLint location, GLsizei count, const GLfloat* v);
@ -3039,7 +3039,7 @@ static void qglfResolveUniform1fv(GLint location, GLsizei count, const GLfloat*
funcs->uniform1fv = qglfResolveUniform1fv;
}
static void qglfResolveUniform1i(GLint location, GLint x)
static void QGLF_APIENTRY qglfResolveUniform1i(GLint location, GLint x)
{
typedef void (QGLF_APIENTRYP type_glUniform1i)(GLint location, GLint x);
@ -3059,7 +3059,7 @@ static void qglfResolveUniform1i(GLint location, GLint x)
funcs->uniform1i = qglfResolveUniform1i;
}
static void qglfResolveUniform1iv(GLint location, GLsizei count, const GLint* v)
static void QGLF_APIENTRY qglfResolveUniform1iv(GLint location, GLsizei count, const GLint* v)
{
typedef void (QGLF_APIENTRYP type_glUniform1iv)(GLint location, GLsizei count, const GLint* v);
@ -3079,7 +3079,7 @@ static void qglfResolveUniform1iv(GLint location, GLsizei count, const GLint* v)
funcs->uniform1iv = qglfResolveUniform1iv;
}
static void qglfResolveUniform2f(GLint location, GLfloat x, GLfloat y)
static void QGLF_APIENTRY qglfResolveUniform2f(GLint location, GLfloat x, GLfloat y)
{
typedef void (QGLF_APIENTRYP type_glUniform2f)(GLint location, GLfloat x, GLfloat y);
@ -3099,7 +3099,7 @@ static void qglfResolveUniform2f(GLint location, GLfloat x, GLfloat y)
funcs->uniform2f = qglfResolveUniform2f;
}
static void qglfResolveUniform2fv(GLint location, GLsizei count, const GLfloat* v)
static void QGLF_APIENTRY qglfResolveUniform2fv(GLint location, GLsizei count, const GLfloat* v)
{
typedef void (QGLF_APIENTRYP type_glUniform2fv)(GLint location, GLsizei count, const GLfloat* v);
@ -3119,7 +3119,7 @@ static void qglfResolveUniform2fv(GLint location, GLsizei count, const GLfloat*
funcs->uniform2fv = qglfResolveUniform2fv;
}
static void qglfResolveUniform2i(GLint location, GLint x, GLint y)
static void QGLF_APIENTRY qglfResolveUniform2i(GLint location, GLint x, GLint y)
{
typedef void (QGLF_APIENTRYP type_glUniform2i)(GLint location, GLint x, GLint y);
@ -3139,7 +3139,7 @@ static void qglfResolveUniform2i(GLint location, GLint x, GLint y)
funcs->uniform2i = qglfResolveUniform2i;
}
static void qglfResolveUniform2iv(GLint location, GLsizei count, const GLint* v)
static void QGLF_APIENTRY qglfResolveUniform2iv(GLint location, GLsizei count, const GLint* v)
{
typedef void (QGLF_APIENTRYP type_glUniform2iv)(GLint location, GLsizei count, const GLint* v);
@ -3159,7 +3159,7 @@ static void qglfResolveUniform2iv(GLint location, GLsizei count, const GLint* v)
funcs->uniform2iv = qglfResolveUniform2iv;
}
static void qglfResolveUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
static void QGLF_APIENTRY qglfResolveUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
{
typedef void (QGLF_APIENTRYP type_glUniform3f)(GLint location, GLfloat x, GLfloat y, GLfloat z);
@ -3179,7 +3179,7 @@ static void qglfResolveUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z
funcs->uniform3f = qglfResolveUniform3f;
}
static void qglfResolveUniform3fv(GLint location, GLsizei count, const GLfloat* v)
static void QGLF_APIENTRY qglfResolveUniform3fv(GLint location, GLsizei count, const GLfloat* v)
{
typedef void (QGLF_APIENTRYP type_glUniform3fv)(GLint location, GLsizei count, const GLfloat* v);
@ -3199,7 +3199,7 @@ static void qglfResolveUniform3fv(GLint location, GLsizei count, const GLfloat*
funcs->uniform3fv = qglfResolveUniform3fv;
}
static void qglfResolveUniform3i(GLint location, GLint x, GLint y, GLint z)
static void QGLF_APIENTRY qglfResolveUniform3i(GLint location, GLint x, GLint y, GLint z)
{
typedef void (QGLF_APIENTRYP type_glUniform3i)(GLint location, GLint x, GLint y, GLint z);
@ -3219,7 +3219,7 @@ static void qglfResolveUniform3i(GLint location, GLint x, GLint y, GLint z)
funcs->uniform3i = qglfResolveUniform3i;
}
static void qglfResolveUniform3iv(GLint location, GLsizei count, const GLint* v)
static void QGLF_APIENTRY qglfResolveUniform3iv(GLint location, GLsizei count, const GLint* v)
{
typedef void (QGLF_APIENTRYP type_glUniform3iv)(GLint location, GLsizei count, const GLint* v);
@ -3239,7 +3239,7 @@ static void qglfResolveUniform3iv(GLint location, GLsizei count, const GLint* v)
funcs->uniform3iv = qglfResolveUniform3iv;
}
static void qglfResolveUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
static void QGLF_APIENTRY qglfResolveUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
typedef void (QGLF_APIENTRYP type_glUniform4f)(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
@ -3259,7 +3259,7 @@ static void qglfResolveUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z
funcs->uniform4f = qglfResolveUniform4f;
}
static void qglfResolveUniform4fv(GLint location, GLsizei count, const GLfloat* v)
static void QGLF_APIENTRY qglfResolveUniform4fv(GLint location, GLsizei count, const GLfloat* v)
{
typedef void (QGLF_APIENTRYP type_glUniform4fv)(GLint location, GLsizei count, const GLfloat* v);
@ -3279,7 +3279,7 @@ static void qglfResolveUniform4fv(GLint location, GLsizei count, const GLfloat*
funcs->uniform4fv = qglfResolveUniform4fv;
}
static void qglfResolveUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
static void QGLF_APIENTRY qglfResolveUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
{
typedef void (QGLF_APIENTRYP type_glUniform4i)(GLint location, GLint x, GLint y, GLint z, GLint w);
@ -3299,7 +3299,7 @@ static void qglfResolveUniform4i(GLint location, GLint x, GLint y, GLint z, GLin
funcs->uniform4i = qglfResolveUniform4i;
}
static void qglfResolveUniform4iv(GLint location, GLsizei count, const GLint* v)
static void QGLF_APIENTRY qglfResolveUniform4iv(GLint location, GLsizei count, const GLint* v)
{
typedef void (QGLF_APIENTRYP type_glUniform4iv)(GLint location, GLsizei count, const GLint* v);
@ -3319,7 +3319,7 @@ static void qglfResolveUniform4iv(GLint location, GLsizei count, const GLint* v)
funcs->uniform4iv = qglfResolveUniform4iv;
}
static void qglfResolveUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
static void QGLF_APIENTRY qglfResolveUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
typedef void (QGLF_APIENTRYP type_glUniformMatrix2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
@ -3339,7 +3339,7 @@ static void qglfResolveUniformMatrix2fv(GLint location, GLsizei count, GLboolean
funcs->uniformMatrix2fv = qglfResolveUniformMatrix2fv;
}
static void qglfResolveUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
static void QGLF_APIENTRY qglfResolveUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
typedef void (QGLF_APIENTRYP type_glUniformMatrix3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
@ -3359,7 +3359,7 @@ static void qglfResolveUniformMatrix3fv(GLint location, GLsizei count, GLboolean
funcs->uniformMatrix3fv = qglfResolveUniformMatrix3fv;
}
static void qglfResolveUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
static void QGLF_APIENTRY qglfResolveUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
typedef void (QGLF_APIENTRYP type_glUniformMatrix4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
@ -3379,7 +3379,7 @@ static void qglfResolveUniformMatrix4fv(GLint location, GLsizei count, GLboolean
funcs->uniformMatrix4fv = qglfResolveUniformMatrix4fv;
}
static void qglfResolveUseProgram(GLuint program)
static void QGLF_APIENTRY qglfResolveUseProgram(GLuint program)
{
typedef void (QGLF_APIENTRYP type_glUseProgram)(GLuint program);
@ -3399,7 +3399,7 @@ static void qglfResolveUseProgram(GLuint program)
funcs->useProgram = qglfResolveUseProgram;
}
static void qglfResolveValidateProgram(GLuint program)
static void QGLF_APIENTRY qglfResolveValidateProgram(GLuint program)
{
typedef void (QGLF_APIENTRYP type_glValidateProgram)(GLuint program);
@ -3419,7 +3419,7 @@ static void qglfResolveValidateProgram(GLuint program)
funcs->validateProgram = qglfResolveValidateProgram;
}
static void qglfResolveVertexAttrib1f(GLuint indx, GLfloat x)
static void QGLF_APIENTRY qglfResolveVertexAttrib1f(GLuint indx, GLfloat x)
{
typedef void (QGLF_APIENTRYP type_glVertexAttrib1f)(GLuint indx, GLfloat x);
@ -3439,7 +3439,7 @@ static void qglfResolveVertexAttrib1f(GLuint indx, GLfloat x)
funcs->vertexAttrib1f = qglfResolveVertexAttrib1f;
}
static void qglfResolveVertexAttrib1fv(GLuint indx, const GLfloat* values)
static void QGLF_APIENTRY qglfResolveVertexAttrib1fv(GLuint indx, const GLfloat* values)
{
typedef void (QGLF_APIENTRYP type_glVertexAttrib1fv)(GLuint indx, const GLfloat* values);
@ -3459,7 +3459,7 @@ static void qglfResolveVertexAttrib1fv(GLuint indx, const GLfloat* values)
funcs->vertexAttrib1fv = qglfResolveVertexAttrib1fv;
}
static void qglfResolveVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y)
static void QGLF_APIENTRY qglfResolveVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y)
{
typedef void (QGLF_APIENTRYP type_glVertexAttrib2f)(GLuint indx, GLfloat x, GLfloat y);
@ -3479,7 +3479,7 @@ static void qglfResolveVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y)
funcs->vertexAttrib2f = qglfResolveVertexAttrib2f;
}
static void qglfResolveVertexAttrib2fv(GLuint indx, const GLfloat* values)
static void QGLF_APIENTRY qglfResolveVertexAttrib2fv(GLuint indx, const GLfloat* values)
{
typedef void (QGLF_APIENTRYP type_glVertexAttrib2fv)(GLuint indx, const GLfloat* values);
@ -3499,7 +3499,7 @@ static void qglfResolveVertexAttrib2fv(GLuint indx, const GLfloat* values)
funcs->vertexAttrib2fv = qglfResolveVertexAttrib2fv;
}
static void qglfResolveVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z)
static void QGLF_APIENTRY qglfResolveVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z)
{
typedef void (QGLF_APIENTRYP type_glVertexAttrib3f)(GLuint indx, GLfloat x, GLfloat y, GLfloat z);
@ -3519,7 +3519,7 @@ static void qglfResolveVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat
funcs->vertexAttrib3f = qglfResolveVertexAttrib3f;
}
static void qglfResolveVertexAttrib3fv(GLuint indx, const GLfloat* values)
static void QGLF_APIENTRY qglfResolveVertexAttrib3fv(GLuint indx, const GLfloat* values)
{
typedef void (QGLF_APIENTRYP type_glVertexAttrib3fv)(GLuint indx, const GLfloat* values);
@ -3539,7 +3539,7 @@ static void qglfResolveVertexAttrib3fv(GLuint indx, const GLfloat* values)
funcs->vertexAttrib3fv = qglfResolveVertexAttrib3fv;
}
static void qglfResolveVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
static void QGLF_APIENTRY qglfResolveVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
typedef void (QGLF_APIENTRYP type_glVertexAttrib4f)(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
@ -3559,7 +3559,7 @@ static void qglfResolveVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat
funcs->vertexAttrib4f = qglfResolveVertexAttrib4f;
}
static void qglfResolveVertexAttrib4fv(GLuint indx, const GLfloat* values)
static void QGLF_APIENTRY qglfResolveVertexAttrib4fv(GLuint indx, const GLfloat* values)
{
typedef void (QGLF_APIENTRYP type_glVertexAttrib4fv)(GLuint indx, const GLfloat* values);
@ -3579,7 +3579,7 @@ static void qglfResolveVertexAttrib4fv(GLuint indx, const GLfloat* values)
funcs->vertexAttrib4fv = qglfResolveVertexAttrib4fv;
}
static void qglfResolveVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr)
static void QGLF_APIENTRY qglfResolveVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr)
{
typedef void (QGLF_APIENTRYP type_glVertexAttribPointer)(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr);

View File

@ -59,6 +59,10 @@ QT_MODULE(OpenGL)
typedef ptrdiff_t qgl_GLintptr;
typedef ptrdiff_t qgl_GLsizeiptr;
#ifdef Q_WS_WIN
# define QGLF_APIENTRY APIENTRY
#endif
#ifndef Q_WS_MAC
# ifndef QGLF_APIENTRYP
# ifdef QGLF_APIENTRY
@ -1945,6 +1949,9 @@ inline void QGLFunctions::glVertexAttribPointer(GLuint indx, GLint size, GLenum
#ifndef GL_RGBA4
#define GL_RGBA4 0x8056
#endif
#ifndef GL_BGRA
#define GL_BGRA 0x80E1
#endif
#ifndef GL_SAMPLE_ALPHA_TO_COVERAGE
#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
#endif

View File

@ -90,7 +90,7 @@ protected:
// Wraps a QGLWidget
class QGLWidget;
class QGLWidgetGLPaintDevice : public QGLPaintDevice
class Q_OPENGL_EXPORT QGLWidgetGLPaintDevice : public QGLPaintDevice
{
public:
QGLWidgetGLPaintDevice();

View File

@ -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<QUIKitWindow *>(widget->platformWindow());
platformWindow->ensureNativeWindow();
}

View File

@ -54,7 +54,7 @@ QUIKitScreen::QUIKitScreen(int screenIndex)
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
UIScreen *screen = [[UIScreen screens] objectAtIndex:screenIndex];
CGRect bounds = [screen bounds];
m_geometry = QRect(0, 0, bounds.size.width, bounds.size.height);
m_geometry = QRect(bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height);
m_format = QImage::Format_ARGB32;
@ -62,7 +62,7 @@ QUIKitScreen::QUIKitScreen(int screenIndex)
const qreal inch = 25.4;
qreal dpi = 160.;
int dragDistance = 14;
int dragDistance = 12;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
dpi = 132.;
dragDistance = 10;

View File

@ -47,6 +47,8 @@
#import <UIKit/UIKit.h>
#import <OpenGLES/ES1/gl.h>
#import <OpenGLES/ES1/glext.h>
#import <OpenGLES/ES2/gl.h>
#import <OpenGLES/ES2/glext.h>
#import <OpenGLES/EAGL.h>
@interface EAGLView : UIView <UIKeyInput>
@ -59,6 +61,7 @@
GLuint mFramebuffer, mColorRenderbuffer, mDepthRenderbuffer;
id delegate;
// ------- Text Input ----------
UITextAutocapitalizationType autocapitalizationType;
UITextAutocorrectionType autocorrectionType;
@ -77,6 +80,8 @@
- (void)setWindow:(QPlatformWindow *)window;
- (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons;
@property (readonly,getter=fbo) GLint fbo;
@property (nonatomic, assign) id delegate;
// ------- Text Input ----------
@ -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();

View File

@ -79,7 +79,11 @@ public:
mFormat.setStereo(false);
mFormat.setDirectRendering(false);
#if defined(QT_OPENGL_ES_2)
EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
#else
EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
#endif
[mView setContext:aContext];
}
@ -116,6 +120,8 @@ private:
@implementation EAGLView
@synthesize delegate;
+ (Class)layerClass
{
return [CAEAGLLayer class];
@ -156,8 +162,8 @@ private:
{
if (mContext) {
[EAGLContext setCurrentContext:mContext];
glBindRenderbufferOES(GL_RENDERBUFFER_OES, mColorRenderbuffer);
[mContext presentRenderbuffer:GL_RENDERBUFFER_OES];
glBindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer);
[mContext presentRenderbuffer:GL_RENDERBUFFER];
}
}
@ -167,15 +173,15 @@ private:
{
[EAGLContext setCurrentContext:mContext];
if (mFramebuffer) {
glDeleteFramebuffersOES(1, &mFramebuffer);
glDeleteFramebuffers(1, &mFramebuffer);
mFramebuffer = 0;
}
if (mColorRenderbuffer) {
glDeleteRenderbuffersOES(1, &mColorRenderbuffer);
glDeleteRenderbuffers(1, &mColorRenderbuffer);
mColorRenderbuffer = 0;
}
if (mDepthRenderbuffer) {
glDeleteRenderbuffersOES(1, &mDepthRenderbuffer);
glDeleteRenderbuffers(1, &mDepthRenderbuffer);
mDepthRenderbuffer = 0;
}
}
@ -186,24 +192,27 @@ private:
if (mContext && !mFramebuffer)
{
[EAGLContext setCurrentContext:mContext];
glGenFramebuffersOES(1, &mFramebuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, mFramebuffer);
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];

View File

@ -47,27 +47,64 @@
#include <QtDebug>
class EAGLPaintDevice;
@interface PaintDeviceHelper : NSObject {
EAGLPaintDevice *device;
}
@property (nonatomic, assign) EAGLPaintDevice *device;
- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer;
@end
class EAGLPaintDevice : public QGLPaintDevice
{
public:
EAGLPaintDevice(QPlatformWindow *window)
:QGLPaintDevice(), mWindow(window)
{
#if defined(QT_OPENGL_ES_2)
helper = [[PaintDeviceHelper alloc] init];
helper.device = this;
EAGLView *view = static_cast<QUIKitWindow *>(window)->nativeView();
view.delegate = helper;
m_thisFBO = view.fbo;
#endif
}
~EAGLPaintDevice()
{
#if defined(QT_OPENGL_ES_2)
[helper release];
#endif
}
void setFramebuffer(GLuint buffer) { m_thisFBO = buffer; }
int devType() const { return QInternal::OpenGL; }
QSize size() const { return mWindow->geometry().size(); }
QGLContext* context() const { return QGLContext::fromPlatformGLContext(mWindow->glContext()); }
QPaintEngine *paintEngine() const { return qt_qgl_paint_engine(); }
void beginPaint(){
QGLPaintDevice::beginPaint();
}
private:
QPlatformWindow *mWindow;
PaintDeviceHelper *helper;
};
@implementation PaintDeviceHelper
@synthesize device;
- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer
{
Q_UNUSED(view)
if (device)
device->setFramebuffer(buffer);
}
@end
QT_BEGIN_NAMESPACE
QUIKitWindowSurface::QUIKitWindowSurface(QWidget *window)

View File

@ -49,7 +49,6 @@
QWaylandEglIntegration::QWaylandEglIntegration(struct wl_display *waylandDisplay)
: mWaylandDisplay(waylandDisplay)
, mNativeEglDisplay(wl_egl_display_create(mWaylandDisplay))
{
qDebug() << "Using Wayland-EGL";
}
@ -63,7 +62,7 @@ QWaylandEglIntegration::~QWaylandEglIntegration()
void QWaylandEglIntegration::initialize()
{
EGLint major,minor;
mEglDisplay = eglGetDisplay((EGLNativeDisplayType)mNativeEglDisplay);
mEglDisplay = eglGetDisplay(mWaylandDisplay);
if (mEglDisplay == NULL) {
qWarning("EGL not available");
} else {
@ -84,11 +83,6 @@ EGLDisplay QWaylandEglIntegration::eglDisplay() const
return mEglDisplay;
}
wl_egl_display * QWaylandEglIntegration::nativeDisplay() const
{
return mNativeEglDisplay;
}
QWaylandGLIntegration *QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay)
{
return new QWaylandEglIntegration(waylandDisplay->wl_display());

View File

@ -65,9 +65,6 @@ private:
struct wl_display *mWaylandDisplay;
EGLDisplay mEglDisplay;
struct wl_egl_display *mNativeEglDisplay;
};
#endif // QWAYLANDEGLINTEGRATION_H

View File

@ -103,7 +103,7 @@ void QWaylandEglWindow::newSurfaceCreated()
if (!size.isValid())
size = QSize(0,0);
mWaylandEglWindow = wl_egl_window_create(mEglIntegration->nativeDisplay(),mSurface,size.width(),size.height(),visual);
mWaylandEglWindow = wl_egl_window_create(mSurface,size.width(),size.height(),visual);
if (mGLContext) {
EGLNativeWindowType window(reinterpret_cast<EGLNativeWindowType>(mWaylandEglWindow));
EGLSurface surface = eglCreateWindowSurface(mEglIntegration->eglDisplay(),mGLContext->eglConfig(),window,NULL);

View File

@ -63,7 +63,6 @@ private:
QWaylandEglIntegration *mEglIntegration;
QWaylandGLContext *mGLContext;
struct wl_egl_window *mWaylandEglWindow;
EGLConfig mConfig;
const QWaylandWindow *mParentWindow;
};

View File

@ -1,12 +1,11 @@
include (../../../eglconvenience/eglconvenience.pri)
LIBS += -lwayland-egl -lEGL
INCLUDEPATH += $$PWD
SOURCES += $$PWD/qwaylandeglintegration.cpp \
$$PWD/qwaylandglcontext.cpp \
$$PWD/qwaylandeglwindow.cpp \
$$PWD/../../../eglconvenience/qeglconvenience.cpp
$$PWD/qwaylandeglwindow.cpp
HEADERS += $$PWD/qwaylandeglintegration.h \
$$PWD/qwaylandglcontext.h \
$$PWD/qwaylandeglwindow.h \
$$PWD/../../../eglconvenience/qeglconvenience.h \
gl_integration/wayland_egl/qwaylandeglinclude.h
$$PWD/qwaylandeglwindow.h

View File

@ -111,9 +111,9 @@ const struct wl_xcomposite_listener QWaylandXCompositeEGLIntegration::xcomposite
void QWaylandXCompositeEGLIntegration::wlDisplayHandleGlobal(wl_display *display, uint32_t id, const char *interface, uint32_t version, void *data)
{
Q_UNUSED(version);
if (strcmp(interface, "xcomposite") == 0) {
if (strcmp(interface, "wl_xcomposite") == 0) {
QWaylandXCompositeEGLIntegration *integration = static_cast<QWaylandXCompositeEGLIntegration *>(data);
integration->mWaylandComposite = wl_xcomposite_create(display,id);
integration->mWaylandComposite = wl_xcomposite_create(display,id,1);
wl_xcomposite_add_listener(integration->mWaylandComposite,&xcomposite_listener,integration);
}

View File

@ -106,9 +106,9 @@ const struct wl_xcomposite_listener QWaylandXCompositeGLXIntegration::xcomposite
void QWaylandXCompositeGLXIntegration::wlDisplayHandleGlobal(wl_display *display, uint32_t id, const char *interface, uint32_t version, void *data)
{
Q_UNUSED(version);
if (strcmp(interface, "xcomposite") == 0) {
if (strcmp(interface, "wl_xcomposite") == 0) {
QWaylandXCompositeGLXIntegration *integration = static_cast<QWaylandXCompositeGLXIntegration *>(data);
integration->mWaylandComposite = wl_xcomposite_create(display,id);
integration->mWaylandComposite = wl_xcomposite_create(display,id,1);
wl_xcomposite_add_listener(integration->mWaylandComposite,&xcomposite_listener,integration);
}

View File

@ -39,7 +39,6 @@
**
****************************************************************************/
#ifndef XCOMPOSITE_CLIENT_PROTOCOL_H
#define XCOMPOSITE_CLIENT_PROTOCOL_H
@ -55,84 +54,63 @@ struct wl_client;
struct wl_xcomposite;
struct wl_proxy;
extern void
wl_proxy_marshal(struct wl_proxy *p, uint32_t opcode, ...);
extern struct wl_proxy *
wl_proxy_create(struct wl_proxy *factory,
const struct wl_interface *interface);
extern struct wl_proxy *
wl_proxy_create_for_id(struct wl_display *display,
const struct wl_interface *interface, uint32_t id);
extern void
wl_proxy_destroy(struct wl_proxy *proxy);
extern int
wl_proxy_add_listener(struct wl_proxy *proxy,
void (**implementation)(void), void *data);
extern void
wl_proxy_set_user_data(struct wl_proxy *proxy, void *user_data);
extern void *
wl_proxy_get_user_data(struct wl_proxy *proxy);
extern const struct wl_interface wl_xcomposite_interface;
struct wl_xcomposite_listener {
void (*root)(void *data,
struct wl_xcomposite *xcomposite,
struct wl_xcomposite *wl_xcomposite,
const char *display_name,
uint32_t root_window);
};
static inline int
wl_xcomposite_add_listener(struct wl_xcomposite *xcomposite,
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;

View File

@ -43,17 +43,17 @@
#include <stdint.h>
#include "wayland-util.h"
static const struct wl_message xcomposite_requests[] = {
static const struct wl_message wl_xcomposite_requests[] = {
{ "create_buffer", "nuiio" },
};
static const struct wl_message xcomposite_events[] = {
static const struct wl_message wl_xcomposite_events[] = {
{ "root", "su" },
};
WL_EXPORT const struct wl_interface wl_xcomposite_interface = {
"xcomposite", 1,
ARRAY_LENGTH(xcomposite_requests), xcomposite_requests,
ARRAY_LENGTH(xcomposite_events), xcomposite_events,
"wl_xcomposite", 1,
ARRAY_LENGTH(wl_xcomposite_requests), wl_xcomposite_requests,
ARRAY_LENGTH(wl_xcomposite_events), wl_xcomposite_events,
};

View File

@ -44,6 +44,7 @@
#include <QtCore/QSize>
#include <wayland-client.h>
#include <wayland-client-protocol.h>
class QWaylandBuffer {

View File

@ -126,6 +126,7 @@ QWaylandDisplay::QWaylandDisplay(void)
#ifdef QT_WAYLAND_GL_SUPPORT
mEglIntegration = QWaylandGLIntegration::createGLIntegration(this);
#endif
blockingReadEvents();
qRegisterMetaType<uint32_t>("uint32_t");
@ -216,9 +217,6 @@ void QWaylandDisplay::outputHandleGeometry(void *data,
int32_t x, int32_t y,
int32_t width, int32_t height)
{
//call back function called from another thread;
//but its safe to call createScreen from another thread since
//QWaylandScreen does a moveToThread
QWaylandDisplay *waylandDisplay = static_cast<QWaylandDisplay *>(data);
QRect outputRect = QRect(x, y, width, height);
waylandDisplay->createNewScreen(output,outputRect);
@ -252,17 +250,17 @@ void QWaylandDisplay::displayHandleGlobal(uint32_t id,
{
Q_UNUSED(version);
if (interface == "output") {
struct wl_output *output = wl_output_create(mDisplay, id);
if (interface == "wl_output") {
struct wl_output *output = wl_output_create(mDisplay, id, 1);
wl_output_add_listener(output, &outputListener, this);
} else if (interface == "compositor") {
mCompositor = wl_compositor_create(mDisplay, id);
} else if (interface == "shm") {
mShm = wl_shm_create(mDisplay, id);
} else if (interface == "shell"){
mShell = wl_shell_create(mDisplay, id);
} else if (interface == "wl_compositor") {
mCompositor = wl_compositor_create(mDisplay, id, 1);
} else if (interface == "wl_shm") {
mShm = wl_shm_create(mDisplay, id, 1);
} else if (interface == "wl_shell"){
mShell = wl_shell_create(mDisplay, id, 1);
wl_shell_add_listener(mShell, &shellListener, this);
} else if (interface == "input_device") {
} else if (interface == "wl_input_device") {
QWaylandInputDevice *inputDevice =
new QWaylandInputDevice(mDisplay, id);
mInputDevices.append(inputDevice);

View File

@ -61,7 +61,7 @@
QWaylandInputDevice::QWaylandInputDevice(struct wl_display *display,
uint32_t id)
: mDisplay(display)
, mInputDevice(wl_input_device_create(display, id))
, mInputDevice(wl_input_device_create(display, id, 1))
, mPointerFocus(NULL)
, mKeyboardFocus(NULL)
, mButtons(0)
@ -101,6 +101,12 @@ void QWaylandInputDevice::inputHandleMotion(void *data,
QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data;
QWaylandWindow *window = inputDevice->mPointerFocus;
if (window == NULL) {
/* We destroyed the pointer focus surface, but the server
* didn't get the message yet. */
return;
}
inputDevice->mSurfacePos = QPoint(surface_x, surface_y);
inputDevice->mGlobalPos = QPoint(x, y);
inputDevice->mTime = time;
@ -120,6 +126,12 @@ void QWaylandInputDevice::inputHandleButton(void *data,
QWaylandWindow *window = inputDevice->mPointerFocus;
Qt::MouseButton qt_button;
if (window == NULL) {
/* We destroyed the pointer focus surface, but the server
* didn't get the message yet. */
return;
}
switch (button) {
case 272:
qt_button = Qt::LeftButton;
@ -229,6 +241,12 @@ void QWaylandInputDevice::inputHandleKey(void *data,
QEvent::Type type;
char s[2];
if (window == NULL) {
/* We destroyed the keyboard focus surface, but the server
* didn't get the message yet. */
return;
}
code = key + inputDevice->mXkb->min_key_code;
level = 0;
@ -250,9 +268,6 @@ void QWaylandInputDevice::inputHandleKey(void *data,
sym = translateKey(sym, s, sizeof s);
qWarning("keycode %d, sym %d, string %d, modifiers 0x%x",
code, sym, s[0], (int) inputDevice->mModifiers);
if (window) {
QWindowSystemInterface::handleKeyEvent(window->widget(),
time, type, sym,

View File

@ -44,6 +44,7 @@
#include "qwaylanddisplay.h"
#include "qwaylandshmsurface.h"
#include "qwaylandshmwindow.h"
#include "qwaylandnativeinterface.h"
#include "qgenericunixfontdatabase.h"
@ -62,9 +63,15 @@ QWaylandIntegration::QWaylandIntegration(bool useOpenGL)
: mFontDb(new QGenericUnixFontDatabase())
, mDisplay(new QWaylandDisplay())
, mUseOpenGL(useOpenGL)
, mNativeInterface(new QWaylandNativeInterface)
{
}
QPlatformNativeInterface * QWaylandIntegration::nativeInterface() const
{
return mNativeInterface;
}
QList<QPlatformScreen *>
QWaylandIntegration::screens() const
{

View File

@ -63,12 +63,15 @@ public:
QPlatformFontDatabase *fontDatabase() const;
QPlatformNativeInterface *nativeInterface() const;
private:
bool hasOpenGL() const;
QPlatformFontDatabase *mFontDb;
QWaylandDisplay *mDisplay;
bool mUseOpenGL;
QPlatformNativeInterface *mNativeInterface;
};
QT_END_NAMESPACE

View File

@ -0,0 +1,72 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwaylandnativeinterface.h"
#include "qwaylanddisplay.h"
#include "qwaylandwindow.h"
#include <QtGui/private/qapplication_p.h>
void *QWaylandNativeInterface::nativeResourceForWidget(const QByteArray &resourceString, QWidget *widget)
{
QByteArray lowerCaseResource = resourceString.toLower();
if (lowerCaseResource == "display")
return qPlatformScreenForWidget(widget)->display()->wl_display();
if (lowerCaseResource == "surface") {
return ((QWaylandWindow *) widget->platformWindow())->wl_surface();
}
return NULL;
}
QWaylandScreen * QWaylandNativeInterface::qPlatformScreenForWidget(QWidget *widget)
{
QWaylandScreen *screen;
if (widget) {
screen = static_cast<QWaylandScreen *>(QPlatformScreen::platformScreenForWidget(widget));
} else {
screen = static_cast<QWaylandScreen *>(QApplicationPrivate::platformIntegration()->screens()[0]);
}
return screen;
}

View File

@ -0,0 +1,60 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QWAYLANDNATIVEINTERFACE_H
#define QWAYLANDNATIVEINTERFACE_H
#include "qwaylandscreen.h"
#include <QtGui/QPlatformNativeInterface>
class QWaylandNativeInterface : public QPlatformNativeInterface
{
public:
void *nativeResourceForWidget(const QByteArray &resourceString,
QWidget *widget);
private:
static QWaylandScreen *qPlatformScreenForWidget(QWidget *widget);
};
#endif // QWAYLANDNATIVEINTERFACE_H

View File

@ -146,6 +146,7 @@ void QWaylandWindow::newSurfaceCreated()
void QWaylandWindow::frameCallback(struct wl_surface *surface, void *data, uint32_t time)
{
Q_UNUSED(time);
Q_UNUSED(surface);
QWaylandWindow *self = static_cast<QWaylandWindow*>(data);
self->mWaitingForFrameSync = false;
}

View File

@ -74,6 +74,9 @@ public:
void damage(const QRegion &region);
void waitForFrameSync();
struct wl_surface *wl_surface() const { return mSurface; }
protected:
struct wl_surface *mSurface;
virtual void newSurfaceCreated();

View File

@ -8,6 +8,7 @@ DEFINES += $$QMAKE_DEFINES_WAYLAND
SOURCES = main.cpp \
qwaylandintegration.cpp \
qwaylandnativeinterface.cpp \
qwaylandshmsurface.cpp \
qwaylandinputdevice.cpp \
qwaylandcursor.cpp \
@ -17,6 +18,7 @@ SOURCES = main.cpp \
qwaylandshmwindow.cpp
HEADERS = qwaylandintegration.h \
qwaylandnativeinterface.h \
qwaylandcursor.h \
qwaylanddisplay.h \
qwaylandwindow.h \

View File

@ -71,6 +71,10 @@ private slots:
void bidiReorderString();
void bidiCursor_qtbug2795();
void bidiCursor_PDF();
void bidiCursorMovement_data();
void bidiCursorMovement();
void bidiCursorLogicalMovement_data();
void bidiCursorLogicalMovement();
};
tst_QComplexText::tst_QComplexText()
@ -185,6 +189,90 @@ void tst_QComplexText::bidiCursor_qtbug2795()
QVERIFY(x1 == x2);
}
void tst_QComplexText::bidiCursorMovement_data()
{
QTest::addColumn<QString>("logical");
QTest::addColumn<int>("basicDir");
const LV *data = logical_visual;
while ( data->name ) {
//next we fill it with data
QTest::newRow( data->name )
<< QString::fromUtf8( data->logical )
<< (int) data->basicDir;
data++;
}
}
void tst_QComplexText::bidiCursorMovement()
{
QFETCH(QString, logical);
QFETCH(int, basicDir);
QTextLayout layout(logical);
QTextOption option = layout.textOption();
option.setTextDirection(basicDir == QChar::DirL ? Qt::LeftToRight : Qt::RightToLeft);
layout.setTextOption(option);
layout.setCursorMoveStyle(QTextCursor::Visual);
bool moved;
int oldPos, newPos = 0;
qreal x, newX;
layout.beginLayout();
QTextLine line = layout.createLine();
layout.endLayout();
newX = line.cursorToX(0);
do {
oldPos = newPos;
x = newX;
newX = line.cursorToX(oldPos);
if (basicDir == QChar::DirL) {
QVERIFY(newX >= x);
newPos = layout.rightCursorPosition(oldPos);
} else
{
QVERIFY(newX <= x);
newPos = layout.leftCursorPosition(oldPos);
}
moved = (oldPos != newPos);
} while (moved);
}
void tst_QComplexText::bidiCursorLogicalMovement_data()
{
bidiCursorMovement_data();
}
void tst_QComplexText::bidiCursorLogicalMovement()
{
QFETCH(QString, logical);
QFETCH(int, basicDir);
QTextLayout layout(logical);
QTextOption option = layout.textOption();
option.setTextDirection(basicDir == QChar::DirL ? Qt::LeftToRight : Qt::RightToLeft);
layout.setTextOption(option);
bool moved;
int oldPos, newPos = 0;
do {
oldPos = newPos;
newPos = layout.nextCursorPosition(oldPos);
QVERIFY(newPos >= oldPos);
moved = (oldPos != newPos);
} while (moved);
do {
oldPos = newPos;
newPos = layout.previousCursorPosition(oldPos);
QVERIFY(newPos <= oldPos);
moved = (oldPos != newPos);
} while (moved);
}
void tst_QComplexText::bidiCursor_PDF()
{
QString str = QString::fromUtf8("\342\200\252hello\342\200\254");

View File

@ -282,6 +282,12 @@ private slots:
void validateAndSet();
#endif
void bidiVisualMovement_data();
void bidiVisualMovement();
void bidiLogicalMovement_data();
void bidiLogicalMovement();
protected slots:
#ifdef QT3_SUPPORT
void lostFocus();
@ -3760,5 +3766,135 @@ void tst_QLineEdit::QTBUG13520_textNotVisible()
}
void tst_QLineEdit::bidiVisualMovement_data()
{
QTest::addColumn<QString>("logical");
QTest::addColumn<int>("basicDir");
QTest::addColumn<IntList>("positionList");
QTest::newRow("Latin text")
<< QString::fromUtf8("abc")
<< (int) QChar::DirL
<< (IntList() << 0 << 1 << 2 << 3);
QTest::newRow("Hebrew text, one item")
<< QString::fromUtf8("\327\220\327\221\327\222")
<< (int) QChar::DirR
<< (QList<int>() << 0 << 1 << 2 << 3);
QTest::newRow("Hebrew text after Latin text")
<< QString::fromUtf8("abc\327\220\327\221\327\222")
<< (int) QChar::DirL
<< (QList<int>() << 0 << 1 << 2 << 6 << 5 << 4 << 3);
QTest::newRow("Latin text after Hebrew text")
<< QString::fromUtf8("\327\220\327\221\327\222abc")
<< (int) QChar::DirR
<< (QList<int>() << 0 << 1 << 2 << 6 << 5 << 4 << 3);
QTest::newRow("LTR, 3 items")
<< QString::fromUtf8("abc\327\220\327\221\327\222abc")
<< (int) QChar::DirL
<< (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 9);
QTest::newRow("RTL, 3 items")
<< QString::fromUtf8("\327\220\327\221\327\222abc\327\220\327\221\327\222")
<< (int) QChar::DirR
<< (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 9);
QTest::newRow("LTR, 4 items")
<< QString::fromUtf8("abc\327\220\327\221\327\222abc\327\220\327\221\327\222")
<< (int) QChar::DirL
<< (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 12 << 11 << 10 << 9);
QTest::newRow("RTL, 4 items")
<< QString::fromUtf8("\327\220\327\221\327\222abc\327\220\327\221\327\222abc")
<< (int) QChar::DirR
<< (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 12 << 11 << 10 << 9);
}
void tst_QLineEdit::bidiVisualMovement()
{
QFETCH(QString, logical);
QFETCH(int, basicDir);
QFETCH(IntList, positionList);
QLineEdit le;
le.setText(logical);
le.setCursorMoveStyle(QTextCursor::Visual);
le.setCursorPosition(0);
bool moved;
int i = 0, oldPos, newPos = 0;
do {
oldPos = newPos;
QVERIFY(oldPos == positionList[i]);
if (basicDir == QChar::DirL) {
QTest::keyClick(&le, Qt::Key_Right);
} else
QTest::keyClick(&le, Qt::Key_Left);
newPos = le.cursorPosition();
moved = (oldPos != newPos);
i++;
} while (moved);
QVERIFY(i == positionList.size());
do {
i--;
oldPos = newPos;
QVERIFY(oldPos == positionList[i]);
if (basicDir == QChar::DirL) {
QTest::keyClick(&le, Qt::Key_Left);
} else
{
QTest::keyClick(&le, Qt::Key_Right);
}
newPos = le.cursorPosition();
moved = (oldPos != newPos);
} while (moved && i >= 0);
}
void tst_QLineEdit::bidiLogicalMovement_data()
{
bidiVisualMovement_data();
}
void tst_QLineEdit::bidiLogicalMovement()
{
QFETCH(QString, logical);
QFETCH(int, basicDir);
QLineEdit le;
le.setText(logical);
le.setCursorMoveStyle(QTextCursor::Logical);
le.setCursorPosition(0);
bool moved;
int i = 0, oldPos, newPos = 0;
do {
oldPos = newPos;
QVERIFY(oldPos == i);
if (basicDir == QChar::DirL) {
QTest::keyClick(&le, Qt::Key_Right);
} else
QTest::keyClick(&le, Qt::Key_Left);
newPos = le.cursorPosition();
moved = (oldPos != newPos);
i++;
} while (moved);
do {
i--;
oldPos = newPos;
QVERIFY(oldPos == i);
if (basicDir == QChar::DirL) {
QTest::keyClick(&le, Qt::Key_Left);
} else
{
QTest::keyClick(&le, Qt::Key_Right);
}
newPos = le.cursorPosition();
moved = (oldPos != newPos);
} while (moved && i >= 0);
}
QTEST_MAIN(tst_QLineEdit)
#include "tst_qlineedit.moc"

Some files were not shown because too many files have changed in this diff Show More