From 5b7d75a57e0ec8ee78f843ab0eb6485b8e3b4a22 Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Wed, 22 Sep 2010 15:41:34 +1000 Subject: Verify the audio format before trying to open an audio device. This was causing a crash on windows because the buffer and period sizes were worked out to 0 with an invalid sample size and dividing one by the other is division by 0. Task-number: QTMOBILITY-438 Reviewed-by: Justin McPherson --- src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp | 23 ++++++----- src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp | 8 +++- src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp | 11 +++++- src/multimedia/audio/qaudioinput_alsa_p.cpp | 24 ++++++++++-- src/multimedia/audio/qaudioinput_mac_p.cpp | 2 +- src/multimedia/audio/qaudioinput_win32_p.cpp | 41 +++++++++++++++++--- src/multimedia/audio/qaudiooutput_alsa_p.cpp | 23 +++++++++-- src/multimedia/audio/qaudiooutput_mac_p.cpp | 6 ++- src/multimedia/audio/qaudiooutput_mac_p.h | 2 + src/multimedia/audio/qaudiooutput_win32_p.cpp | 36 ++++++++++++----- tests/auto/qaudioinput/tst_qaudioinput.cpp | 47 +++++++++++++++++++++++ tests/auto/qaudiooutput/tst_qaudiooutput.cpp | 47 +++++++++++++++++++++++ 12 files changed, 235 insertions(+), 35 deletions(-) diff --git a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp index 633b309..25622a4 100644 --- a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp +++ b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp @@ -257,37 +257,40 @@ bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const // set the values! snd_pcm_hw_params_set_channels(handle,params,format.channels()); snd_pcm_hw_params_set_rate(handle,params,format.frequency(),dir); + + err = -1; + switch(format.sampleSize()) { case 8: if(format.sampleType() == QAudioFormat::SignedInt) - snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S8); + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S8); else if(format.sampleType() == QAudioFormat::UnSignedInt) - snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U8); + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U8); break; case 16: if(format.sampleType() == QAudioFormat::SignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) - snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_LE); + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) - snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_BE); + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_BE); } else if(format.sampleType() == QAudioFormat::UnSignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) - snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_LE); + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) - snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_BE); + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_BE); } break; case 32: if(format.sampleType() == QAudioFormat::SignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) - snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_LE); + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) - snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_BE); + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_BE); } else if(format.sampleType() == QAudioFormat::UnSignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) - snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_LE); + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) - snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_BE); + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_BE); } } diff --git a/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp index ecd03e5..1909009 100644 --- a/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp +++ b/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp @@ -78,7 +78,13 @@ QAudioDeviceInfoInternal::QAudioDeviceInfoInternal(QByteArray const& handle, QAu bool QAudioDeviceInfoInternal::isFormatSupported(const QAudioFormat& format) const { - return format.codec() == QString::fromLatin1("audio/pcm"); + QAudioDeviceInfoInternal *self = const_cast(this); + + return format.isValid() + && format.codec() == QString::fromLatin1("audio/pcm") + && self->supportedSampleRates().contains(format.sampleRate()) + && self->supportedChannelCounts().contains(format.channelCount()) + && self->supportedSampleSizes().contains(format.sampleSize()); } QAudioFormat QAudioDeviceInfoInternal::preferredFormat() const diff --git a/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp index 4e6b2df..a4b28d4 100644 --- a/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp +++ b/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp @@ -196,8 +196,9 @@ bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const break; } } + if (!match) + failed = true; } - if (!match) failed = true; // check frequency match = false; @@ -208,6 +209,8 @@ bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const break; } } + if (!match) + failed = true; } // check sample size @@ -219,6 +222,8 @@ bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const break; } } + if (!match) + failed = true; } // check byte order @@ -230,6 +235,8 @@ bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const break; } } + if (!match) + failed = true; } // check sample type @@ -241,6 +248,8 @@ bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const break; } } + if (!match) + failed = true; } if(!failed) { diff --git a/src/multimedia/audio/qaudioinput_alsa_p.cpp b/src/multimedia/audio/qaudioinput_alsa_p.cpp index 58669b3..ddafa3d 100644 --- a/src/multimedia/audio/qaudioinput_alsa_p.cpp +++ b/src/multimedia/audio/qaudioinput_alsa_p.cpp @@ -152,7 +152,7 @@ int QAudioInputPrivate::xrun_recovery(int err) int QAudioInputPrivate::setFormat() { - snd_pcm_format_t format = SND_PCM_FORMAT_S16; + snd_pcm_format_t format = SND_PCM_FORMAT_UNKNOWN; if(settings.sampleSize() == 8) { format = SND_PCM_FORMAT_U8; @@ -204,7 +204,9 @@ int QAudioInputPrivate::setFormat() format = SND_PCM_FORMAT_FLOAT64_BE; } - return snd_pcm_hw_params_set_format( handle, hwparams, format); + return format != SND_PCM_FORMAT_UNKNOWN + ? snd_pcm_hw_params_set_format( handle, hwparams, format) + : -1; } QIODevice* QAudioInputPrivate::start(QIODevice* device) @@ -259,10 +261,26 @@ bool QAudioInputPrivate::open() elapsedTimeOffset = 0; int dir; - int err=-1; + int err = 0; int count=0; unsigned int freakuency=settings.frequency(); + if (!settings.isValid()) { + qWarning("QAudioOutput: open error, invalid format."); + } else if (settings.frequency() <= 0) { + qWarning("QAudioOutput: open error, invalid sample rate (%d).", + settings.frequency()); + } else { + err = -1; + } + + if (err == 0) { + errorState = QAudio::OpenError; + deviceState = QAudio::StoppedState; + return false; + } + + QString dev = QString(QLatin1String(m_device.constData())); QList devices = QAudioDeviceInfoInternal::availableDevices(QAudio::AudioInput); if(dev.compare(QLatin1String("default")) == 0) { diff --git a/src/multimedia/audio/qaudioinput_mac_p.cpp b/src/multimedia/audio/qaudioinput_mac_p.cpp index 5897e75..c3d2ae2 100644 --- a/src/multimedia/audio/qaudioinput_mac_p.cpp +++ b/src/multimedia/audio/qaudioinput_mac_p.cpp @@ -717,7 +717,7 @@ QIODevice* QAudioInputPrivate::start(QIODevice* device) { QIODevice* op = device; - if (!audioFormat.isValid() || !open()) { + if (!audioDeviceInfo->isFormatSupported(audioFormat) || !open()) { stateCode = QAudio::StoppedState; errorCode = QAudio::OpenError; return audioIO; diff --git a/src/multimedia/audio/qaudioinput_win32_p.cpp b/src/multimedia/audio/qaudioinput_win32_p.cpp index 3f6e778..225d2f1 100644 --- a/src/multimedia/audio/qaudioinput_win32_p.cpp +++ b/src/multimedia/audio/qaudioinput_win32_p.cpp @@ -214,13 +214,44 @@ bool QAudioInputPrivate::open() qDebug()< 48000) { + qWarning("QAudioInput: open error, frequency out of range (%d).", settings.frequency()); + } else if (buffer_size == 0) { + + buffer_size + = (settings.frequency() + * settings.channels() + * settings.sampleSize() +#ifndef Q_OS_WINCE // Default buffer size, 200ms, default period size is 40ms + + 39) / 40; + period_size = buffer_size / 5; + } else { + period_size = buffer_size / 5; +#else // For wince reduce size to 40ms for buffer size and 20ms period + + 199) / 200; + period_size = buffer_size / 2; } else { - period_size = buffer_size/5; + period_size = buffer_size / 2; +#endif } + + if (period_size == 0) { + errorState = QAudio::OpenError; + deviceState = QAudio::StoppedState; + emit stateChanged(deviceState); + return false; + } + timeStamp.restart(); elapsedTimeOffset = 0; wfx.nSamplesPerSec = settings.frequency(); diff --git a/src/multimedia/audio/qaudiooutput_alsa_p.cpp b/src/multimedia/audio/qaudiooutput_alsa_p.cpp index 49b32c0..ecf3215 100644 --- a/src/multimedia/audio/qaudiooutput_alsa_p.cpp +++ b/src/multimedia/audio/qaudiooutput_alsa_p.cpp @@ -155,7 +155,7 @@ int QAudioOutputPrivate::xrun_recovery(int err) int QAudioOutputPrivate::setFormat() { - snd_pcm_format_t pcmformat = SND_PCM_FORMAT_S16; + snd_pcm_format_t pcmformat = SND_PCM_FORMAT_UNKNOWN; if(settings.sampleSize() == 8) { pcmformat = SND_PCM_FORMAT_U8; @@ -208,7 +208,9 @@ int QAudioOutputPrivate::setFormat() pcmformat = SND_PCM_FORMAT_FLOAT64_BE; } - return snd_pcm_hw_params_set_format( handle, hwparams, pcmformat); + return pcmformat != SND_PCM_FORMAT_UNKNOWN + ? snd_pcm_hw_params_set_format( handle, hwparams, pcmformat) + : -1; } QIODevice* QAudioOutputPrivate::start(QIODevice* device) @@ -275,10 +277,25 @@ bool QAudioOutputPrivate::open() elapsedTimeOffset = 0; int dir; - int err=-1; + int err = 0; int count=0; unsigned int freakuency=settings.frequency(); + if (!settings.isValid()) { + qWarning("QAudioOutput: open error, invalid format."); + } else if (settings.frequency() <= 0) { + qWarning("QAudioOutput: open error, invalid sample rate (%d).", + settings.frequency()); + } else { + err = -1; + } + + if (err == 0) { + errorState = QAudio::OpenError; + deviceState = QAudio::StoppedState; + return false; + } + QString dev = QString(QLatin1String(m_device.constData())); QList devices = QAudioDeviceInfoInternal::availableDevices(QAudio::AudioOutput); if(dev.compare(QLatin1String("default")) == 0) { diff --git a/src/multimedia/audio/qaudiooutput_mac_p.cpp b/src/multimedia/audio/qaudiooutput_mac_p.cpp index cc52d90..86a2e31 100644 --- a/src/multimedia/audio/qaudiooutput_mac_p.cpp +++ b/src/multimedia/audio/qaudiooutput_mac_p.cpp @@ -60,11 +60,11 @@ #include #include -#include #include #include "qaudio_mac_p.h" #include "qaudiooutput_mac_p.h" +#include "qaudiodeviceinfo_mac_p.h" QT_BEGIN_NAMESPACE @@ -278,6 +278,7 @@ QAudioOutputPrivate::QAudioOutputPrivate(const QByteArray& device, const QAudioF if (QAudio::Mode(mode) == QAudio::AudioInput) errorCode = QAudio::OpenError; else { + audioDeviceInfo = new QAudioDeviceInfoInternal(device, QAudio::AudioOutput); isOpen = false; audioDeviceId = AudioDeviceID(did); audioUnit = 0; @@ -299,6 +300,7 @@ QAudioOutputPrivate::QAudioOutputPrivate(const QByteArray& device, const QAudioF QAudioOutputPrivate::~QAudioOutputPrivate() { + delete audioDeviceInfo; close(); } @@ -424,7 +426,7 @@ QIODevice* QAudioOutputPrivate::start(QIODevice* device) { QIODevice* op = device; - if (!audioFormat.isValid() || !open()) { + if (!audioDeviceInfo->isFormatSupported(audioFormat) || !open()) { stateCode = QAudio::StoppedState; errorCode = QAudio::OpenError; return audioIO; diff --git a/src/multimedia/audio/qaudiooutput_mac_p.h b/src/multimedia/audio/qaudiooutput_mac_p.h index 752905c..7013961 100644 --- a/src/multimedia/audio/qaudiooutput_mac_p.h +++ b/src/multimedia/audio/qaudiooutput_mac_p.h @@ -73,6 +73,7 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE class QIODevice; +class QAbstractAudioDeviceInfo; namespace QtMultimediaInternal { @@ -101,6 +102,7 @@ public: QWaitCondition threadFinished; QMutex mutex; QTimer* intervalTimer; + QAbstractAudioDeviceInfo *audioDeviceInfo; QAudio::Error errorCode; QAudio::State stateCode; diff --git a/src/multimedia/audio/qaudiooutput_win32_p.cpp b/src/multimedia/audio/qaudiooutput_win32_p.cpp index 09771b3..f038e51 100644 --- a/src/multimedia/audio/qaudiooutput_win32_p.cpp +++ b/src/multimedia/audio/qaudiooutput_win32_p.cpp @@ -251,20 +251,38 @@ bool QAudioOutputPrivate::open() QTime now(QTime::currentTime()); qDebug()<= 8000 && settings.frequency() <= 48000)) { + + period_size = 0; + + if (!settings.isValid()) { + qWarning("QAudioOutput: open error, invalid format."); + } else if (settings.channels() <= 0) { + qWarning("QAudioOutput: open error, invalid number of channels (%d).", + settings.channels()); + } else if (settings.sampleSize() <= 0) { + qWarning("QAudioOutput: open error, invalid sample size (%d).", + settings.sampleSize()); + } else if (settings.frequency() < 8000 || settings.frequency() > 48000) { + qWarning("QAudioOutput: open error, frequency out of range (%d).", settings.frequency()); + } else if (buffer_size == 0) { + // Default buffer size, 200ms, default period size is 40ms + buffer_size + = (settings.frequency() + * settings.channels() + * settings.sampleSize() + + 39) / 40; + period_size = buffer_size / 5; + } else { + period_size = buffer_size / 5; + } + + if (period_size == 0) { errorState = QAudio::OpenError; deviceState = QAudio::StoppedState; emit stateChanged(deviceState); - qWarning("QAudioOutput: open error, frequency out of range."); return false; } - if(buffer_size == 0) { - // Default buffer size, 200ms, default period size is 40ms - buffer_size = settings.frequency()*settings.channels()*(settings.sampleSize()/8)*0.2; - period_size = buffer_size/5; - } else { - period_size = buffer_size/5; - } + waveBlocks = allocateBlocks(period_size, buffer_size/period_size); mutex.lock(); diff --git a/tests/auto/qaudioinput/tst_qaudioinput.cpp b/tests/auto/qaudioinput/tst_qaudioinput.cpp index 84c3874..1808b1d 100644 --- a/tests/auto/qaudioinput/tst_qaudioinput.cpp +++ b/tests/auto/qaudioinput/tst_qaudioinput.cpp @@ -50,6 +50,8 @@ #define SRCDIR "" #endif +Q_DECLARE_METATYPE(QAudioFormat) + class tst_QAudioInput : public QObject { Q_OBJECT @@ -58,6 +60,8 @@ public: private slots: void initTestCase(); + void invalidFormat_data(); + void invalidFormat(); void settings(); void buffers(); void notifyInterval(); @@ -71,6 +75,8 @@ private: void tst_QAudioInput::initTestCase() { + qRegisterMetaType(); + format.setFrequency(8000); format.setChannels(1); format.setSampleSize(8); @@ -91,6 +97,47 @@ void tst_QAudioInput::initTestCase() audio = new QAudioInput(format, this); } +void tst_QAudioInput::invalidFormat_data() +{ + QTest::addColumn("invalidFormat"); + + QAudioFormat audioFormat; + + QTest::newRow("Null Format") + << audioFormat; + + audioFormat = format; + audioFormat.setChannels(0); + QTest::newRow("Channel count 0") + << audioFormat; + + audioFormat = format; + audioFormat.setFrequency(0); + QTest::newRow("Sample rate 0") + << audioFormat; + + audioFormat = format; + audioFormat.setSampleSize(0); + QTest::newRow("Sample size 0") + << audioFormat; +} + +void tst_QAudioInput::invalidFormat() +{ + QFETCH(QAudioFormat, invalidFormat); + + QAudioInput audioInput(invalidFormat, this); + + // Check that we are in the default state before calling start + QVERIFY2((audioInput.state() == QAudio::StoppedState), "state() was not set to StoppedState before start()"); + QVERIFY2((audioInput.error() == QAudio::NoError), "error() was not set to QAudio::NoError before start()"); + + audioInput.start(); + + // Check that error is raised + QVERIFY2((audioInput.error() == QAudio::OpenError),"error() was not set to QAudio::OpenError after start()"); +} + void tst_QAudioInput::settings() { if(available) { diff --git a/tests/auto/qaudiooutput/tst_qaudiooutput.cpp b/tests/auto/qaudiooutput/tst_qaudiooutput.cpp index 437ef5e..e6d11a6 100644 --- a/tests/auto/qaudiooutput/tst_qaudiooutput.cpp +++ b/tests/auto/qaudiooutput/tst_qaudiooutput.cpp @@ -52,6 +52,8 @@ #define SRCDIR "" #endif +Q_DECLARE_METATYPE(QAudioFormat) + class tst_QAudioOutput : public QObject { Q_OBJECT @@ -60,6 +62,8 @@ public: private slots: void initTestCase(); + void invalidFormat_data(); + void invalidFormat(); void settings(); void buffers(); void notifyInterval(); @@ -74,6 +78,8 @@ private: void tst_QAudioOutput::initTestCase() { + qRegisterMetaType(); + format.setFrequency(8000); format.setChannels(1); format.setSampleSize(8); @@ -92,6 +98,47 @@ void tst_QAudioOutput::initTestCase() audio = new QAudioOutput(format, this); } +void tst_QAudioOutput::invalidFormat_data() +{ + QTest::addColumn("invalidFormat"); + + QAudioFormat audioFormat; + + QTest::newRow("Null Format") + << audioFormat; + + audioFormat = format; + audioFormat.setChannels(0); + QTest::newRow("Channel count 0") + << audioFormat; + + audioFormat = format; + audioFormat.setFrequency(0); + QTest::newRow("Sample rate 0") + << audioFormat; + + audioFormat = format; + audioFormat.setSampleSize(0); + QTest::newRow("Sample size 0") + << audioFormat; +} + +void tst_QAudioOutput::invalidFormat() +{ + QFETCH(QAudioFormat, invalidFormat); + + QAudioOutput audioOutput(invalidFormat, this); + + // Check that we are in the default state before calling start + QVERIFY2((audioOutput.state() == QAudio::StoppedState), "state() was not set to StoppedState before start()"); + QVERIFY2((audioOutput.error() == QAudio::NoError), "error() was not set to QAudio::NoError before start()"); + + audioOutput.start(); + + // Check that error is raised + QVERIFY2((audioOutput.error() == QAudio::OpenError),"error() was not set to QAudio::OpenError after start()"); +} + void tst_QAudioOutput::settings() { if(available) { -- cgit v0.12 From 51de46840d32f714faa4717ae54a1e8559a43eab Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Thu, 23 Sep 2010 09:54:03 +1000 Subject: Fix compile failure in QtMultimedia. QAudioFormat::sampleRate() and QAudioFormat::channelCount() weren't introduced until 4.7. Use frequency() and channels() instead. Reviewed-by: Justin McPherson --- src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp index 1909009..d3dfa5f 100644 --- a/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp +++ b/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp @@ -82,9 +82,9 @@ bool QAudioDeviceInfoInternal::isFormatSupported(const QAudioFormat& format) con return format.isValid() && format.codec() == QString::fromLatin1("audio/pcm") - && self->supportedSampleRates().contains(format.sampleRate()) - && self->supportedChannelCounts().contains(format.channelCount()) - && self->supportedSampleSizes().contains(format.sampleSize()); + && self->frequencyList().contains(format.frequency()) + && self->channelsList().contains(format.channels()) + && self->sampleSizeList().contains(format.sampleSize()); } QAudioFormat QAudioDeviceInfoInternal::preferredFormat() const -- cgit v0.12 From 992809f9ba91c50bc759508127b493172236c149 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Thu, 23 Sep 2010 12:36:42 +0200 Subject: Fixes gray_raster incorrectly reporting out of memory error. The bug caused a useless realloction everytime a path was rasterized with gray_raster. Task-number: QTBUG-13871 Reviewed-by: Samuel --- src/gui/painting/qgrayraster.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/painting/qgrayraster.c b/src/gui/painting/qgrayraster.c index 94039fb..19cef49 100644 --- a/src/gui/painting/qgrayraster.c +++ b/src/gui/painting/qgrayraster.c @@ -324,6 +324,7 @@ { void* buffer; long buffer_size; + long buffer_allocated_size; int band_size; void* memory; PWorker worker; @@ -1767,7 +1768,7 @@ // If raster object and raster buffer are allocated, but // raster size isn't of the minimum size, indicate out of // memory. - if (raster && raster->buffer && raster->buffer_size < MINIMUM_POOL_SIZE ) + if (raster->buffer_allocated_size < MINIMUM_POOL_SIZE ) return ErrRaster_OutOfMemory; /* return immediately if the outline is empty */ @@ -1906,6 +1907,7 @@ rast->buffer_size = 0; rast->worker = NULL; } + rast->buffer_allocated_size = pool_size; } } -- cgit v0.12 From d31dcaf0c17d56f74d4faeaae3b5ce54ed847ee6 Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Fri, 24 Sep 2010 12:47:06 +0200 Subject: Named anonymous struct in the OpenGL paint engine. Task-number: QTBUG-13926 Reviewed-by: Gunnar --- src/opengl/qpaintengine_opengl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp index 58778ea..2f17aa6 100644 --- a/src/opengl/qpaintengine_opengl.cpp +++ b/src/opengl/qpaintengine_opengl.cpp @@ -506,12 +506,12 @@ struct QDrawQueueItem ////////// GL program cache: start -typedef struct { +struct GLProgram { int brush; // brush index or mask index int mode; // composition mode index bool mask; GLuint program; -} GLProgram; +}; typedef QMultiHash QGLProgramHash; -- cgit v0.12 From 4e781b65c60c6bdf0917fe9983a4f1e699643e55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Fri, 24 Sep 2010 13:16:01 +0200 Subject: Don't pretend to support single buffered EGL surfaces. Task-number: QTBUG-12865 Reviewed-by: Samuel --- src/opengl/qgl.cpp | 3 +++ src/opengl/qgl_egl.cpp | 1 + 2 files changed, 4 insertions(+) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 0d1a66e..b678790 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -509,6 +509,9 @@ QGLFormat::~QGLFormat() exchange the screen contents with the buffer. The result is flicker-free drawing and often better performance. + Note that single buffered contexts are currently not supported + with EGL. + \sa doubleBuffer(), QGLContext::swapBuffers(), QGLWidget::swapBuffers() */ diff --git a/src/opengl/qgl_egl.cpp b/src/opengl/qgl_egl.cpp index ebd1169..c79c4cd 100644 --- a/src/opengl/qgl_egl.cpp +++ b/src/opengl/qgl_egl.cpp @@ -143,6 +143,7 @@ void qt_glformat_from_eglconfig(QGLFormat& format, const EGLConfig config) format.setRgba(true); // EGL doesn't support colour index rendering format.setStereo(false); // EGL doesn't support stereo buffers format.setAccumBufferSize(0); // EGL doesn't support accululation buffers + format.setDoubleBuffer(true); // We don't support single buffered EGL contexts // Clear the EGL error state because some of the above may // have errored out because the attribute is not applicable -- cgit v0.12 From d5e6aa0a70004338a644387ba3d682a73fa169a9 Mon Sep 17 00:00:00 2001 From: aavit Date: Fri, 24 Sep 2010 16:49:19 +0200 Subject: Optimization of pixel conversion when storing jpeg Reviewed-by: Kim --- src/gui/image/qjpeghandler.cpp | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/gui/image/qjpeghandler.cpp b/src/gui/image/qjpeghandler.cpp index b9eda05..d47cc82 100644 --- a/src/gui/image/qjpeghandler.cpp +++ b/src/gui/image/qjpeghandler.cpp @@ -648,22 +648,28 @@ static bool write_jpeg_image(const QImage &image, QIODevice *device, int sourceQ break; case QImage::Format_RGB32: case QImage::Format_ARGB32: - case QImage::Format_ARGB32_Premultiplied: { - const QRgb* rgb = (const QRgb*)image.constScanLine(cinfo.next_scanline); - for (int i=0; i Date: Mon, 27 Sep 2010 07:10:54 +0200 Subject: fix documentation of drawText(int, int, int, int, ... --- src/gui/painting/qpainter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 12be93e..376d68b 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -6185,7 +6185,7 @@ void QPainter::drawText(const QRectF &r, int flags, const QString &str, QRectF * By default, QPainter draws text anti-aliased. - \note The y-position is used as the baseline of the font. + \note The y-position is used as the top of the font. \sa Qt::AlignmentFlag, Qt::TextFlag */ -- cgit v0.12 From ce2a273bab9b9094a1f0f3f60309797e11e59404 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Mon, 27 Sep 2010 11:39:05 +0200 Subject: Doc update for the support of MSVC 2010 64-bit MS has released a hotfix for the support of MSVC 2010 64-bit. It fixes the optimizer that could generate code that crashes. Reviewed-by: Trust-Me Task-number: QTBUG-11445 --- doc/src/platforms/compiler-notes.qdoc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/src/platforms/compiler-notes.qdoc b/doc/src/platforms/compiler-notes.qdoc index 3870e8f..bcf7cb4 100644 --- a/doc/src/platforms/compiler-notes.qdoc +++ b/doc/src/platforms/compiler-notes.qdoc @@ -267,8 +267,9 @@ for more information. There currently is a problem when compiling Qt with Visual Studio 2010 for 64-bit. - Its optimizer causes trouble and crashes for the release builds and it is not supported - in that configuration. See task http://bugreports.qt.nokia.com/browse/QTBUG-11445. + Its optimizer causes trouble and generates code that crashes for the release builds. + To avoid the crashes, You need to apply the hotfix in the following article + http://support.microsoft.com/kb/2280741. \section1 IBM xlC (AIX) -- cgit v0.12 From c9a5ab5fd506663c5a7cd587d1b963c067d334bf Mon Sep 17 00:00:00 2001 From: aavit Date: Fri, 24 Sep 2010 17:51:14 +0200 Subject: Avoid creating copy of an image in memory when storing as png Task-number: QT-3871 Reviewed-by: Kim --- src/gui/image/qpnghandler.cpp | 92 ++++++++++++++-------------- tests/auto/qimagereader/tst_qimagereader.cpp | 43 +++++++++++++ 2 files changed, 88 insertions(+), 47 deletions(-) diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index dc54313..935aba0 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -678,41 +678,19 @@ bool QPNGImageWriter::writeImage(const QImage& image, int off_x, int off_y) return writeImage(image, -1, QString(), off_x, off_y); } -bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image_in, int quality_in, const QString &description, +bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image, int quality_in, const QString &description, int off_x_in, int off_y_in) { #ifdef QT_NO_IMAGE_TEXT Q_UNUSED(description); #endif - QImage image; - switch (image_in.format()) { - case QImage::Format_ARGB32_Premultiplied: - case QImage::Format_ARGB4444_Premultiplied: - case QImage::Format_ARGB8555_Premultiplied: - case QImage::Format_ARGB8565_Premultiplied: - case QImage::Format_ARGB6666_Premultiplied: - image = image_in.convertToFormat(QImage::Format_ARGB32); - break; - case QImage::Format_RGB16: - case QImage::Format_RGB444: - case QImage::Format_RGB555: - case QImage::Format_RGB666: - case QImage::Format_RGB888: - image = image_in.convertToFormat(QImage::Format_RGB32); - break; - default: - image = image_in; - break; - } - QPoint offset = image.offset(); int off_x = off_x_in + offset.x(); int off_y = off_y_in + offset.y(); png_structp png_ptr; png_infop info_ptr; - png_bytep* row_pointers; png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,0,0,0); if (!png_ptr) { @@ -743,13 +721,18 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image_in, png_set_write_fn(png_ptr, (void*)this, qpiw_write_fn, qpiw_flush_fn); + + int color_type = 0; + if (image.colorCount()) + color_type = PNG_COLOR_TYPE_PALETTE; + else if (image.hasAlphaChannel()) + color_type = PNG_COLOR_TYPE_RGB_ALPHA; + else + color_type = PNG_COLOR_TYPE_RGB; + png_set_IHDR(png_ptr, info_ptr, image.width(), image.height(), - image.depth() == 1 ? 1 : 8 /* per channel */, - image.depth() == 32 - ? image.format() == QImage::Format_RGB32 - ? PNG_COLOR_TYPE_RGB - : PNG_COLOR_TYPE_RGB_ALPHA - : PNG_COLOR_TYPE_PALETTE, 0, 0, 0); // also sets #channels + image.depth() == 1 ? 1 : 8, // per channel + color_type, 0, 0, 0); // sets #channels if (gamma != 0.0) { png_set_gAMA(png_ptr, info_ptr, 1.0/gamma); @@ -794,8 +777,9 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image_in, png_set_swap_alpha(png_ptr); } - // Qt==ARGB==Big(ARGB)==Little(BGRA) - if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) { + // Qt==ARGB==Big(ARGB)==Little(BGRA). But RGB888 is RGB regardless + if (QSysInfo::ByteOrder == QSysInfo::LittleEndian + && image.format() != QImage::Format_RGB888) { png_set_bgr(png_ptr); } @@ -820,7 +804,7 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image_in, if (image.depth() != 1) png_set_packing(png_ptr); - if (image.format() == QImage::Format_RGB32) + if (color_type == PNG_COLOR_TYPE_RGB && image.format() != QImage::Format_RGB888) png_set_filler(png_ptr, 0, QSysInfo::ByteOrder == QSysInfo::BigEndian ? PNG_FILLER_BEFORE : PNG_FILLER_AFTER); @@ -841,22 +825,36 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image_in, png_write_chunk(png_ptr, (png_byte*)"gIFg", data, 4); } - png_uint_32 width; - png_uint_32 height; - int bit_depth; - int color_type; - png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, - 0, 0, 0); - - const uchar *data = (static_cast(&image))->bits(); - int bpl = image.bytesPerLine(); - row_pointers = new png_bytep[height]; - uint y; - for (y=0; y("format"); + + QTest::newRow("Format_Mono") << QImage::Format_Mono; + QTest::newRow("Format_MonoLSB") << QImage::Format_MonoLSB; + QTest::newRow("Format_Indexed8") << QImage::Format_Indexed8; + QTest::newRow("Format_RGB32") << QImage::Format_RGB32; + QTest::newRow("Format_ARGB32") << QImage::Format_ARGB32; + QTest::newRow("Format_ARGB32_Premultiplied") << QImage::Format_ARGB32_Premultiplied; + QTest::newRow("Format_RGB16") << QImage::Format_RGB16; + QTest::newRow("Format_ARGB8565_Premultiplied") << QImage::Format_ARGB8565_Premultiplied; + QTest::newRow("Format_RGB666") << QImage::Format_RGB666; + QTest::newRow("Format_ARGB6666_Premultiplied") << QImage::Format_ARGB6666_Premultiplied; + QTest::newRow("Format_RGB555") << QImage::Format_RGB555; + QTest::newRow("Format_ARGB8555_Premultiplied") << QImage::Format_ARGB8555_Premultiplied; + QTest::newRow("Format_RGB888") << QImage::Format_RGB888; + QTest::newRow("Format_RGB444") << QImage::Format_RGB444; + QTest::newRow("Format_ARGB4444_Premultiplied") << QImage::Format_ARGB4444_Premultiplied; +} + +void tst_QImageReader::saveFormat() +{ + QFETCH(QImage::Format, format); + + QImage orig(":/images/kollada.png"); + + QImage converted = orig.convertToFormat(format); + QBuffer buf; + buf.open(QIODevice::WriteOnly); + QVERIFY(converted.save(&buf, "png")); + buf.close(); + QImage stored = QImage::fromData(buf.buffer(), "png"); + + stored = stored.convertToFormat(QImage::Format_ARGB32); + converted = converted.convertToFormat(QImage::Format_ARGB32); + QCOMPARE(stored, converted); +} + + QTEST_MAIN(tst_QImageReader) #include "tst_qimagereader.moc" -- cgit v0.12 From 5ff714badf06f492c3f6f8282b64181cc93faadb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Mon, 27 Sep 2010 12:14:56 +0200 Subject: Don't disable texture_from_pixmap on GLX/X11 by default. We made a mistake of trying to make use of the texture_from_pixmap extension by default when binding textures in Qt. The extension have several limitation and using it produces crashes with certain drivers/graphic card combos, but we can't change this now since it will break existing apps using well behaved drivers. We'll fix this for 4.8 with either a QGL::BindOption or configure flag. Revert "Don't try to use the texture_from_pixmap extension in GL on desktop/X11." This reverts commit 07c5429d5aacab932cd912e66287d66fb952e7c4. --- src/opengl/qgl.cpp | 33 ++++++++++++++++++++++++++------- src/opengl/qgl_p.h | 3 +++ 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index b678790..9e74e04 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -1692,6 +1692,9 @@ void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format) workaround_brokenFBOReadBack = false; workaroundsCached = false; + workaround_brokenTextureFromPixmap = false; + workaround_brokenTextureFromPixmap_init = false; + for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) vertexAttributeArraysEnabledState[i] = false; } @@ -2577,18 +2580,34 @@ QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target, } } -#if defined(Q_WS_X11) && !defined(QT_NO_EGL) - // Only try to use texture_from_pixmap under X11/EGL +#if defined(Q_WS_X11) + // Try to use texture_from_pixmap const QX11Info *xinfo = qt_x11Info(paintDevice); if (pd->classId() == QPixmapData::X11Class && pd->pixelType() == QPixmapData::PixmapType && xinfo && xinfo->screen() == pixmap.x11Info().screen() && target == GL_TEXTURE_2D) { - texture = bindTextureFromNativePixmap(const_cast(&pixmap), key, options); - if (texture) { - texture->options |= QGLContext::MemoryManagedBindOption; - texture->boundPixmap = pd; - boundPixmaps.insert(pd, QPixmap(pixmap)); + if (!workaround_brokenTextureFromPixmap_init) { + workaround_brokenTextureFromPixmap_init = true; + + const QByteArray versionString(reinterpret_cast(glGetString(GL_VERSION))); + const int pos = versionString.indexOf("NVIDIA "); + + if (pos >= 0) { + const QByteArray nvidiaVersionString = versionString.mid(pos + strlen("NVIDIA ")); + + if (nvidiaVersionString.startsWith("195") || nvidiaVersionString.startsWith("256")) + workaround_brokenTextureFromPixmap = true; + } + } + + if (!workaround_brokenTextureFromPixmap) { + texture = bindTextureFromNativePixmap(const_cast(&pixmap), key, options); + if (texture) { + texture->options |= QGLContext::MemoryManagedBindOption; + texture->boundPixmap = pd; + boundPixmaps.insert(pd, QPixmap(pixmap)); + } } } #endif diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 6323ce2..623eeaf 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -401,6 +401,9 @@ public: uint workaround_brokenFBOReadBack : 1; uint workaroundsCached : 1; + uint workaround_brokenTextureFromPixmap : 1; + uint workaround_brokenTextureFromPixmap_init : 1; + QPaintDevice *paintDevice; QColor transpColor; QGLContext *q_ptr; -- cgit v0.12 From d60dc7cba21794866c9382f83080fab1a129eb08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Mon, 27 Sep 2010 13:02:47 +0200 Subject: Fixed performance regression in curve stroking. Change c46688b8a88da made us use m_curve_threshold for both QBezier::shifted and QBezier::toPolygon, and adjusted the threshold dynamically based on the painter scale. Since the threshold in shifted was already relative to the pen width, it is independent from the painter scale. Instead, we need to set a separate threshold for dashing. Also, in several places we were calling setCurveThresholdForTransform with the painter matrix even though we were transforming the points into device coordinate space before stroking. Task-number: QTBUG-13894 Reviewed-by: Gunnar Sletta --- src/gui/painting/qpaintengineex.cpp | 2 +- src/gui/painting/qstroker.cpp | 9 +++++---- src/gui/painting/qstroker_p.h | 3 ++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index 1e857e4..c1e3d66 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -517,7 +517,7 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) QPainterPath painterPath = state()->matrix.map(path.convertToPainterPath()); d->activeStroker->strokePath(painterPath, d->strokeHandler, QTransform()); } else { - d->activeStroker->setCurveThresholdFromTransform(state()->matrix); + d->activeStroker->setCurveThresholdFromTransform(QTransform()); d->activeStroker->begin(d->strokeHandler); if (types) { while (points < lastPoint) { diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp index 9cff339..9decf41 100644 --- a/src/gui/painting/qstroker.cpp +++ b/src/gui/painting/qstroker.cpp @@ -190,6 +190,7 @@ static inline qreal adapted_angle_on_x(const QLineF &line) QStrokerOps::QStrokerOps() : m_elements(0) , m_curveThreshold(qt_real_to_fixed(0.25)) + , m_dashThreshold(qt_real_to_fixed(0.25)) , m_customData(0) , m_moveTo(0) , m_lineTo(0) @@ -243,7 +244,7 @@ void QStrokerOps::strokePath(const QPainterPath &path, void *customData, const Q if (path.isEmpty()) return; - setCurveThresholdFromTransform(matrix); + setCurveThresholdFromTransform(QTransform()); begin(customData); int count = path.elementCount(); if (matrix.isIdentity()) { @@ -315,7 +316,7 @@ void QStrokerOps::strokePolygon(const QPointF *points, int pointCount, bool impl if (!pointCount) return; - setCurveThresholdFromTransform(matrix); + setCurveThresholdFromTransform(QTransform()); begin(data); if (matrix.isIdentity()) { moveTo(qt_real_to_fixed(points[0].x()), qt_real_to_fixed(points[0].y())); @@ -356,7 +357,7 @@ void QStrokerOps::strokeEllipse(const QRectF &rect, void *data, const QTransform } } - setCurveThresholdFromTransform(matrix); + setCurveThresholdFromTransform(QTransform()); begin(data); moveTo(qt_real_to_fixed(start.x()), qt_real_to_fixed(start.y())); for (int i=0; i<12; i+=3) { @@ -1142,7 +1143,7 @@ void QDashStroker::processCurrentSubpath() QPainterPath dashPath; - QSubpathFlatIterator it(&m_elements, m_curveThreshold); + QSubpathFlatIterator it(&m_elements, m_dashThreshold); qfixed2d prev = it.next(); bool clipping = !m_clip_rect.isEmpty(); diff --git a/src/gui/painting/qstroker_p.h b/src/gui/painting/qstroker_p.h index d646135..5607a8e 100644 --- a/src/gui/painting/qstroker_p.h +++ b/src/gui/painting/qstroker_p.h @@ -168,7 +168,7 @@ public: { qreal scale; qt_scaleForTransform(transform, &scale); - setCurveThreshold(scale == 0 ? qreal(0.5) : (qreal(0.5) / scale)); + m_dashThreshold = scale == 0 ? qreal(0.5) : (qreal(0.5) / scale); } void setCurveThreshold(qfixed threshold) { m_curveThreshold = threshold; } @@ -184,6 +184,7 @@ protected: QRectF m_clip_rect; qfixed m_curveThreshold; + qfixed m_dashThreshold; void *m_customData; qStrokerMoveToHook m_moveTo; -- cgit v0.12 From 165dbe2615bf4b908e6bc84bb8963ca72fe5f866 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Tue, 28 Sep 2010 10:44:07 +0200 Subject: Fixed crash when using Qt::WA_DeleteOnClose on a QPrintDialog on Mac. The Qt::WA_DeleteOnClose bug was fixed some time ago, while this workaround was "forgotten" in the QPrintDialog code. It actually causes a crash and is no longer necessary. Task-number: QTBUG-11430 Reviewed-by: Prasanth --- src/gui/dialogs/qprintdialog_mac.mm | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/gui/dialogs/qprintdialog_mac.mm b/src/gui/dialogs/qprintdialog_mac.mm index 84a72db..82e4db5 100644 --- a/src/gui/dialogs/qprintdialog_mac.mm +++ b/src/gui/dialogs/qprintdialog_mac.mm @@ -140,11 +140,6 @@ QT_USE_NAMESPACE QPrintDialogPrivate *d = static_cast(contextInfo); QPrintDialog *dialog = d->printDialog(); - // temporary hack to work around bug in deleteLater() in Qt/Mac Cocoa -#if 1 - bool deleteDialog = dialog->testAttribute(Qt::WA_DeleteOnClose); - dialog->setAttribute(Qt::WA_DeleteOnClose, false); -#endif if (returnCode == NSOKButton) { UInt32 frompage, topage; @@ -192,10 +187,6 @@ QT_USE_NAMESPACE } dialog->done((returnCode == NSOKButton) ? QDialog::Accepted : QDialog::Rejected); -#if 1 - if (deleteDialog) - delete dialog; -#endif } @end -- cgit v0.12 From 52c45eba97a929b6ea832512bf5d5b121e5fd453 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Tue, 28 Sep 2010 13:34:14 +0200 Subject: Fixed regression in clipping.qps autotest on 64-bit. TPos needs to be 32-bit, not 64-bit. QT_FT_Pos being 64-bit caused sizeof(TWorker) + sizeof(TCell) in qgrayraster.c to exceed 4096, which is the MINIMUM_POOL_SIZE, leading to rendering errors in certain cases. Reviewed-by: Yoann Lopes --- src/gui/painting/qrasterdefs_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qrasterdefs_p.h b/src/gui/painting/qrasterdefs_p.h index 19a0b16..4d803c7 100644 --- a/src/gui/painting/qrasterdefs_p.h +++ b/src/gui/painting/qrasterdefs_p.h @@ -100,7 +100,7 @@ QT_FT_BEGIN_HEADER /* distances in integer font units, or 16,16, or 26.6 fixed float */ /* pixel coordinates. */ /* */ - typedef signed long QT_FT_Pos; + typedef signed int QT_FT_Pos; /*************************************************************************/ -- cgit v0.12 From 59fc149ae0d43b3b5bb9e5695531d6f576598e2d Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 28 Sep 2010 15:07:38 +0200 Subject: tst_qstatemachine.cpp: fix compilation with Sun Studio Task-number: QTBUG-12995 --- tests/auto/qstatemachine/tst_qstatemachine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp index 2bf76e7..f6aee88 100644 --- a/tests/auto/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp @@ -1112,7 +1112,7 @@ void tst_QStateMachine::machineWithParent() QObject object; QStateMachine *machine = new QStateMachine(&object); QCOMPARE(machine->parent(), &object); - QCOMPARE(machine->parentState(), (QObject*)0); + QCOMPARE(machine->parentState(), static_cast(0)); } void tst_QStateMachine::addAndRemoveState() -- cgit v0.12 From e355a8073881cb9e5cce87b0e498d7f22b7d83ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Tue, 28 Sep 2010 18:16:11 +0200 Subject: Work around an ATI driver problem with mutli-sampled pbuffers. Explicitly check if the pbuffer context is multi-sampled and turn off the render_texture extension if it is. Task-number: QTBUG-14027 Reviewed-by: Kim --- src/opengl/qglpixelbuffer_win.cpp | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/opengl/qglpixelbuffer_win.cpp b/src/opengl/qglpixelbuffer_win.cpp index b55f383..c61d9bf 100644 --- a/src/opengl/qglpixelbuffer_win.cpp +++ b/src/opengl/qglpixelbuffer_win.cpp @@ -172,6 +172,10 @@ typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, con #define WGL_SAMPLES_ARB 0x2042 #endif +#ifndef GL_SAMPLES_ARB +#define GL_SAMPLES_ARB 0x80A9 +#endif + QGLFormat pfiToQGLFormat(HDC hdc, int pfi); static void qt_format_to_attrib_list(bool has_render_texture, const QGLFormat &f, int attribs[]) @@ -242,8 +246,7 @@ static void qt_format_to_attrib_list(bool has_render_texture, const QGLFormat &f bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidget *shareWidget) { - QGLWidget dmy; - dmy.makeCurrent(); // needed for wglGetProcAddress() to succeed + QGLTemporaryContext tempContext; PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB = (PFNWGLCREATEPBUFFERARBPROC) wglGetProcAddress("wglCreatePbufferARB"); @@ -257,13 +260,12 @@ bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidge if (!wglCreatePbufferARB) // assumes that if one can be resolved, all of them can return false; - dc = GetDC(dmy.winId()); + dc = wglGetCurrentDC(); Q_ASSERT(dc); + has_render_texture = false; // sample buffers doesn't work in conjunction with the render_texture extension - if (f.sampleBuffers()) { - has_render_texture = false; - } else { + if (!f.sampleBuffers()) { PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC) wglGetProcAddress("wglGetExtensionsStringARB"); @@ -292,7 +294,6 @@ bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidge if (num_formats == 0) { qWarning("QGLPixelBuffer: Unable to find a pixel format with pbuffer - giving up."); - ReleaseDC(dmy.winId(), dc); return false; } format = pfiToQGLFormat(dc, pixel_format); @@ -305,26 +306,32 @@ bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidge pbuf = wglCreatePbufferARB(dc, pixel_format, size.width(), size.height(), has_render_texture ? pb_attribs : 0); - if(!pbuf) { + if (!pbuf) { // try again without the render_texture extension pbuf = wglCreatePbufferARB(dc, pixel_format, size.width(), size.height(), 0); has_render_texture = false; if (!pbuf) { qWarning("QGLPixelBuffer: Unable to create pbuffer [w=%d, h=%d] - giving up.", size.width(), size.height()); - ReleaseDC(dmy.winId(), dc); return false; } } - ReleaseDC(dmy.winId(), dc); dc = wglGetPbufferDCARB(pbuf); ctx = wglCreateContext(dc); - if (!dc || !ctx) { qWarning("QGLPixelBuffer: Unable to create pbuffer context - giving up."); return false; } + // Explicitly disable the render_texture extension if we have a + // multi-sampled pbuffer context. This seems to be a problem only with + // ATI cards if multi-sampling is forced globally in the driver. + wglMakeCurrent(dc, ctx); + GLint samples = 0; + glGetIntegerv(GL_SAMPLES_ARB, &samples); + if (has_render_texture && samples != 0) + has_render_texture = false; + HGLRC share_ctx = shareWidget ? shareWidget->d_func()->glcx->d_func()->rc : 0; if (share_ctx && !wglShareLists(share_ctx, ctx)) qWarning("QGLPixelBuffer: Unable to share display lists - with share widget."); -- cgit v0.12 From 6368ca1c36488d1297c768a5fae52f65bb5b91be Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Mon, 27 Sep 2010 13:34:59 +0200 Subject: Fixed potential crash when loading corrupt GIFs. Task-number: QTBUG-13774 Reviewed-by: aavit --- src/gui/image/qgifhandler.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/gui/image/qgifhandler.cpp b/src/gui/image/qgifhandler.cpp index 124d27b..a050baf 100644 --- a/src/gui/image/qgifhandler.cpp +++ b/src/gui/image/qgifhandler.cpp @@ -505,17 +505,26 @@ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length, code=oldcode; } while (code>=clear_code+2) { + if (code >= max_code) { + state = Error; + return -1; + } *sp++=table[1][code]; if (code==table[0][code]) { state=Error; - break; + return -1; } if (sp-stack>=(1<<(max_lzw_bits))*2) { state=Error; - break; + return -1; } code=table[0][code]; } + if (code < 0) { + state = Error; + return -1; + } + *sp++=firstcode=table[1][code]; code=max_code; if (code<(1< Date: Tue, 28 Sep 2010 15:25:37 +0200 Subject: Fixed antialiased rasterization bug in raster engine. When rasterization in the gray raster fails due to out of memory there might already have been a number of spans flushed. To avoid flushing these spans multiple times and thus getting overdraw artifacts we need to keep track of how many spans to skip when we redo the rasterization. This fixes the rendering error in arthur test paths_aa.qps Reviewed-by: Yoann Lopes --- src/gui/painting/qgrayraster.c | 38 ++++++++++++++++++++++++++------ src/gui/painting/qpaintengine_raster.cpp | 9 ++++++++ src/gui/painting/qrasterdefs_p.h | 1 + 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/gui/painting/qgrayraster.c b/src/gui/painting/qgrayraster.c index 19cef49..9356037 100644 --- a/src/gui/painting/qgrayraster.c +++ b/src/gui/painting/qgrayraster.c @@ -317,6 +317,7 @@ PCell* ycells; int ycount; + int skip_spans; } TWorker, *PWorker; @@ -331,7 +332,12 @@ } TRaster, *PRaster; - + int q_gray_rendered_spans(TRaster *raster) + { + if ( raster && raster->worker ) + return raster->worker->skip_spans > 0 ? 0 : -raster->worker->skip_spans; + return 0; + } /*************************************************************************/ /* */ @@ -1179,6 +1185,7 @@ { QT_FT_Span* span; int coverage; + int skip; /* compute the coverage line's coverage, depending on the */ @@ -1229,9 +1236,16 @@ if ( ras.num_gray_spans >= QT_FT_MAX_GRAY_SPANS ) { - if ( ras.render_span ) - ras.render_span( ras.num_gray_spans, ras.gray_spans, + if ( ras.render_span && ras.num_gray_spans > ras.skip_spans ) + { + skip = ras.skip_spans > 0 ? ras.skip_spans : 0; + ras.render_span( ras.num_gray_spans - skip, + ras.gray_spans + skip, ras.render_span_data ); + } + + ras.skip_spans -= ras.num_gray_spans; + /* ras.render_span( span->y, ras.gray_spans, count ); */ #ifdef DEBUG_GRAYS @@ -1601,7 +1615,8 @@ TBand* volatile band; int volatile n, num_bands; TPos volatile min, max, max_y; - QT_FT_BBox* clip; + QT_FT_BBox* clip; + int skip; ras.num_gray_spans = 0; @@ -1742,9 +1757,15 @@ } } - if ( ras.render_span && ras.num_gray_spans > 0 ) - ras.render_span( ras.num_gray_spans, - ras.gray_spans, ras.render_span_data ); + if ( ras.render_span && ras.num_gray_spans > ras.skip_spans ) + { + skip = ras.skip_spans > 0 ? ras.skip_spans : 0; + ras.render_span( ras.num_gray_spans - skip, + ras.gray_spans + skip, + ras.render_span_data ); + } + + ras.skip_spans -= ras.num_gray_spans; if ( ras.band_shoot > 8 && ras.band_size > 16 ) ras.band_size = ras.band_size / 2; @@ -1765,6 +1786,9 @@ if ( !raster || !raster->buffer || !raster->buffer_size ) return ErrRaster_Invalid_Argument; + if ( raster->worker ) + raster->worker->skip_spans = params->skip_spans; + // If raster object and raster buffer are allocated, but // raster size isn't of the minimum size, indicate out of // memory. diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 09a87aa..36e1082 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -4148,6 +4148,10 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, rasterize(outline, callback, (void *)spanData, rasterBuffer); } +extern "C" { + int q_gray_rendered_spans(QT_FT_Raster raster); +} + void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, ProcessSpans callback, void *userData, QRasterBuffer *) @@ -4212,10 +4216,13 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, bool done = false; int error; + int rendered_spans = 0; + while (!done) { rasterParams.flags |= (QT_FT_RASTER_FLAG_AA | QT_FT_RASTER_FLAG_DIRECT); rasterParams.gray_spans = callback; + rasterParams.skip_spans = rendered_spans; error = qt_ft_grays_raster.raster_render(*grayRaster.data(), &rasterParams); // Out of memory, reallocate some more and try again... @@ -4244,6 +4251,8 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, #endif Q_CHECK_PTR(rasterPoolBase); // note: we just freed the old rasterPoolBase. I hope it's not fatal. + rendered_spans += q_gray_rendered_spans(*grayRaster.data()); + qt_ft_grays_raster.raster_done(*grayRaster.data()); qt_ft_grays_raster.raster_new(grayRaster.data()); qt_ft_grays_raster.raster_reset(*grayRaster.data(), rasterPoolBase, rasterPoolSize); diff --git a/src/gui/painting/qrasterdefs_p.h b/src/gui/painting/qrasterdefs_p.h index 4d803c7..f6339ed 100644 --- a/src/gui/painting/qrasterdefs_p.h +++ b/src/gui/painting/qrasterdefs_p.h @@ -1088,6 +1088,7 @@ QT_FT_BEGIN_HEADER QT_FT_Raster_BitSet_Func bit_set; /* doesn't work! */ void* user; QT_FT_BBox clip_box; + int skip_spans; } QT_FT_Raster_Params; -- cgit v0.12 From 33f525e636ef8fa64a15d3e66c56adaea0075bda Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 29 Sep 2010 12:56:38 +0200 Subject: Fix double painting when adding an item into a linear layout the problem was that the item is first painted at its default position, then moved by the layout and finally repainted. We now made sure the item is laid out before the first paint event occurs. Task-number: QTBUG-13865 Reviewed-by: bnilsen --- src/gui/graphicsview/qgraphicslinearlayout.cpp | 8 +++-- tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp | 40 ++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/gui/graphicsview/qgraphicslinearlayout.cpp b/src/gui/graphicsview/qgraphicslinearlayout.cpp index 1588364..7e8d19f 100644 --- a/src/gui/graphicsview/qgraphicslinearlayout.cpp +++ b/src/gui/graphicsview/qgraphicslinearlayout.cpp @@ -275,13 +275,17 @@ void QGraphicsLinearLayout::insertItem(int index, QGraphicsLayoutItem *item) qWarning("QGraphicsLinearLayout::insertItem: cannot insert itself"); return; } + Q_ASSERT(item); + + //the order of the following instructions is very important because + //invalidating the layout before adding the child item will make the layout happen + //before we try to paint the item + invalidate(); d->addChildLayoutItem(item); - Q_ASSERT(item); d->fixIndex(&index); d->engine.insertRow(index, d->orientation); new QGridLayoutItem(&d->engine, item, d->gridRow(index), d->gridColumn(index), 1, 1, 0, index); - invalidate(); } /*! diff --git a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp index ddc4f73..7f24ddc 100644 --- a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp +++ b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp @@ -184,6 +184,7 @@ private slots: void task250119_shortcutContext(); void QT_BUG_6544_tabFocusFirstUnsetWhenRemovingItems(); void QT_BUG_12056_tabFocusFirstUnsetWhenRemovingItems(); + void QT_BUG_13865_doublePaintWhenAddingASubItem(); }; @@ -3321,6 +3322,45 @@ void tst_QGraphicsWidget::QT_BUG_12056_tabFocusFirstUnsetWhenRemovingItems() //This should not crash } + +struct GreenWidget : public QGraphicsWidget +{ + GreenWidget() : count(0) + { + } + + void paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * ) + { + count++; + painter->setPen(Qt::green); + painter->drawRect(option->rect.adjusted(0,0,-1,-1)); + } + + int count; +}; + +void tst_QGraphicsWidget::QT_BUG_13865_doublePaintWhenAddingASubItem() +{ + QGraphicsScene scene; + QGraphicsView view(&scene); + QGraphicsWidget *widget = new QGraphicsWidget; + widget->resize(100, 100); + scene.addItem(widget); + QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(widget); + + view.show(); + QTest::qWaitForWindowShown(&view); + + + GreenWidget *sub = new GreenWidget; + layout->addItem(sub); + + QTest::qWait(100); + QCOMPARE(sub->count, 1); //it should only be painted once + +} + + QTEST_MAIN(tst_QGraphicsWidget) #include "tst_qgraphicswidget.moc" -- cgit v0.12 From 02aecce59cb76ceb88f63520355381c3b5c5a513 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 29 Sep 2010 14:08:21 +0200 Subject: QTextCodec: Fix valgrind warning when using QTextCodec in destructions functions Reviewed-by: Denis --- src/corelib/codecs/qtextcodec.cpp | 52 +++++++++++++++++--------------- tests/auto/qtextcodec/tst_qtextcodec.cpp | 9 ++++++ 2 files changed, 37 insertions(+), 24 deletions(-) diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp index c9fbec8..83e1f0c 100644 --- a/src/corelib/codecs/qtextcodec.cpp +++ b/src/corelib/codecs/qtextcodec.cpp @@ -110,6 +110,10 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, (QTextCodecFactoryInterface_iid, QLatin1String("/codecs"))) #endif +//Cache for QTextCodec::codecForName and codecForMib. +typedef QHash QTextCodecCache; +Q_GLOBAL_STATIC(QTextCodecCache, qTextCodecCache) + static char qtolower(register char c) { if (c >= 'A' && c <= 'Z') return c + 0x20; return c; } @@ -181,7 +185,6 @@ static QTextCodec *createForMib(int mib) } static QList *all = 0; -static int clearCaches = 0; // flags specifying if caches should be invalided: 0x1 codecForName, 0x2 codecForMib #ifdef Q_DEBUG_TEXTCODEC static bool destroying_is_ok = false; #endif @@ -1007,7 +1010,9 @@ QTextCodec::~QTextCodec() QMutexLocker locker(textCodecsMutex()); #endif all->removeAll(this); - clearCaches = 0x1 | 0x2; + QTextCodecCache *cache = qTextCodecCache(); + if (cache) + cache->clear(); } } @@ -1037,32 +1042,33 @@ QTextCodec *QTextCodec::codecForName(const QByteArray &name) if (!validCodecs()) return 0; - static QHash cache; - if (clearCaches & 0x1) { - cache.clear(); - clearCaches &= ~0x1; + QTextCodecCache *cache = qTextCodecCache(); + QTextCodec *codec; + if (cache) { + codec = cache->value(name); + if (codec) + return codec; } - QTextCodec *codec = cache.value(name); - if (codec) - return codec; for (int i = 0; i < all->size(); ++i) { QTextCodec *cursor = all->at(i); if (nameMatch(cursor->name(), name)) { - cache.insert(name, cursor); + if (cache) + cache->insert(name, cursor); return cursor; } QList aliases = cursor->aliases(); for (int y = 0; y < aliases.size(); ++y) if (nameMatch(aliases.at(y), name)) { - cache.insert(name, cursor); + if (cache) + cache->insert(name, cursor); return cursor; } } codec = createForName(name); - if (codec) - cache.insert(name, codec); + if (codec && cache) + cache->insert(name, codec); return codec; } @@ -1081,20 +1087,18 @@ QTextCodec* QTextCodec::codecForMib(int mib) if (!validCodecs()) return 0; - static QHash cache; - if (clearCaches & 0x2) { - cache.clear(); - clearCaches &= ~0x2; - } - QTextCodec *codec = cache.value(mib); - if (codec) - return codec; + QByteArray key = "MIB: " + QByteArray::number(mib); + QTextCodecCache *cache = qTextCodecCache(); + QTextCodec *codec; + if (cache) + codec = cache->value(key); QList::ConstIterator i; for (int i = 0; i < all->size(); ++i) { QTextCodec *cursor = all->at(i); if (cursor->mibEnum() == mib) { - cache.insert(mib, cursor); + if (cache) + cache->insert(key, cursor); return cursor; } } @@ -1106,8 +1110,8 @@ QTextCodec* QTextCodec::codecForMib(int mib) if (!codec && mib == 1000) return codecForMib(1015); - if (codec) - cache.insert(mib, codec); + if (codec && cache) + cache->insert(key, codec); return codec; } diff --git a/tests/auto/qtextcodec/tst_qtextcodec.cpp b/tests/auto/qtextcodec/tst_qtextcodec.cpp index cc41591..3d8f1a3 100644 --- a/tests/auto/qtextcodec/tst_qtextcodec.cpp +++ b/tests/auto/qtextcodec/tst_qtextcodec.cpp @@ -2236,6 +2236,15 @@ void tst_QTextCodec::moreToFromUnicode() QCOMPARE(testData, cStr); } +struct DontCrashAtExit { + ~DontCrashAtExit() { + QTextCodec *c = QTextCodec::codecForName("utf8"); + if (c) + c->toUnicode("azerty"); + + } +} dontCrashAtExit; + QTEST_MAIN(tst_QTextCodec) #include "tst_qtextcodec.moc" -- cgit v0.12 From c1f9978c9d61bcbdb2f280185a3abdea13d7f532 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Thu, 30 Sep 2010 11:38:14 +0200 Subject: Fixed a layout issue where you could get NaN as dimensions The problem is that with empty layouts we could sometimes divide by 0. Note: This doesn't fix the whole task... Task-number: QTBUG-13547 Reviewed-by: ogoffart --- src/gui/graphicsview/qgridlayoutengine.cpp | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/gui/graphicsview/qgridlayoutengine.cpp b/src/gui/graphicsview/qgridlayoutengine.cpp index f3b2026..1e3addc 100644 --- a/src/gui/graphicsview/qgridlayoutengine.cpp +++ b/src/gui/graphicsview/qgridlayoutengine.cpp @@ -306,20 +306,19 @@ void QGridLayoutRowData::calculateGeometries(int start, int end, qreal targetSiz ultimatePreferredSize = ultimatePreferredSize * 3 / 2; ultimateSumPreferredSizes = ultimateSumPreferredSizes * 3 / 2; - qreal ultimateFactor = (stretch * ultimateSumPreferredSizes - / sumStretches) - - (box.q_preferredSize); - qreal transitionalFactor = sumCurrentAvailable - * (ultimatePreferredSize - box.q_preferredSize) - / (ultimateSumPreferredSizes - - sumPreferredSizes); - - qreal alpha = qMin(sumCurrentAvailable, - ultimateSumPreferredSizes - sumPreferredSizes); qreal beta = ultimateSumPreferredSizes - sumPreferredSizes; + if (!beta) { + factors[i] = 1; + } else { + qreal alpha = qMin(sumCurrentAvailable, beta); + qreal ultimateFactor = (stretch * ultimateSumPreferredSizes / sumStretches) + - (box.q_preferredSize); + qreal transitionalFactor = sumCurrentAvailable * (ultimatePreferredSize - box.q_preferredSize) / beta; + + factors[i] = ((alpha * ultimateFactor) + + ((beta - alpha) * transitionalFactor)) / beta; + } - factors[i] = ((alpha * ultimateFactor) - + ((beta - alpha) * transitionalFactor)) / beta; } sumFactors += factors[i]; if (desired < sumCurrentAvailable) -- cgit v0.12 From 5bd6f7eb5c7d87c08539b6c2df416990cc417ec7 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Thu, 30 Sep 2010 11:40:39 +0200 Subject: Revert "Fix (implement!) hfw/wfh in QGridLayoutEngine" This reverts commit 62b5ef3cc1306e46a4042b14867f2f92d9a110f3. The implementation of hfw from this patch is unfortunately not robust enough. It doesn't manage correctly the constraints on the layouts and the cell spans. It caused bad behaviour or regressions seen in tasks: QTBUG-13547, QTBUG-13067, QTBUG-13549, and more Reviewed-By: ogoffart --- src/gui/graphicsview/qgraphicslayoutitem.cpp | 51 +-- src/gui/graphicsview/qgraphicslayoutitem_p.h | 6 - src/gui/graphicsview/qgridlayoutengine.cpp | 251 +------------- src/gui/graphicsview/qgridlayoutengine_p.h | 23 +- .../tst_qgraphicsgridlayout.cpp | 364 +-------------------- 5 files changed, 17 insertions(+), 678 deletions(-) diff --git a/src/gui/graphicsview/qgraphicslayoutitem.cpp b/src/gui/graphicsview/qgraphicslayoutitem.cpp index 634f68c..ad4b2b5 100644 --- a/src/gui/graphicsview/qgraphicslayoutitem.cpp +++ b/src/gui/graphicsview/qgraphicslayoutitem.cpp @@ -48,7 +48,6 @@ #include "qgraphicslayoutitem.h" #include "qgraphicslayoutitem_p.h" #include "qwidget.h" -#include "qgraphicswidget.h" #include @@ -140,11 +139,9 @@ QSizeF *QGraphicsLayoutItemPrivate::effectiveSizeHints(const QSizeF &constraint) if (!sizeHintCacheDirty && cachedConstraint == constraint) return cachedSizeHints; - const bool hasConstraint = constraint.width() >= 0 || constraint.height() >= 0; - for (int i = 0; i < Qt::NSizeHints; ++i) { cachedSizeHints[i] = constraint; - if (userSizeHints && !hasConstraint) + if (userSizeHints) combineSize(cachedSizeHints[i], userSizeHints[i]); } @@ -262,52 +259,6 @@ void QGraphicsLayoutItemPrivate::setSizeComponent( q->updateGeometry(); } - -bool QGraphicsLayoutItemPrivate::hasHeightForWidth() const -{ - Q_Q(const QGraphicsLayoutItem); - if (isLayout) { - const QGraphicsLayout *l = static_cast(q); - for (int i = l->count() - 1; i >= 0; --i) { - if (QGraphicsLayoutItemPrivate::get(l->itemAt(i))->hasHeightForWidth()) - return true; - } - } else if (QGraphicsItem *item = q->graphicsItem()) { - if (item->isWidget()) { - QGraphicsWidget *w = static_cast(item); - if (w->layout()) { - return QGraphicsLayoutItemPrivate::get(w->layout())->hasHeightForWidth(); - } - } - } - return q->sizePolicy().hasHeightForWidth(); -} - -bool QGraphicsLayoutItemPrivate::hasWidthForHeight() const -{ - // enable this code when we add QSizePolicy::hasWidthForHeight() (For 4.8) -#if 1 - return false; -#else - Q_Q(const QGraphicsLayoutItem); - if (isLayout) { - const QGraphicsLayout *l = static_cast(q); - for (int i = l->count() - 1; i >= 0; --i) { - if (QGraphicsLayoutItemPrivate::get(l->itemAt(i))->hasWidthForHeight()) - return true; - } - } else if (QGraphicsItem *item = q->graphicsItem()) { - if (item->isWidget()) { - QGraphicsWidget *w = static_cast(item); - if (w->layout()) { - return QGraphicsLayoutItemPrivate::get(w->layout())->hasWidthForHeight(); - } - } - } - return q->sizePolicy().hasWidthForHeight(); -#endif -} - /*! \class QGraphicsLayoutItem \brief The QGraphicsLayoutItem class can be inherited to allow your custom diff --git a/src/gui/graphicsview/qgraphicslayoutitem_p.h b/src/gui/graphicsview/qgraphicslayoutitem_p.h index b752e03..15cc7a5 100644 --- a/src/gui/graphicsview/qgraphicslayoutitem_p.h +++ b/src/gui/graphicsview/qgraphicslayoutitem_p.h @@ -65,9 +65,6 @@ class Q_AUTOTEST_EXPORT QGraphicsLayoutItemPrivate public: virtual ~QGraphicsLayoutItemPrivate(); QGraphicsLayoutItemPrivate(QGraphicsLayoutItem *parent, bool isLayout); - static QGraphicsLayoutItemPrivate *get(QGraphicsLayoutItem *q) { return q->d_func();} - static const QGraphicsLayoutItemPrivate *get(const QGraphicsLayoutItem *q) { return q->d_func();} - void init(); QSizeF *effectiveSizeHints(const QSizeF &constraint) const; QGraphicsItem *parentItem() const; @@ -76,9 +73,6 @@ public: enum SizeComponent { Width, Height }; void setSizeComponent(Qt::SizeHint which, SizeComponent component, qreal value); - bool hasHeightForWidth() const; - bool hasWidthForHeight() const; - QSizePolicy sizePolicy; QGraphicsLayoutItem *parent; diff --git a/src/gui/graphicsview/qgridlayoutengine.cpp b/src/gui/graphicsview/qgridlayoutengine.cpp index 1e3addc..ae5bf90 100644 --- a/src/gui/graphicsview/qgridlayoutengine.cpp +++ b/src/gui/graphicsview/qgridlayoutengine.cpp @@ -545,24 +545,6 @@ QSizePolicy::Policy QGridLayoutItem::sizePolicy(Qt::Orientation orientation) con : sizePolicy.verticalPolicy(); } -/* - returns true if the size policy returns true for either hasHeightForWidth() - or hasWidthForHeight() - */ -bool QGridLayoutItem::hasDynamicConstraint() const -{ - return QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasHeightForWidth() - || QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasWidthForHeight(); -} - -Qt::Orientation QGridLayoutItem::dynamicConstraintOrientation() const -{ - if (QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasHeightForWidth()) - return Qt::Vertical; - else //if (QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasWidthForHeight()) - return Qt::Horizontal; -} - QSizePolicy::ControlTypes QGridLayoutItem::controlTypes(LayoutSide /* side */) const { return q_layoutItem->sizePolicy().controlType(); @@ -631,14 +613,7 @@ QRectF QGridLayoutItem::geometryWithin(qreal x, qreal y, qreal width, qreal heig qreal cellWidth = width; qreal cellHeight = height; - QSize constraint; - if (hasDynamicConstraint()) { - if (dynamicConstraintOrientation() == Qt::Vertical) - constraint.setWidth(cellWidth); - else - constraint.setHeight(cellHeight); - } - QSizeF size = effectiveMaxSize(constraint).boundedTo(QSizeF(cellWidth, cellHeight)); + QSizeF size = effectiveMaxSize().boundedTo(QSizeF(cellWidth, cellHeight)); width = size.width(); height = size.height(); @@ -700,13 +675,13 @@ void QGridLayoutItem::insertOrRemoveRows(int row, int delta, Qt::Orientation ori Note that effectiveSizeHint does not take sizePolicy into consideration, (since it only evaluates the hints, as the name implies) */ -QSizeF QGridLayoutItem::effectiveMaxSize(const QSizeF &constraint) const +QSizeF QGridLayoutItem::effectiveMaxSize() const { - QSizeF size = constraint; + QSizeF size; bool vGrow = (sizePolicy(Qt::Vertical) & QSizePolicy::GrowFlag) == QSizePolicy::GrowFlag; bool hGrow = (sizePolicy(Qt::Horizontal) & QSizePolicy::GrowFlag) == QSizePolicy::GrowFlag; if (!vGrow || !hGrow) { - QSizeF pref = layoutItem()->effectiveSizeHint(Qt::PreferredSize, constraint); + QSizeF pref = layoutItem()->effectiveSizeHint(Qt::PreferredSize); if (!vGrow) size.setHeight(pref.height()); if (!hGrow) @@ -714,7 +689,7 @@ QSizeF QGridLayoutItem::effectiveMaxSize(const QSizeF &constraint) const } if (!size.isValid()) { - QSizeF maxSize = layoutItem()->effectiveSizeHint(Qt::MaximumSize, constraint); + QSizeF maxSize = layoutItem()->effectiveSizeHint(Qt::MaximumSize); if (size.width() == -1) size.setWidth(maxSize.width()); if (size.height() == -1) @@ -1035,7 +1010,6 @@ void QGridLayoutEngine::invalidate() q_cachedEffectiveLastRows[Ver] = -1; q_cachedDataForStyleInfo.invalidate(); q_cachedSize = QSizeF(); - q_cachedConstraintOrientation = UnknownConstraint; } static void visualRect(QRectF *geom, Qt::LayoutDirection dir, const QRectF &contentsRect) @@ -1100,13 +1074,10 @@ QRectF QGridLayoutEngine::cellRect(const QLayoutStyleInfo &styleInfo, } QSizeF QGridLayoutEngine::sizeHint(const QLayoutStyleInfo &styleInfo, Qt::SizeHint which, - const QSizeF &constraint) const + const QSizeF & /* constraint */) const { ensureColumnAndRowData(styleInfo); - if (hasDynamicConstraint()) - return dynamicallyConstrainedSizeHint(which, constraint); - switch (which) { case Qt::MinimumSize: return QSizeF(q_totalBoxes[Hor].q_minimumSize, q_totalBoxes[Ver].q_minimumSize); @@ -1404,11 +1375,7 @@ void QGridLayoutEngine::fillRowData(QGridLayoutRowData *rowData, const QLayoutSt box = &multiCell.q_box; multiCell.q_stretch = itemStretch; } - // Items with constraints are not included in the orientation that - // they are constrained (since it depends on the hfw/constraint function). - // They must be combined at a later stage. - if (!item->hasDynamicConstraint() || orientation != item->dynamicConstraintOrientation()) - box->combine(item->box(orientation)); + box->combine(item->box(orientation)); if (effectiveRowSpan == 1) { QSizePolicy::ControlTypes controls = item->controlTypes(top); @@ -1565,138 +1532,6 @@ void QGridLayoutEngine::ensureColumnAndRowData(const QLayoutStyleInfo &styleInfo q_cachedDataForStyleInfo = styleInfo; } -QSizeF QGridLayoutEngine::dynamicallyConstrainedSizeHint(Qt::SizeHint which, - const QSizeF &constraint) const -{ - Q_ASSERT(hasDynamicConstraint()); - if (constraint.width() < 0 && constraint.height() < 0) { - // Process the hfw / wfh items that we did not process in fillRowData() - const Qt::Orientation constraintOrient = constraintOrientation(); - - QGridLayoutRowData rowData = constraintOrient == Qt::Vertical ? q_rowData : q_columnData; - for (int i = q_items.count() - 1; i >= 0; --i) { - QGridLayoutItem *item = q_items.at(i); - if (item->hasDynamicConstraint()) { - QGridLayoutBox box = item->box(constraintOrient); - QGridLayoutBox &rowBox = rowData.boxes[item->firstRow(constraintOrient)]; - rowBox.combine(box); - } - } - - QGridLayoutBox totalBoxes[2]; - if (constraintOrient == Qt::Vertical) { - totalBoxes[Hor] = q_columnData.totalBox(0, columnCount()); - totalBoxes[Ver] = rowData.totalBox(0, rowCount()); - } else { - totalBoxes[Hor] = rowData.totalBox(0, columnCount()); - totalBoxes[Ver] = q_rowData.totalBox(0, rowCount()); - } - return QSizeF(totalBoxes[Hor].q_sizes(which), totalBoxes[Ver].q_sizes(which)); - } - - - Q_ASSERT(constraint.width() >= 0 || constraint.height() >= 0); - q_xx.resize(columnCount()); - q_yy.resize(rowCount()); - q_widths.resize(columnCount()); - q_heights.resize(rowCount()); - q_descents.resize(rowCount()); - - - const Qt::Orientation orientation = constraintOrientation(); - QGridLayoutRowData *colData; - QGridLayoutRowData constrainedRowData; - QGridLayoutBox *totalBox; - qreal *sizes; - qreal *pos; - qreal *descents; - qreal targetSize; - qreal cCount; - qreal rCount; - - if (orientation == Qt::Vertical) { - // height for width - colData = &q_columnData; - totalBox = &q_totalBoxes[Hor]; - sizes = q_widths.data(); - pos = q_xx.data(); - descents = 0; - targetSize = constraint.width(); - cCount = columnCount(); - rCount = rowCount(); - constrainedRowData = q_rowData; - } else { - // width for height - colData = &q_rowData; - totalBox = &q_totalBoxes[Ver]; - sizes = q_heights.data(); - pos = q_yy.data(); - descents = q_descents.data(); - targetSize = constraint.height(); - cCount = rowCount(); - rCount = columnCount(); - constrainedRowData = q_columnData; - } - colData->calculateGeometries(0, cCount, targetSize, pos, sizes, descents, *totalBox); - for (int i = q_items.count() - 1; i >= 0; --i) { - QGridLayoutItem *item = q_items.at(i); - - if (item->hasDynamicConstraint()) { - const qreal size = sizes[item->firstColumn(orientation)]; - QGridLayoutBox box = item->box(orientation, size); - QGridLayoutBox &rowBox = constrainedRowData.boxes[item->firstRow(orientation)]; - rowBox.combine(box); - } - } - const qreal newSize = constrainedRowData.totalBox(0, rCount).q_sizes(which); - - return (orientation == Qt::Vertical) ? QSizeF(targetSize, newSize) : QSizeF(newSize, targetSize); -} - - -/** - returns false if the layout has contradicting constraints (i.e. some items with a horizontal - constraint and other items with a vertical constraint) - */ -bool QGridLayoutEngine::ensureDynamicConstraint() const -{ - if (q_cachedConstraintOrientation == UnknownConstraint) { - for (int i = q_items.count() - 1; i >= 0; --i) { - QGridLayoutItem *item = q_items.at(i); - if (item->hasDynamicConstraint()) { - Qt::Orientation itemConstraintOrientation = item->dynamicConstraintOrientation(); - if (q_cachedConstraintOrientation == UnknownConstraint) { - q_cachedConstraintOrientation = itemConstraintOrientation; - } else if (q_cachedConstraintOrientation != itemConstraintOrientation) { - q_cachedConstraintOrientation = UnfeasibleConstraint; - qWarning("QGridLayoutEngine: Unfeasible, cannot mix horizontal and" - " vertical constraint in the same layout"); - return false; - } - } - } - if (q_cachedConstraintOrientation == UnknownConstraint) - q_cachedConstraintOrientation = NoConstraint; - } - return true; -} - -bool QGridLayoutEngine::hasDynamicConstraint() const -{ - if (!ensureDynamicConstraint()) - return false; - return q_cachedConstraintOrientation != NoConstraint; -} - -/* - * return value is only valid if hasConstraint() returns true - */ -Qt::Orientation QGridLayoutEngine::constraintOrientation() const -{ - (void)ensureDynamicConstraint(); - return (Qt::Orientation)q_cachedConstraintOrientation; -} - void QGridLayoutEngine::ensureGeometries(const QLayoutStyleInfo &styleInfo, const QSizeF &size) const { @@ -1709,74 +1544,10 @@ void QGridLayoutEngine::ensureGeometries(const QLayoutStyleInfo &styleInfo, q_widths.resize(columnCount()); q_heights.resize(rowCount()); q_descents.resize(rowCount()); - - - Qt::Orientation orientation = Qt::Vertical; - if (hasDynamicConstraint()) - orientation = constraintOrientation(); - - /* - In order to do hfw we need to first distribute the columns, then the rows. - In order to do wfh we need to first distribute the rows, then the columns. - - If there is no constraint, the order of distributing the rows or columns first is irrelevant. - We choose horizontal just to keep the same behaviour as before (however, there shouldn't - be any behaviour difference). - */ - - QGridLayoutRowData *colData; - QGridLayoutRowData rowData; - qreal *widths; - qreal *heights; - qreal *xx; - qreal *yy; - qreal *xdescents = 0; - qreal *ydescents = 0; - qreal cCount; - qreal rCount; - QSizeF oSize = size; - if (orientation == Qt::Vertical) { - // height for width - colData = &q_columnData; - rowData = q_rowData; - widths = q_widths.data(); - heights = q_heights.data(); - xx = q_xx.data(); - yy = q_yy.data(); - cCount = columnCount(); - rCount = rowCount(); - ydescents = q_descents.data(); - } else { - // width for height - colData = &q_rowData; - rowData = q_columnData; - widths = q_heights.data(); - heights = q_widths.data(); - xx = q_yy.data(); - yy = q_xx.data(); - cCount = rowCount(); - rCount = columnCount(); - xdescents = q_descents.data(); - oSize.transpose(); - } - - colData->calculateGeometries(0, cCount, oSize.width(), xx, widths, - xdescents, q_totalBoxes[orientation == Qt::Horizontal]); - for (int i = q_items.count() - 1; i >= 0; --i) { - QGridLayoutItem *item = q_items.at(i); - const int col = item->firstColumn(orientation); - const int row = item->firstRow(orientation); - if (item->hasDynamicConstraint()) { - const qreal sz = widths[col]; - QGridLayoutBox box = item->box(orientation, sz); - rowData.boxes[row].combine(box); - } - } - - QGridLayoutBox &totalBox = q_totalBoxes[orientation == Qt::Vertical]; - totalBox = rowData.totalBox(0, rCount); - rowData.calculateGeometries(0, rCount, oSize.height(), yy, heights, - ydescents, totalBox); + q_columnData.calculateGeometries(0, columnCount(), size.width(), q_xx.data(), q_widths.data(), + 0, q_totalBoxes[Hor]); + q_rowData.calculateGeometries(0, rowCount(), size.height(), q_yy.data(), q_heights.data(), + q_descents.data(), q_totalBoxes[Ver]); q_cachedSize = size; } diff --git a/src/gui/graphicsview/qgridlayoutengine_p.h b/src/gui/graphicsview/qgridlayoutengine_p.h index 580af7e..9ac9a8e 100644 --- a/src/gui/graphicsview/qgridlayoutengine_p.h +++ b/src/gui/graphicsview/qgridlayoutengine_p.h @@ -91,14 +91,6 @@ enum LayoutSide { Bottom }; -enum { - NoConstraint, - HorizontalConstraint, - VerticalConstraint, - UnknownConstraint, // need to update cache - UnfeasibleConstraint // not feasible, it be has some items with Vertical and others with Horizontal constraints -}; - template class QLayoutParameter { @@ -278,10 +270,6 @@ public: inline void setAlignment(Qt::Alignment alignment) { q_alignment = alignment; } QSizePolicy::Policy sizePolicy(Qt::Orientation orientation) const; - - bool hasDynamicConstraint() const; - Qt::Orientation dynamicConstraintOrientation() const; - QSizePolicy::ControlTypes controlTypes(LayoutSide side) const; QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; QGridLayoutBox box(Qt::Orientation orientation, qreal constraint = -1.0) const; @@ -292,7 +280,7 @@ public: void setGeometry(const QRectF &rect); void transpose(); void insertOrRemoveRows(int row, int delta, Qt::Orientation orientation = Qt::Vertical); - QSizeF effectiveMaxSize(const QSizeF &constraint) const; + QSizeF effectiveMaxSize() const; #ifdef QT_DEBUG void dump(int indent = 0) const; @@ -384,14 +372,6 @@ public: int column, int rowSpan, int columnSpan) const; QSizeF sizeHint(const QLayoutStyleInfo &styleInfo, Qt::SizeHint which, const QSizeF &constraint) const; - - // heightForWidth / widthForHeight support - QSizeF dynamicallyConstrainedSizeHint(Qt::SizeHint which, const QSizeF &constraint) const; - bool ensureDynamicConstraint() const; - bool hasDynamicConstraint() const; - Qt::Orientation constraintOrientation() const; - - QSizePolicy::ControlTypes controlTypes(LayoutSide side) const; void transpose(); void setVisualDirection(Qt::LayoutDirection direction); @@ -425,7 +405,6 @@ private: // Lazily computed from the above user input mutable int q_cachedEffectiveFirstRows[NOrientations]; mutable int q_cachedEffectiveLastRows[NOrientations]; - mutable quint8 q_cachedConstraintOrientation : 2; // Layout item input mutable QLayoutStyleInfo q_cachedDataForStyleInfo; diff --git a/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp b/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp index 03c1d5b..5b03767 100644 --- a/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp +++ b/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp @@ -107,13 +107,12 @@ private slots: void avoidRecursionInInsertItem(); void styleInfoLeak(); void task236367_maxSizeHint(); - void heightForWidth(); }; class RectWidget : public QGraphicsWidget { public: - RectWidget(QGraphicsItem *parent = 0) : QGraphicsWidget(parent), m_fnConstraint(0) {} + RectWidget(QGraphicsItem *parent = 0) : QGraphicsWidget(parent){} void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { @@ -126,12 +125,9 @@ public: QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const { - if (constraint.width() < 0 && constraint.height() < 0 && m_sizeHints[which].isValid()) { + if (m_sizeHints[which].isValid()) { return m_sizeHints[which]; } - if (m_fnConstraint) { - return m_fnConstraint(which, constraint); - } return QGraphicsWidget::sizeHint(which, constraint); } @@ -140,13 +136,7 @@ public: updateGeometry(); } - void setConstraintFunction(QSizeF (*fnConstraint)(Qt::SizeHint, const QSizeF &)) { - m_fnConstraint = fnConstraint; - } - QSizeF m_sizeHints[Qt::NSizeHints]; - QSizeF (*m_fnConstraint)(Qt::SizeHint, const QSizeF &); - }; struct ItemDesc @@ -156,8 +146,7 @@ struct ItemDesc m_rowSpan(1), m_colSpan(1), m_sizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred)), - m_align(0), - m_fnConstraint(0) + m_align(0) { } @@ -224,20 +213,8 @@ struct ItemDesc return (*this); } - ItemDesc &heightForWidth(QSizeF (*fnConstraint)(Qt::SizeHint, const QSizeF &)) { - m_fnConstraint = fnConstraint; - m_constraintOrientation = Qt::Vertical; - return (*this); - } - void apply(QGraphicsGridLayout *layout, QGraphicsWidget *item) { - QSizePolicy sp = m_sizePolicy; - if (m_fnConstraint) { - sp.setHeightForWidth(m_constraintOrientation == Qt::Vertical); - //sp.setWidthForHeight(m_constraintOrientation == Qt::Horizontal); - } - - item->setSizePolicy(sp); + item->setSizePolicy(m_sizePolicy); for (int i = 0; i < Qt::NSizeHints; ++i) { if (!m_sizes[i].isValid()) continue; @@ -256,7 +233,6 @@ struct ItemDesc break; } } - layout->addItem(item, m_pos.first, m_pos.second, m_rowSpan, m_colSpan); layout->setAlignment(item, m_align); } @@ -264,7 +240,6 @@ struct ItemDesc void apply(QGraphicsGridLayout *layout, RectWidget *item) { for (int i = 0; i < Qt::NSizeHints; ++i) item->setSizeHint((Qt::SizeHint)i, m_sizeHints[i]); - item->setConstraintFunction(m_fnConstraint); apply(layout, static_cast(item)); } @@ -276,9 +251,6 @@ struct ItemDesc QSizeF m_sizeHints[Qt::NSizeHints]; QSizeF m_sizes[Qt::NSizeHints]; Qt::Alignment m_align; - - Qt::Orientation m_constraintOrientation; - QSizeF (*m_fnConstraint)(Qt::SizeHint, const QSizeF &); }; typedef QList ItemList; @@ -2144,17 +2116,6 @@ void tst_QGraphicsGridLayout::alignment2() delete widget; } -static QSizeF hfw1(Qt::SizeHint, const QSizeF &constraint) -{ - QSizeF result(constraint); - if (constraint.width() < 0 && constraint.height() < 0) { - return QSizeF(50, 400); - } else if (constraint.width() >= 0) { - result.setHeight(20000./constraint.width()); - } - return result; -} - void tst_QGraphicsGridLayout::geometries_data() { @@ -2184,186 +2145,6 @@ void tst_QGraphicsGridLayout::geometries_data() << QRectF(0, 0, 60,10) << QRectF(0, 10, 60,10) ); - // change layout height and verify - QTest::newRow("hfw-h401") << (ItemList() - << ItemDesc(0,0) - .minSize(QSizeF(1,1)) - .preferredSize(QSizeF(50,10)) - .maxSize(QSizeF(100, 100)) - << ItemDesc(0,1) - .minSize(QSizeF(1,1)) - .preferredSize(QSizeF(50,10)) - .maxSize(QSizeF(100, 100)) - << ItemDesc(1,0) - .minSize(QSizeF(1,1)) - .preferredSize(QSizeF(50,10)) - .maxSize(QSizeF(100, 100)) - << ItemDesc(1,1) - .minSize(QSizeF(40,40)) - .preferredSize(QSizeF(50,400)) - .maxSize(QSizeF(500, 500)) - .heightForWidth(hfw1) - ) - << QSizeF(100, 401) - << (RectList() - << QRectF(0, 0, 50, 1) << QRectF(50, 0, 50, 1) - << QRectF(0, 1, 50,100) << QRectF(50, 1, 50,400) - ); - - - QTest::newRow("hfw-h408") << (ItemList() - << ItemDesc(0,0) - .minSize(QSizeF(1,1)) - .preferredSize(QSizeF(50,10)) - .maxSize(QSizeF(100, 100)) - << ItemDesc(0,1) - .minSize(QSizeF(1,1)) - .preferredSize(QSizeF(50,10)) - .maxSize(QSizeF(100, 100)) - << ItemDesc(1,0) - .minSize(QSizeF(1,1)) - .preferredSize(QSizeF(50,10)) - .maxSize(QSizeF(100, 100)) - << ItemDesc(1,1) - .minSize(QSizeF(40,40)) - .preferredSize(QSizeF(50,400)) - .maxSize(QSizeF(500, 500)) - .heightForWidth(hfw1) - ) - << QSizeF(100, 408) - << (RectList() - << QRectF(0, 0, 50, 8) << QRectF(50, 0, 50, 8) - << QRectF(0, 8, 50,100) << QRectF(50, 8, 50,400) - ); - - QTest::newRow("hfw-h410") << (ItemList() - << ItemDesc(0,0) - .minSize(QSizeF(1,1)) - .preferredSize(QSizeF(50,10)) - .maxSize(QSizeF(100, 100)) - << ItemDesc(0,1) - .minSize(QSizeF(1,1)) - .preferredSize(QSizeF(50,10)) - .maxSize(QSizeF(100, 100)) - << ItemDesc(1,0) - .minSize(QSizeF(1,1)) - .preferredSize(QSizeF(50,10)) - .maxSize(QSizeF(100, 100)) - << ItemDesc(1,1) - .minSize(QSizeF(40,40)) - .preferredSize(QSizeF(50,400)) - .maxSize(QSizeF(500, 500)) - .heightForWidth(hfw1) - ) - << QSizeF(100, 410) - << (RectList() - << QRectF(0, 0, 50,10) << QRectF(50, 0, 50,10) - << QRectF(0, 10, 50,100) << QRectF(50, 10, 50,400) - ); - - QTest::newRow("hfw-h470") << (ItemList() - << ItemDesc(0,0) - .minSize(QSizeF(1,1)) - .preferredSize(QSizeF(50,10)) - .maxSize(QSizeF(100, 100)) - << ItemDesc(0,1) - .minSize(QSizeF(1,1)) - .preferredSize(QSizeF(50,10)) - .maxSize(QSizeF(100, 100)) - << ItemDesc(1,0) - .minSize(QSizeF(1,1)) - .preferredSize(QSizeF(50,10)) - .maxSize(QSizeF(100, 100)) - << ItemDesc(1,1) - .minSize(QSizeF(40,40)) - .preferredSize(QSizeF(50,400)) - .maxSize(QSizeF(500, 500)) - .heightForWidth(hfw1) - ) - << QSizeF(100, 470) - << (RectList() - << QRectF(0, 0, 50,70) << QRectF(50, 0, 50,70) - << QRectF(0, 70, 50,100) << QRectF(50, 70, 50,400) - ); - - - // change layout width and verify - QTest::newRow("hfw-w100") << (ItemList() - << ItemDesc(0,0) - .minSize(QSizeF(1,1)) - .preferredSize(QSizeF(50,10)) - .maxSize(QSizeF(100, 100)) - << ItemDesc(0,1) - .minSize(QSizeF(1,1)) - .preferredSize(QSizeF(50,10)) - .maxSize(QSizeF(100, 100)) - << ItemDesc(1,0) - .minSize(QSizeF(1,1)) - .preferredSize(QSizeF(50,10)) - .maxSize(QSizeF(100, 100)) - << ItemDesc(1,1) - .minSize(QSizeF(40,40)) - .preferredSize(QSizeF(50,400)) - .maxSize(QSizeF(5000, 5000)) - .heightForWidth(hfw1) - ) - << QSizeF(100, 401) - << (RectList() - << QRectF( 0, 0, 50, 1) << QRectF( 50, 0, 50, 1) - << QRectF( 0, 1, 50, 100) << QRectF( 50, 1, 50, 400) - ); - - QTest::newRow("hfw-w160") << (ItemList() - << ItemDesc(0,0) - .minSize(QSizeF(1,1)) - .preferredSize(QSizeF(50,10)) - .maxSize(QSizeF(100, 100)) - << ItemDesc(0,1) - .minSize(QSizeF(1,1)) - .preferredSize(QSizeF(50,10)) - .maxSize(QSizeF(100, 100)) - << ItemDesc(1,0) - .minSize(QSizeF(1,1)) - .preferredSize(QSizeF(50,10)) - .maxSize(QSizeF(100, 100)) - << ItemDesc(1,1) - .minSize(QSizeF(40,40)) - .preferredSize(QSizeF(50,400)) - .maxSize(QSizeF(5000, 5000)) - .heightForWidth(hfw1) - ) - << QSizeF(160, 401) - << (RectList() - << QRectF( 0, 0, 80, 100) << QRectF( 80, 0, 80, 100) - << QRectF( 0, 100, 80, 100) << QRectF( 80, 100, 80, 250) - ); - - - QTest::newRow("hfw-w500") << (ItemList() - << ItemDesc(0,0) - .minSize(QSizeF(1,1)) - .preferredSize(QSizeF(50,10)) - .maxSize(QSizeF(100, 100)) - << ItemDesc(0,1) - .minSize(QSizeF(1,1)) - .preferredSize(QSizeF(50,10)) - .maxSize(QSizeF(100, 100)) - << ItemDesc(1,0) - .minSize(QSizeF(1,1)) - .preferredSize(QSizeF(50,10)) - .maxSize(QSizeF(100, 100)) - << ItemDesc(1,1) - .minSize(QSizeF(40,40)) - .preferredSize(QSizeF(50,400)) - .maxSize(QSizeF(5000, 5000)) - .heightForWidth(hfw1) - ) - << QSizeF(500, 401) - << (RectList() - << QRectF( 0, 0, 100, 100) << QRectF(100, 0, 100, 100) - << QRectF( 0, 100, 100, 100) << QRectF(100, 100, 400, 50) - ); - } void tst_QGraphicsGridLayout::geometries() @@ -2434,143 +2215,6 @@ void tst_QGraphicsGridLayout::task236367_maxSizeHint() QCOMPARE(widget->size(), QSizeF(w, h)); } -/* -static qreal hfw(qreal w) -{ - if (w == 0) - return 20000; - return 20000/w; -} -*/ -static QSizeF hfw(Qt::SizeHint /*which*/, const QSizeF &constraint) -{ - QSizeF result(constraint); - const qreal cw = constraint.width(); - const qreal ch = constraint.height(); - if (cw < 0 && ch < 0) { - return QSizeF(200, 100); - } else if (cw >= 0) { - result.setHeight(20000./cw); - } else if (cw == 0) { - result.setHeight(20000); - } else if (ch >= 0) { - result.setWidth(20000./ch); - } else if (ch == 0) { - result.setWidth(20000); - } - - return result; -} - -static qreal growthFactorBelowPreferredSize(qreal desired, qreal sumAvailable, qreal sumDesired) -{ - Q_ASSERT(sumDesired != 0.0); - return desired * qPow(sumAvailable / sumDesired, desired / sumDesired); -} - -static void expectedWidth(qreal minSize1, qreal prefSize1, - qreal minSize2, qreal prefSize2, - qreal targetSize, qreal *width1, qreal *width2) -{ - qreal sumAvail,factor1,factor2; - // stretch behaviour is different below and above preferred size... - if (targetSize < prefSize1 + prefSize2) { - sumAvail = targetSize - minSize1 - minSize2; - const qreal desired1 = prefSize1 - minSize1; - const qreal desired2 = prefSize2 - minSize2; - const qreal sumDesired = desired1 + desired2; - factor1 = growthFactorBelowPreferredSize(desired1, sumAvail, sumDesired); - factor2 = growthFactorBelowPreferredSize(desired2, sumAvail, sumDesired); - const qreal sumFactors = factor1 + factor2; - *width1 = sumAvail*factor1/sumFactors + minSize1; - *width2 = sumAvail*factor2/sumFactors + minSize2; - } else { - sumAvail = targetSize - prefSize1 - prefSize2; - factor1 = prefSize1; - factor2 = prefSize2; - const qreal sumFactors = factor1 + factor2; - *width1 = sumAvail*factor1/sumFactors + prefSize1; - *width2 = sumAvail*factor2/sumFactors + prefSize2; - } -} - - -bool qFuzzyCompare(const QSizeF &a, const QSizeF &b) -{ - return qFuzzyCompare(a.width(), b.width()) && qFuzzyCompare(a.height(), b.height()); -} - -void tst_QGraphicsGridLayout::heightForWidth() -{ - QGraphicsWidget *widget = new QGraphicsWidget; - QGraphicsGridLayout *layout = new QGraphicsGridLayout; - widget->setLayout(layout); - layout->setContentsMargins(0, 0, 0, 0); - layout->setSpacing(0); - RectWidget *w00 = new RectWidget; - w00->setSizeHint(Qt::MinimumSize, QSizeF(1,1)); - w00->setSizeHint(Qt::PreferredSize, QSizeF(10,10)); - w00->setSizeHint(Qt::MaximumSize, QSizeF(100,100)); - layout->addItem(w00, 0, 0); - - RectWidget *w01 = new RectWidget; - w01->setSizeHint(Qt::MinimumSize, QSizeF(1,1)); - w01->setSizeHint(Qt::PreferredSize, QSizeF(10,10)); - w01->setSizeHint(Qt::MaximumSize, QSizeF(100,100)); - layout->addItem(w01, 0, 1); - - RectWidget *w10 = new RectWidget; - w10->setSizeHint(Qt::MinimumSize, QSizeF(1,1)); - w10->setSizeHint(Qt::PreferredSize, QSizeF(10,10)); - w10->setSizeHint(Qt::MaximumSize, QSizeF(100,100)); - layout->addItem(w10, 1, 0); - - RectWidget *w11 = new RectWidget; - w11->setSizeHint(Qt::MinimumSize, QSizeF(1,1)); - w11->setSizeHint(Qt::MaximumSize, QSizeF(30000,30000)); - w11->setConstraintFunction(hfw); - QSizePolicy sp(QSizePolicy::Preferred, QSizePolicy::Preferred); - sp.setHeightForWidth(true); - w11->setSizePolicy(sp); - layout->addItem(w11, 1, 1); - - QSizeF prefSize = layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(-1, -1)); - QCOMPARE(prefSize, QSizeF(10+200, 10+100)); - - QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(2, -1)), QSizeF(2, 20001)); - QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(2, -1)), QSizeF(2, 20010)); - QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(2, -1)), QSizeF(2, 20100)); - qreal width1; - qreal width2; - expectedWidth(1, 10, 1, 200, 20, &width1, &width2); - QSizeF expectedSize = hfw(Qt::MinimumSize, QSizeF(width2, -1)) + QSizeF(width1, 1); - QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(20, -1)), expectedSize); - expectedSize.rheight()+=9; - QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(20, -1)), expectedSize); - expectedSize.rheight()+=90; - QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(20, -1)), expectedSize); - - expectedWidth(1, 10, 1, 200, 300, &width1, &width2); - expectedSize = hfw(Qt::MinimumSize, QSizeF(width2, -1)) + QSizeF(width1, 1); - QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(300, -1)), expectedSize); - expectedSize.rheight()+=9; - QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(300, -1)), expectedSize); - // the height of the hfw widget is shorter than the one to the left, which is 100, so - // the total height of the last row is 100 (which leaves the layout height to be 200) - QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(300, -1)), QSizeF(300, 200)); - - // the hfw item is shorter than the item to the left - expectedWidth(1, 10, 1, 200, 500, &width1, &width2); - expectedSize = hfw(Qt::MinimumSize, QSizeF(width2, -1)) + QSizeF(width1, 1); - QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(500, -1)), expectedSize); - expectedSize.rheight()+=9; - QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(500, -1)), expectedSize); - // the height of the hfw widget is shorter than the one to the left, which is 100, so - // the total height of the last row is 100 (which leaves the layout height to be 200) - QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(500, -1)), QSizeF(500, 200)); - -} - QTEST_MAIN(tst_QGraphicsGridLayout) #include "tst_qgraphicsgridlayout.moc" -- cgit v0.12 From 086a349d770eafe007136f3dda6ef7d6093a86a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Fri, 17 Sep 2010 08:30:04 +0200 Subject: Moving QPdf::stripSpecialCharacter to fontengine It is only used by the fontengines. This is one of the steps to make it easier to make fontengines build outside of QtGui. Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/painting/qpdf.cpp | 18 ------------------ src/gui/painting/qpdf_p.h | 2 -- src/gui/text/qfontengine.cpp | 24 ++++++++++++++++++------ src/gui/text/qfontengine_ft.cpp | 6 +----- src/gui/text/qfontengine_mac.mm | 3 +-- src/gui/text/qfontengine_p.h | 2 ++ src/gui/text/qfontengine_win.cpp | 5 +---- 7 files changed, 23 insertions(+), 37 deletions(-) diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index 6e02435..ba5d164 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -916,24 +916,6 @@ const char *QPdf::paperSizeToString(QPrinter::PaperSize paperSize) } -QByteArray QPdf::stripSpecialCharacters(const QByteArray &string) -{ - QByteArray s = string; - s.replace(' ', ""); - s.replace('(', ""); - s.replace(')', ""); - s.replace('<', ""); - s.replace('>', ""); - s.replace('[', ""); - s.replace(']', ""); - s.replace('{', ""); - s.replace('}', ""); - s.replace('/', ""); - s.replace('%', ""); - return s; -} - - // -------------------------- base engine, shared code between PS and PDF ----------------------- QPdfBaseEngine::QPdfBaseEngine(QPdfBaseEnginePrivate &dd, PaintEngineFeatures f) diff --git a/src/gui/painting/qpdf_p.h b/src/gui/painting/qpdf_p.h index 9c4d05d..5c5ceb4 100644 --- a/src/gui/painting/qpdf_p.h +++ b/src/gui/painting/qpdf_p.h @@ -156,8 +156,6 @@ namespace QPdf { PaperSize paperSize(QPrinter::PaperSize paperSize); const char *paperSizeToString(QPrinter::PaperSize paperSize); - - QByteArray stripSpecialCharacters(const QByteArray &string); } diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 0dfd295..7e04180 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -46,7 +46,6 @@ #include "qpainter.h" #include "qpainterpath.h" #include "qvarlengtharray.h" -#include #include #include #include @@ -667,11 +666,7 @@ void QFontEngine::removeGlyphFromCache(glyph_t) QFontEngine::Properties QFontEngine::properties() const { Properties p; -#ifndef QT_NO_PRINTER - QByteArray psname = QPdf::stripSpecialCharacters(fontDef.family.toUtf8()); -#else - QByteArray psname = fontDef.family.toUtf8(); -#endif + QByteArray psname = QFontEngine::convertToPostscriptFontFamilyName(fontDef.family.toUtf8()); psname += '-'; psname += QByteArray::number(fontDef.style); psname += '-'; @@ -1081,6 +1076,23 @@ quint32 QFontEngine::getTrueTypeGlyphIndex(const uchar *cmap, uint unicode) return 0; } +QByteArray QFontEngine::convertToPostscriptFontFamilyName(const QByteArray &family) +{ + QByteArray f = family; + f.replace(' ', ""); + f.replace('(', ""); + f.replace(')', ""); + f.replace('<', ""); + f.replace('>', ""); + f.replace('[', ""); + f.replace(']', ""); + f.replace('{', ""); + f.replace('}', ""); + f.replace('/', ""); + f.replace('%', ""); + return f; +} + Q_GLOBAL_STATIC_WITH_INITIALIZER(QVector, qt_grayPalette, { x->resize(256); QRgb *it = x->data(); diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index a9b25f5..cc6af7f 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -51,7 +51,6 @@ #include "qabstractfileengine.h" #include "qthreadstorage.h" #include -#include #include #include "qfontengine_ft_p.h" @@ -1196,10 +1195,7 @@ QFontEngine::Properties QFontEngineFT::properties() const { Properties p = freetype->properties(); if (p.postscriptName.isEmpty()) { - p.postscriptName = fontDef.family.toUtf8(); -#ifndef QT_NO_PRINTER - p.postscriptName = QPdf::stripSpecialCharacters(p.postscriptName); -#endif + p.postscriptName = QFontEngine::convertToPostscriptFontFamilyName(fontDef.family.toUtf8()); } return freetype->properties(); diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm index bdf3848..b3efe6c 100644 --- a/src/gui/text/qfontengine_mac.mm +++ b/src/gui/text/qfontengine_mac.mm @@ -46,7 +46,6 @@ #include #include #include -#include #include #include #include @@ -1853,7 +1852,7 @@ QFontEngine::Properties QFontEngineMac::properties() const QCFString psName; if (ATSFontGetPostScriptName(FMGetATSFontRefFromFont(fontID), kATSOptionFlagsDefault, &psName) == noErr) props.postscriptName = QString(psName).toUtf8(); - props.postscriptName = QPdf::stripSpecialCharacters(props.postscriptName); + props.postscriptName = QFontEngine::convertToPostscriptFontFamilyName(props.postscriptName); return props; } diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index 3b91cd8..571cf98 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -227,6 +227,8 @@ public: static const uchar *getCMap(const uchar *table, uint tableSize, bool *isSymbolFont, int *cmapSize); static quint32 getTrueTypeGlyphIndex(const uchar *cmap, uint unicode); + static QByteArray convertToPostscriptFontFamilyName(const QByteArray &fontFamily); + QAtomicInt ref; QFontDef fontDef; uint cache_cost; // amount of mem used in kb by the font diff --git a/src/gui/text/qfontengine_win.cpp b/src/gui/text/qfontengine_win.cpp index ef1b504..7609ee5 100644 --- a/src/gui/text/qfontengine_win.cpp +++ b/src/gui/text/qfontengine_win.cpp @@ -63,7 +63,6 @@ #include #include -#include #include "qpaintengine.h" #include "qvarlengtharray.h" #include @@ -1039,9 +1038,7 @@ QFontEngine::Properties QFontEngineWin::properties() const p.italicAngle = otm->otmItalicAngle; p.postscriptName = QString::fromWCharArray((wchar_t *)((char *)otm + (quintptr)otm->otmpFamilyName)).toLatin1(); p.postscriptName += QString::fromWCharArray((wchar_t *)((char *)otm + (quintptr)otm->otmpStyleName)).toLatin1(); -#ifndef QT_NO_PRINTER - p.postscriptName = QPdf::stripSpecialCharacters(p.postscriptName); -#endif + p.postscriptName = QFontEngine::convertToPostscriptFontFamilyName(p.postscriptName); p.boundingBox = QRectF(otm->otmrcFontBox.left, -otm->otmrcFontBox.top, otm->otmrcFontBox.right - otm->otmrcFontBox.left, otm->otmrcFontBox.top - otm->otmrcFontBox.bottom); -- cgit v0.12 From 4cd4160d85dc1e158a545422cac895792b14eda6 Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Wed, 29 Sep 2010 18:41:38 +0200 Subject: Fixed parsing of SVGs with absolute font sizes. Task-number: QTBUG-14070 Reviewed-by: Gunnar --- src/svg/qsvghandler.cpp | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp index bf19a88..c17ca7a 100644 --- a/src/svg/qsvghandler.cpp +++ b/src/svg/qsvghandler.cpp @@ -1282,8 +1282,39 @@ static void parseFont(QSvgNode *node, fontStyle->setFamily(attributes.fontFamily.toString().trimmed()); if (!attributes.fontSize.isEmpty() && attributes.fontSize != QT_INHERIT) { + // TODO: Support relative sizes 'larger' and 'smaller'. QSvgHandler::LengthType dummy; // should always be pixel size - fontStyle->setSize(parseLength(attributes.fontSize.toString(), dummy, handler)); + qreal size = 0; + static const qreal sizeTable[] = { qreal(6.9), qreal(8.3), qreal(10.0), qreal(12.0), qreal(14.4), qreal(17.3), qreal(20.7) }; + enum AbsFontSize { XXSmall, XSmall, Small, Medium, Large, XLarge, XXLarge }; + switch (attributes.fontSize.at(0).unicode()) { + case 'x': + if (attributes.fontSize == QLatin1String("xx-small")) + size = sizeTable[XXSmall]; + else if (attributes.fontSize == QLatin1String("x-small")) + size = sizeTable[XSmall]; + else if (attributes.fontSize == QLatin1String("x-large")) + size = sizeTable[XLarge]; + else if (attributes.fontSize == QLatin1String("xx-large")) + size = sizeTable[XXLarge]; + break; + case 's': + if (attributes.fontSize == QLatin1String("small")) + size = sizeTable[Small]; + break; + case 'm': + if (attributes.fontSize == QLatin1String("medium")) + size = sizeTable[Medium]; + break; + case 'l': + if (attributes.fontSize == QLatin1String("large")) + size = sizeTable[Large]; + break; + default: + size = parseLength(attributes.fontSize.toString(), dummy, handler); + break; + } + fontStyle->setSize(size); } if (!attributes.fontStyle.isEmpty() && attributes.fontStyle != QT_INHERIT) { -- cgit v0.12 From b8089f0b7a0fef9318070aea9c8344bfe987bac9 Mon Sep 17 00:00:00 2001 From: Leandro Melo Date: Thu, 30 Sep 2010 11:43:10 +0200 Subject: Build fix for -qtnamespace. Reviewed-by: Thiago Macieira --- src/corelib/plugin/qsystemlibrary.cpp | 5 +++++ src/corelib/plugin/qsystemlibrary_p.h | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/src/corelib/plugin/qsystemlibrary.cpp b/src/corelib/plugin/qsystemlibrary.cpp index eeb142b..1b8d8fe 100644 --- a/src/corelib/plugin/qsystemlibrary.cpp +++ b/src/corelib/plugin/qsystemlibrary.cpp @@ -77,6 +77,9 @@ in the documentation for LoadLibrary for Windows CE at MSDN. (http://msdn.microsoft.com/en-us/library/ms886736.aspx) */ + +QT_BEGIN_NAMESPACE + #if defined(Q_OS_WINCE) HINSTANCE QSystemLibrary::load(const wchar_t *libraryName, bool onlySystemDirectory /* = true */) { @@ -134,3 +137,5 @@ HINSTANCE QSystemLibrary::load(const wchar_t *libraryName, bool onlySystemDirect } #endif //Q_OS_WINCE + +QT_END_NAMESPACE diff --git a/src/corelib/plugin/qsystemlibrary_p.h b/src/corelib/plugin/qsystemlibrary_p.h index 3251a3c..8000a61 100644 --- a/src/corelib/plugin/qsystemlibrary_p.h +++ b/src/corelib/plugin/qsystemlibrary_p.h @@ -47,6 +47,8 @@ #include #include +QT_BEGIN_NAMESPACE + class QSystemLibrary { public: @@ -101,6 +103,8 @@ private: bool m_didLoad; }; +QT_END_NAMESPACE + #endif //Q_OS_WIN #endif //QSYSTEMLIBRARY_P_H -- cgit v0.12 From 718d22962de9b2798ccae4aac6cb5e3798d440a1 Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Thu, 30 Sep 2010 13:19:08 +0200 Subject: Fixed accessing freed memory in raster engine. The bug was discovered when running the svgviewer example on 64-bit Windows. Reviewed-by: Samuel --- src/gui/painting/qpaintengine_raster.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 36e1082..9749244 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -4233,6 +4233,8 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, break; } + rendered_spans += q_gray_rendered_spans(*grayRaster.data()); + #if defined(Q_WS_WIN64) _aligned_free(rasterPoolBase); #else @@ -4251,8 +4253,6 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, #endif Q_CHECK_PTR(rasterPoolBase); // note: we just freed the old rasterPoolBase. I hope it's not fatal. - rendered_spans += q_gray_rendered_spans(*grayRaster.data()); - qt_ft_grays_raster.raster_done(*grayRaster.data()); qt_ft_grays_raster.raster_new(grayRaster.data()); qt_ft_grays_raster.raster_reset(*grayRaster.data(), rasterPoolBase, rasterPoolSize); -- cgit v0.12 From c2d539bbb25220105ee79de6d0d59e686508d765 Mon Sep 17 00:00:00 2001 From: Leandro Melo Date: Thu, 30 Sep 2010 11:43:10 +0200 Subject: Build fix for -qtnamespace. Reviewed-by: Thiago Macieira (cherry picked from commit b8089f0b7a0fef9318070aea9c8344bfe987bac9) --- src/corelib/plugin/qsystemlibrary.cpp | 5 +++++ src/corelib/plugin/qsystemlibrary_p.h | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/src/corelib/plugin/qsystemlibrary.cpp b/src/corelib/plugin/qsystemlibrary.cpp index a11ed50..43de946 100644 --- a/src/corelib/plugin/qsystemlibrary.cpp +++ b/src/corelib/plugin/qsystemlibrary.cpp @@ -77,6 +77,9 @@ in the documentation for LoadLibrary for Windows CE at MSDN. (http://msdn.microsoft.com/en-us/library/ms886736.aspx) */ + +QT_BEGIN_NAMESPACE + #if defined(Q_OS_WINCE) HINSTANCE QSystemLibrary::load(const wchar_t *libraryName, bool onlySystemDirectory/*= true*/) { @@ -134,3 +137,5 @@ HINSTANCE QSystemLibrary::load(const wchar_t *libraryName, bool onlySystemDirect } #endif //Q_OS_WINCE + +QT_END_NAMESPACE diff --git a/src/corelib/plugin/qsystemlibrary_p.h b/src/corelib/plugin/qsystemlibrary_p.h index 3251a3c..8000a61 100644 --- a/src/corelib/plugin/qsystemlibrary_p.h +++ b/src/corelib/plugin/qsystemlibrary_p.h @@ -47,6 +47,8 @@ #include #include +QT_BEGIN_NAMESPACE + class QSystemLibrary { public: @@ -101,6 +103,8 @@ private: bool m_didLoad; }; +QT_END_NAMESPACE + #endif //Q_OS_WIN #endif //QSYSTEMLIBRARY_P_H -- cgit v0.12 From 30769c79fa18cd14fe1cdb7d0eca95a5daca77a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Thu, 30 Sep 2010 15:12:17 +0200 Subject: Stabilize tst_QGraphicsWidget::QT_BUG_13865_doublePaintWhenAddingASubItem --- tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp index 7f24ddc..5891075 100644 --- a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp +++ b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp @@ -3350,6 +3350,7 @@ void tst_QGraphicsWidget::QT_BUG_13865_doublePaintWhenAddingASubItem() view.show(); QTest::qWaitForWindowShown(&view); + QApplication::processEvents(); GreenWidget *sub = new GreenWidget; -- cgit v0.12 From c146652bfb336c084c39db7513e27540e456791e Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Mon, 27 Sep 2010 17:35:06 +0200 Subject: FocusOut even when QGraphicsItem gets hidden. If a parent QGraphicsItem becomes invisible, its child would not receive a focus out event. Review-by: Thierry Task-number: QTBUG-13916 --- src/gui/graphicsview/qgraphicsitem.cpp | 8 +++-- tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp | 34 ++++++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 3b18c31..fc44a44 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -6655,6 +6655,11 @@ bool QGraphicsItem::sceneEvent(QEvent *event) return true; } + if (event->type() == QEvent::FocusOut) { + focusOutEvent(static_cast(event)); + return true; + } + if (!d_ptr->visible) { // Eaten return true; @@ -6664,9 +6669,6 @@ bool QGraphicsItem::sceneEvent(QEvent *event) case QEvent::FocusIn: focusInEvent(static_cast(event)); break; - case QEvent::FocusOut: - focusOutEvent(static_cast(event)); - break; case QEvent::GraphicsSceneContextMenu: contextMenuEvent(static_cast(event)); break; diff --git a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp index 5891075..9d6def8 100644 --- a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp +++ b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp @@ -101,6 +101,7 @@ private slots: void focusWidget_data(); void focusWidget(); void focusWidget2(); + void focusWidget3(); void focusPolicy_data(); void focusPolicy(); void font_data(); @@ -558,6 +559,39 @@ void tst_QGraphicsWidget::focusWidget2() QVERIFY(!widget->focusWidget()); } +class FocusWatchWidget : public QGraphicsWidget +{ +public: + FocusWatchWidget(QGraphicsItem *parent = 0) : QGraphicsWidget(parent) { gotFocusInCount = 0; gotFocusOutCount = 0; } + int gotFocusInCount, gotFocusOutCount; +protected: + void focusInEvent(QFocusEvent *fe) { gotFocusInCount++; QGraphicsWidget::focusInEvent(fe); } + void focusOutEvent(QFocusEvent *fe) { gotFocusOutCount++; QGraphicsWidget::focusOutEvent(fe); } +}; + +void tst_QGraphicsWidget::focusWidget3() +{ + QGraphicsScene scene; + QEvent windowActivate(QEvent::WindowActivate); + qApp->sendEvent(&scene, &windowActivate); + + QGraphicsWidget *widget = new QGraphicsWidget; + FocusWatchWidget *subWidget = new FocusWatchWidget(widget); + subWidget->setFocusPolicy(Qt::StrongFocus); + + scene.addItem(widget); + widget->show(); + + QTRY_VERIFY(!widget->hasFocus()); + QTRY_VERIFY(!subWidget->hasFocus()); + + subWidget->setFocus(); + QCOMPARE(subWidget->gotFocusInCount, 1); + QCOMPARE(subWidget->gotFocusOutCount, 0); + widget->hide(); + QCOMPARE(subWidget->gotFocusOutCount, 1); +} + Q_DECLARE_METATYPE(Qt::FocusPolicy) void tst_QGraphicsWidget::focusPolicy_data() { -- cgit v0.12 From ea8dd9d2dbd3345fbf76625c441d9832f758bf70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Fri, 1 Oct 2010 14:51:54 +0200 Subject: Fixed antialiased rendering error in raster engine due to wrong merge. We should only add to rendered_spans once, before freeing the rasterizer memory pool. This fixes the tst_qpathclipper:clip2() auto-test failure on 32-bit linux. Reviewed-by: Kim --- src/gui/painting/qpaintengine_raster.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 135ae00..9749244 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -4253,8 +4253,6 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, #endif Q_CHECK_PTR(rasterPoolBase); // note: we just freed the old rasterPoolBase. I hope it's not fatal. - rendered_spans += q_gray_rendered_spans(*grayRaster.data()); - qt_ft_grays_raster.raster_done(*grayRaster.data()); qt_ft_grays_raster.raster_new(grayRaster.data()); qt_ft_grays_raster.raster_reset(*grayRaster.data(), rasterPoolBase, rasterPoolSize); -- cgit v0.12 From 73fa0f87c26a3f5bf17746ec91d05264f0020093 Mon Sep 17 00:00:00 2001 From: Chris Meyer Date: Mon, 4 Oct 2010 10:49:32 +0200 Subject: Fix QTBUG-13730. QGraphicsScene::render clipping bug. Includes test case. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merge-request: 2480 Reviewed-by: Samuel Rødal --- src/gui/graphicsview/qgraphicsscene.cpp | 2 +- .../render/all-all-untransformed-clip-ellipse.png | Bin 0 -> 1819 bytes .../render/all-all-untransformed-clip-rect.png | Bin 0 -> 1255 bytes tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp | 65 ++++++++++++--------- 4 files changed, 40 insertions(+), 27 deletions(-) create mode 100644 tests/auto/qgraphicsscene/testData/render/all-all-untransformed-clip-ellipse.png create mode 100644 tests/auto/qgraphicsscene/testData/render/all-all-untransformed-clip-rect.png diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 8dc15bf..e58b93c 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -1759,7 +1759,7 @@ void QGraphicsScene::render(QPainter *painter, const QRectF &target, const QRect painter->save(); // Transform the painter. - painter->setClipRect(targetRect); + painter->setClipRect(targetRect, Qt::IntersectClip); QTransform painterTransform; painterTransform *= QTransform() .translate(targetRect.left(), targetRect.top()) diff --git a/tests/auto/qgraphicsscene/testData/render/all-all-untransformed-clip-ellipse.png b/tests/auto/qgraphicsscene/testData/render/all-all-untransformed-clip-ellipse.png new file mode 100644 index 0000000..9b401b4 Binary files /dev/null and b/tests/auto/qgraphicsscene/testData/render/all-all-untransformed-clip-ellipse.png differ diff --git a/tests/auto/qgraphicsscene/testData/render/all-all-untransformed-clip-rect.png b/tests/auto/qgraphicsscene/testData/render/all-all-untransformed-clip-rect.png new file mode 100644 index 0000000..1c59698 Binary files /dev/null and b/tests/auto/qgraphicsscene/testData/render/all-all-untransformed-clip-rect.png differ diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp index b8e729e..09cf4e2 100644 --- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp @@ -2617,59 +2617,70 @@ void tst_QGraphicsScene::render_data() QTest::addColumn("sourceRect"); QTest::addColumn("aspectRatioMode"); QTest::addColumn("matrix"); + QTest::addColumn("clip"); + + QPainterPath clip_rect; + clip_rect.addRect(50, 100, 200, 150); + + QPainterPath clip_ellipse; + clip_ellipse.addEllipse(100,50,150,200); QTest::newRow("all-all-untransformed") << QRectF() << QRectF() - << Qt::IgnoreAspectRatio << QMatrix(); + << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); QTest::newRow("all-topleft-untransformed") << QRectF(0, 0, 150, 150) - << QRectF() << Qt::IgnoreAspectRatio << QMatrix(); + << QRectF() << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); QTest::newRow("all-topright-untransformed") << QRectF(150, 0, 150, 150) - << QRectF() << Qt::IgnoreAspectRatio << QMatrix(); + << QRectF() << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); QTest::newRow("all-bottomleft-untransformed") << QRectF(0, 150, 150, 150) - << QRectF() << Qt::IgnoreAspectRatio << QMatrix(); + << QRectF() << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); QTest::newRow("all-bottomright-untransformed") << QRectF(150, 150, 150, 150) - << QRectF() << Qt::IgnoreAspectRatio << QMatrix(); + << QRectF() << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); QTest::newRow("topleft-all-untransformed") << QRectF() << QRectF(-10, -10, 10, 10) - << Qt::IgnoreAspectRatio << QMatrix(); + << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); QTest::newRow("topright-all-untransformed") << QRectF() << QRectF(0, -10, 10, 10) - << Qt::IgnoreAspectRatio << QMatrix(); + << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); QTest::newRow("bottomleft-all-untransformed") << QRectF() << QRectF(-10, 0, 10, 10) - << Qt::IgnoreAspectRatio << QMatrix(); + << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); QTest::newRow("bottomright-all-untransformed") << QRectF() << QRectF(0, 0, 10, 10) - << Qt::IgnoreAspectRatio << QMatrix(); + << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); QTest::newRow("topleft-topleft-untransformed") << QRectF(0, 0, 150, 150) << QRectF(-10, -10, 10, 10) - << Qt::IgnoreAspectRatio << QMatrix(); + << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); QTest::newRow("topright-topleft-untransformed") << QRectF(150, 0, 150, 150) << QRectF(-10, -10, 10, 10) - << Qt::IgnoreAspectRatio << QMatrix(); + << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); QTest::newRow("bottomleft-topleft-untransformed") << QRectF(0, 150, 150, 150) << QRectF(-10, -10, 10, 10) - << Qt::IgnoreAspectRatio << QMatrix(); + << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); QTest::newRow("bottomright-topleft-untransformed") << QRectF(150, 150, 150, 150) << QRectF(-10, -10, 10, 10) - << Qt::IgnoreAspectRatio << QMatrix(); + << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); QTest::newRow("top-topleft-untransformed") << QRectF(0, 0, 300, 150) << QRectF(-10, -10, 10, 10) - << Qt::IgnoreAspectRatio << QMatrix(); + << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); QTest::newRow("bottom-topleft-untransformed") << QRectF(0, 150, 300, 150) << QRectF(-10, -10, 10, 10) - << Qt::IgnoreAspectRatio << QMatrix(); + << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); QTest::newRow("left-topleft-untransformed") << QRectF(0, 0, 150, 300) << QRectF(-10, -10, 10, 10) - << Qt::IgnoreAspectRatio << QMatrix(); + << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); QTest::newRow("right-topleft-untransformed") << QRectF(150, 0, 150, 300) << QRectF(-10, -10, 10, 10) - << Qt::IgnoreAspectRatio << QMatrix(); + << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); QTest::newRow("top-bottomright-untransformed") << QRectF(0, 0, 300, 150) << QRectF(0, 0, 10, 10) - << Qt::IgnoreAspectRatio << QMatrix(); + << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); QTest::newRow("bottom-bottomright-untransformed") << QRectF(0, 150, 300, 150) << QRectF(0, 0, 10, 10) - << Qt::IgnoreAspectRatio << QMatrix(); + << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); QTest::newRow("left-bottomright-untransformed") << QRectF(0, 0, 150, 300) << QRectF(0, 0, 10, 10) - << Qt::IgnoreAspectRatio << QMatrix(); + << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); QTest::newRow("right-bottomright-untransformed") << QRectF(150, 0, 150, 300) << QRectF(0, 0, 10, 10) - << Qt::IgnoreAspectRatio << QMatrix(); + << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); QTest::newRow("all-all-45-deg-right") << QRectF() << QRectF() - << Qt::IgnoreAspectRatio << QMatrix().rotate(-45); + << Qt::IgnoreAspectRatio << QMatrix().rotate(-45) << QPainterPath(); QTest::newRow("all-all-45-deg-left") << QRectF() << QRectF() - << Qt::IgnoreAspectRatio << QMatrix().rotate(45); + << Qt::IgnoreAspectRatio << QMatrix().rotate(45) << QPainterPath(); QTest::newRow("all-all-scale-2x") << QRectF() << QRectF() - << Qt::IgnoreAspectRatio << QMatrix().scale(2, 2); + << Qt::IgnoreAspectRatio << QMatrix().scale(2, 2) << QPainterPath(); QTest::newRow("all-all-translate-50-0") << QRectF() << QRectF() - << Qt::IgnoreAspectRatio << QMatrix().translate(50, 0); + << Qt::IgnoreAspectRatio << QMatrix().translate(50, 0) << QPainterPath(); QTest::newRow("all-all-translate-0-50") << QRectF() << QRectF() - << Qt::IgnoreAspectRatio << QMatrix().translate(0, 50); + << Qt::IgnoreAspectRatio << QMatrix().translate(0, 50) << QPainterPath(); + QTest::newRow("all-all-untransformed-clip-rect") << QRectF() << QRectF() + << Qt::IgnoreAspectRatio << QMatrix() << clip_rect; + QTest::newRow("all-all-untransformed-clip-ellipse") << QRectF() << QRectF() + << Qt::IgnoreAspectRatio << QMatrix() << clip_ellipse; } void tst_QGraphicsScene::render() @@ -2678,6 +2689,7 @@ void tst_QGraphicsScene::render() QFETCH(QRectF, sourceRect); QFETCH(Qt::AspectRatioMode, aspectRatioMode); QFETCH(QMatrix, matrix); + QFETCH(QPainterPath, clip); QPixmap pix(30, 30); pix.fill(Qt::blue); @@ -2703,6 +2715,7 @@ void tst_QGraphicsScene::render() painter.drawLine(0, 150, 300, 150); painter.drawLine(150, 0, 150, 300); painter.setMatrix(matrix); + if (!clip.isEmpty()) painter.setClipPath(clip); scene.render(&painter, targetRect, sourceRect, aspectRatioMode); painter.end(); -- cgit v0.12