diff options
author | Martin Smith <msmith@trolltech.com> | 2010-02-23 08:54:52 (GMT) |
---|---|---|
committer | Martin Smith <msmith@trolltech.com> | 2010-02-23 08:54:52 (GMT) |
commit | 6e9015a71645fa5da09cbd6240b45e1472a2c1ea (patch) | |
tree | bf7d1da9a3440926ab9fdc56b9691438bd0db62d /src | |
parent | 1ef21425463204ff60defb9ca97813ff07db2149 (diff) | |
parent | 58d6be490b6ede5ad339ca4c938c59418f116b2a (diff) | |
download | Qt-6e9015a71645fa5da09cbd6240b45e1472a2c1ea.zip Qt-6e9015a71645fa5da09cbd6240b45e1472a2c1ea.tar.gz Qt-6e9015a71645fa5da09cbd6240b45e1472a2c1ea.tar.bz2 |
Merge branch '4.6' of git@scm.dev.nokia.troll.no:qt/oslo-staging-1 into 4.6
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/kernel/qapplication_win.cpp | 5 | ||||
-rw-r--r-- | src/gui/styles/qstylesheetstyle.cpp | 7 | ||||
-rw-r--r-- | src/multimedia/audio/qaudioinput.cpp | 74 | ||||
-rw-r--r-- | src/multimedia/audio/qaudioinput_alsa_p.cpp | 121 | ||||
-rw-r--r-- | src/multimedia/audio/qaudiooutput.cpp | 78 | ||||
-rw-r--r-- | src/multimedia/audio/qaudiooutput_alsa_p.cpp | 64 | ||||
-rw-r--r-- | src/openvg/qpaintengine_vg.cpp | 124 |
7 files changed, 212 insertions, 261 deletions
diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index 0a4869b..aac834d 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -1905,8 +1905,13 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam break; if (!msg.wParam) { +#ifdef Q_WS_WINCE + // On Windows CE, lParam parameter is a constant, not a char pointer. + if (msg.lParam == INI_INTL) { +#else QString area = QString::fromWCharArray((wchar_t*)msg.lParam); if (area == QLatin1String("intl")) { +#endif QLocalePrivate::updateSystemPrivate(); if (!widget->testAttribute(Qt::WA_SetLocale)) widget->dptr()->setLocale_helper(QLocale(), true); diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp index b36294a..c550938 100644 --- a/src/gui/styles/qstylesheetstyle.cpp +++ b/src/gui/styles/qstylesheetstyle.cpp @@ -5743,6 +5743,13 @@ QRect QStyleSheetStyle::subElementRect(SubElement se, const QStyleOption *opt, c return positionRect(w, subRule, subRule2, pe, opt->rect, opt->direction); } +#ifndef QT_NO_TOOLBAR + case SE_ToolBarHandle: + if (hasStyleRule(w, PseudoElement_ToolBarHandle)) + return ParentStyle::subElementRect(se, opt, w); + break; +#endif //QT_NO_TOOLBAR + default: break; } diff --git a/src/multimedia/audio/qaudioinput.cpp b/src/multimedia/audio/qaudioinput.cpp index 45cafc1..fd892dd 100644 --- a/src/multimedia/audio/qaudioinput.cpp +++ b/src/multimedia/audio/qaudioinput.cpp @@ -190,18 +190,18 @@ QAudioInput::~QAudioInput() Passing a QIODevice allows the data to be transfered without any extra code. All that is required is to open the QIODevice. + If able to successfully get audio data from the systems audio device the + state() is set to either QAudio::ActiveState or QAudio::IdleState, + error() is set to QAudio::NoError and the stateChanged() signal is emitted. + + If a problem occurs during this process the error() is set to QAudio::OpenError, + state() is set to QAudio::StoppedState and stateChanged() signal is emitted. + \sa QIODevice */ void QAudioInput::start(QIODevice* device) { - /* - -If currently not StoppedState, stop - -If previous start was push mode, delete internal QIODevice. - -open audio input. - If ok, NoError and ActiveState, else OpenError and StoppedState. - -emit stateChanged() - */ d->start(device); } @@ -210,19 +210,18 @@ void QAudioInput::start(QIODevice* device) transfer. This QIODevice can be used to read() audio data directly. + If able to access the systems audio device the state() is set to + QAudio::IdleState, error() is set to QAudio::NoError + and the stateChanged() signal is emitted. + + If a problem occurs during this process the error() is set to QAudio::OpenError, + state() is set to QAudio::StoppedState and stateChanged() signal is emitted. + \sa QIODevice */ QIODevice* QAudioInput::start() { - /* - -If currently not StoppedState, stop - -If no internal QIODevice, create one. - -open audio input. - -If ok, NoError and IdleState, else OpenError and StoppedState - -emit stateChanged() - -return internal QIODevice - */ return d->start(0); } @@ -236,17 +235,14 @@ QAudioFormat QAudioInput::format() const } /*! - Stops the audio input. + Stops the audio input, detaching from the system resource. + + Sets error() to QAudio::NoError, state() to QAudio::StoppedState and + emit stateChanged() signal. */ void QAudioInput::stop() { - /* - -If StoppedState, return - -set to StoppedState - -detach from audio device - -emit stateChanged() - */ d->stop(); } @@ -256,42 +252,32 @@ void QAudioInput::stop() void QAudioInput::reset() { - /* - -drop all buffered audio, set buffers to zero. - -call stop() - */ d->reset(); } /*! Stops processing audio data, preserving buffered audio data. + + Sets error() to QAudio::NoError, state() to QAudio::SuspendedState and + emit stateChanged() signal. */ void QAudioInput::suspend() { - /* - -If not ActiveState|IdleState, return - -stop processing audio, saving all buffered audio data - -set NoError and SuspendedState - -emit stateChanged() - */ d->suspend(); } /*! Resumes processing audio data after a suspend(). + + Sets error() to QAudio::NoError. + Sets state() to QAudio::ActiveState if you previously called start(QIODevice*). + Sets state() to QAudio::IdleState if you previously called start(). + emits stateChanged() signal. */ void QAudioInput::resume() { - /* - -If SuspendedState, return - -resume audio - -(PULL MODE): set ActiveState, NoError - -(PUSH MODE): set IdleState, NoError - -kick start audio if needed - -emit stateChanged() - */ d->resume(); } @@ -327,6 +313,9 @@ int QAudioInput::bufferSize() const /*! Returns the amount of audio data available to read in bytes. + + NOTE: returned value is only valid while in QAudio::ActiveState or QAudio::IdleState + state, otherwise returns zero. */ int QAudioInput::bytesReady() const @@ -352,7 +341,10 @@ int QAudioInput::periodSize() const /*! Sets the interval for notify() signal to be emitted. This is based on the \a ms of audio data processed - not on actual real-time. The resolution of the timer is platform specific. + not on actual real-time. + The minimum resolution of the timer is platform specific and values + should be checked with notifyInterval() to confirm actual value + being used. */ void QAudioInput::setNotifyInterval(int ms) diff --git a/src/multimedia/audio/qaudioinput_alsa_p.cpp b/src/multimedia/audio/qaudioinput_alsa_p.cpp index 26e46b3..6010f3c 100644 --- a/src/multimedia/audio/qaudioinput_alsa_p.cpp +++ b/src/multimedia/audio/qaudioinput_alsa_p.cpp @@ -217,9 +217,11 @@ QIODevice* QAudioInputPrivate::start(QIODevice* device) //set to pull mode pullMode = true; audioSource = device; + deviceState = QAudio::ActiveState; } else { //set to push mode pullMode = false; + deviceState = QAudio::IdleState; audioSource = new InputPrivate(this); audioSource->open(QIODevice::ReadOnly | QIODevice::Unbuffered); } @@ -413,7 +415,6 @@ bool QAudioInputPrivate::open() timer->start(period_time*chunks/2000); errorState = QAudio::NoError; - deviceState = QAudio::ActiveState; totalTimeValue = 0; @@ -439,7 +440,7 @@ int QAudioInputPrivate::bytesReady() const if(resuming) return period_size; - if(deviceState != QAudio::ActiveState) + if(deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState) return 0; int frames = snd_pcm_avail_update(handle); if((int)frames > (int)buffer_frames) @@ -450,8 +451,8 @@ int QAudioInputPrivate::bytesReady() const qint64 QAudioInputPrivate::read(char* data, qint64 len) { - Q_UNUSED(data) Q_UNUSED(len) + // Read in some audio data and write it to QIODevice, pull mode if ( !handle ) return 0; @@ -468,7 +469,7 @@ qint64 QAudioInputPrivate::read(char* data, qint64 len) if (readFrames >= 0) { err = snd_pcm_frames_to_bytes(handle, readFrames); #ifdef DEBUG_AUDIO - qDebug()<<QString::fromLatin1("PULL: read in bytes = %1 (frames=%2)").arg(err).arg(readFrames).toLatin1().constData(); + qDebug()<<QString::fromLatin1("read in bytes = %1 (frames=%2)").arg(err).arg(readFrames).toLatin1().constData(); #endif break; } else if((readFrames == -EAGAIN) || (readFrames == -EINTR)) { @@ -489,28 +490,46 @@ qint64 QAudioInputPrivate::read(char* data, qint64 len) if(err > 0) { // got some send it onward #ifdef DEBUG_AUDIO - qDebug()<<"PULL: frames to write to QIODevice = "<< + qDebug()<<"frames to write to QIODevice = "<< snd_pcm_bytes_to_frames( handle, (int)err )<<" ("<<err<<") bytes"; #endif - if(deviceState != QAudio::ActiveState) + if(deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState) return 0; + if (pullMode) { + qint64 l = audioSource->write(audioBuffer,err); + if(l < 0) { + close(); + errorState = QAudio::IOError; + deviceState = QAudio::StoppedState; + emit stateChanged(deviceState); + } else if(l == 0) { + if (deviceState != QAudio::IdleState) { + errorState = QAudio::NoError; + deviceState = QAudio::IdleState; + emit stateChanged(deviceState); + } + } else { + totalTimeValue += err; + resuming = false; + if (deviceState != QAudio::ActiveState) { + errorState = QAudio::NoError; + deviceState = QAudio::ActiveState; + emit stateChanged(deviceState); + } + } + return l; - qint64 l = audioSource->write(audioBuffer,err); - if(l < 0) { - close(); - errorState = QAudio::IOError; - deviceState = QAudio::StoppedState; - emit stateChanged(deviceState); - } else if(l == 0) { - errorState = QAudio::NoError; - deviceState = QAudio::IdleState; } else { - totalTimeValue += snd_pcm_bytes_to_frames(handle, err)*1000000/settings.frequency(); + memcpy(data,audioBuffer,err); + totalTimeValue += err; resuming = false; - errorState = QAudio::NoError; - deviceState = QAudio::ActiveState; + if (deviceState != QAudio::ActiveState) { + errorState = QAudio::NoError; + deviceState = QAudio::ActiveState; + emit stateChanged(deviceState); + } + return err; } - return l; } return 0; } @@ -569,7 +588,7 @@ int QAudioInputPrivate::notifyInterval() const qint64 QAudioInputPrivate::processedUSecs() const { - return totalTimeValue; + return qint64(1000000) * totalTimeValue / settings.frequency(); } void QAudioInputPrivate::suspend() @@ -617,34 +636,10 @@ bool QAudioInputPrivate::deviceReady() qint64 QAudioInputPrivate::elapsedUSecs() const { - if(!handle) - return 0; - if (deviceState == QAudio::StoppedState) return 0; -#if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14) - snd_pcm_status_t* status; - snd_pcm_status_alloca(&status); - - snd_timestamp_t t1,t2; - if( snd_pcm_status(handle, status) >= 0) { - snd_pcm_status_get_tstamp(status,&t1); - snd_pcm_status_get_trigger_tstamp(status,&t2); - t1.tv_sec-=t2.tv_sec; - - signed long l = (signed long)t1.tv_usec - (signed long)t2.tv_usec; - if(l < 0) { - t1.tv_sec--; - l = -l; - l %= 1000000; - } - return ((t1.tv_sec * 1000000)+l); - } else - return 0; -#else return clockStamp.elapsed()*1000; -#endif } void QAudioInputPrivate::reset() @@ -670,43 +665,7 @@ InputPrivate::~InputPrivate() qint64 InputPrivate::readData( char* data, qint64 len) { - // push mode, user read() called - if((audioDevice->state() != QAudio::ActiveState) && !audioDevice->resuming) - return 0; - - int readFrames; - int count=0, err = 0; - - while(count < 5) { - int frames = snd_pcm_bytes_to_frames(audioDevice->handle, len); - readFrames = snd_pcm_readi(audioDevice->handle, data, frames); - if (readFrames >= 0) { - err = snd_pcm_frames_to_bytes(audioDevice->handle, readFrames); -#ifdef DEBUG_AUDIO - qDebug()<<QString::fromLatin1("PUSH: read in bytes = %1 (frames=%2)").arg(err).arg(readFrames).toLatin1().constData(); -#endif - break; - } else if((readFrames == -EAGAIN) || (readFrames == -EINTR)) { - audioDevice->errorState = QAudio::IOError; - err = 0; - break; - } else { - if(readFrames == -EPIPE) { - audioDevice->errorState = QAudio::UnderrunError; - err = snd_pcm_prepare(audioDevice->handle); - } else if(readFrames == -ESTRPIPE) { - err = snd_pcm_prepare(audioDevice->handle); - } - if(err != 0) break; - } - count++; - } - if(err > 0 && readFrames > 0) { - audioDevice->totalTimeValue += readFrames*1000/audioDevice->settings.frequency()*1000; - audioDevice->deviceState = QAudio::ActiveState; - return err; - } - return 0; + return audioDevice->read(data,len); } qint64 InputPrivate::writeData(const char* data, qint64 len) diff --git a/src/multimedia/audio/qaudiooutput.cpp b/src/multimedia/audio/qaudiooutput.cpp index afd8a84..b0b5244 100644 --- a/src/multimedia/audio/qaudiooutput.cpp +++ b/src/multimedia/audio/qaudiooutput.cpp @@ -202,18 +202,18 @@ QAudioFormat QAudioOutput::format() const Passing a QIODevice allows the data to be transfered without any extra code. All that is required is to open the QIODevice. + If able to successfully output audio data to the systems audio device the + state() is set to QAudio::ActiveState, error() is set to QAudio::NoError + and the stateChanged() signal is emitted. + + If a problem occurs during this process the error() is set to QAudio::OpenError, + state() is set to QAudio::StoppedState and stateChanged() signal is emitted. + \sa QIODevice */ void QAudioOutput::start(QIODevice* device) { - /* - -If currently not StoppedState, stop. - -If previous start was push mode, delete internal QIODevice. - -open audio output. - -If ok, NoError and ActiveState, else OpenError and StoppedState - -emit stateChanged() - */ d->start(device); } @@ -221,34 +221,30 @@ void QAudioOutput::start(QIODevice* device) Returns a pointer to the QIODevice being used to handle the data transfer. This QIODevice can be used to write() audio data directly. + If able to access the systems audio device the state() is set to + QAudio::IdleState, error() is set to QAudio::NoError + and the stateChanged() signal is emitted. + + If a problem occurs during this process the error() is set to QAudio::OpenError, + state() is set to QAudio::StoppedState and stateChanged() signal is emitted. + \sa QIODevice */ QIODevice* QAudioOutput::start() { - /* - -If currently not StoppedState, stop. - -If no internal QIODevice, create one. - -open audio output. - -If ok, NoError and IdleState, else OpenError and StoppedState - -emit stateChanged() - -return internal QIODevice - */ return d->start(0); } /*! - Stops the audio output. + Stops the audio output, detaching from the system resource. + + Sets error() to QAudio::NoError, state() to QAudio::StoppedState and + emit stateChanged() signal. */ void QAudioOutput::stop() { - /* - -If StoppedState, return - -set to StoppedState - -detach from audio device - -emit stateChanged() - */ d->stop(); } @@ -258,55 +254,44 @@ void QAudioOutput::stop() void QAudioOutput::reset() { - /* - -drop all buffered audio, set buffers to zero. - -call stop() - */ d->reset(); } /*! Stops processing audio data, preserving buffered audio data. + + Sets error() to QAudio::NoError, state() to QAudio::SuspendedState and + emit stateChanged() signal. */ void QAudioOutput::suspend() { - /* - -If not ActiveState|IdleState, return - -stop processing audio, saving all buffered audio data - -set NoError and SuspendedState - -emit stateChanged() - */ d->suspend(); } /*! Resumes processing audio data after a suspend(). + + Sets error() to QAudio::NoError. + Sets state() to QAudio::ActiveState if you previously called start(QIODevice*). + Sets state() to QAudio::IdleState if you previously called start(). + emits stateChanged() signal. */ void QAudioOutput::resume() { - /* - -If SuspendedState, return - -resume audio - -(PULL MODE): set ActiveState, NoError - -(PUSH MODE): set IdleState, NoError - -kick start audio if needed - -emit stateChanged() - */ d->resume(); } /*! Returns the free space available in bytes in the audio buffer. + + NOTE: returned value is only valid while in QAudio::ActiveState or QAudio::IdleState + state, otherwise returns zero. */ int QAudioOutput::bytesFree() const { - /* - -If not ActiveState|IdleState, return 0 - -return space available in audio buffer in bytes - */ return d->bytesFree(); } @@ -353,7 +338,10 @@ int QAudioOutput::bufferSize() const /*! Sets the interval for notify() signal to be emitted. This is based on the \a ms of audio data processed - not on actual real-time. The resolution of the timer is platform specific. + not on actual real-time. + The minimum resolution of the timer is platform specific and values + should be checked with notifyInterval() to confirm actual value + being used. */ void QAudioOutput::setNotifyInterval(int ms) diff --git a/src/multimedia/audio/qaudiooutput_alsa_p.cpp b/src/multimedia/audio/qaudiooutput_alsa_p.cpp index 7b89cef..b127103 100644 --- a/src/multimedia/audio/qaudiooutput_alsa_p.cpp +++ b/src/multimedia/audio/qaudiooutput_alsa_p.cpp @@ -259,6 +259,7 @@ void QAudioOutputPrivate::stop() { if(deviceState == QAudio::StoppedState) return; + errorState = QAudio::NoError; deviceState = QAudio::StoppedState; close(); emit stateChanged(deviceState); @@ -494,10 +495,13 @@ qint64 QAudioOutputPrivate::write( const char *data, qint64 len ) err = snd_pcm_writei( handle, data, frames ); } if(err > 0) { - totalTimeValue += err*1000000/settings.frequency(); + totalTimeValue += err; resuming = false; errorState = QAudio::NoError; - deviceState = QAudio::ActiveState; + if (deviceState != QAudio::ActiveState) { + deviceState = QAudio::ActiveState; + emit stateChanged(deviceState); + } return snd_pcm_frames_to_bytes( handle, err ); } else err = xrun_recovery(err); @@ -542,7 +546,7 @@ int QAudioOutputPrivate::notifyInterval() const qint64 QAudioOutputPrivate::processedUSecs() const { - return totalTimeValue; + return qint64(1000000) * totalTimeValue / settings.frequency(); } void QAudioOutputPrivate::resume() @@ -562,10 +566,8 @@ void QAudioOutputPrivate::resume() bytesAvailable = (int)snd_pcm_frames_to_bytes(handle, buffer_frames); } resuming = true; - if(pullMode) - deviceState = QAudio::ActiveState; - else - deviceState = QAudio::IdleState; + + deviceState = QAudio::ActiveState; errorState = QAudio::NoError; timer->start(period_time/1000); @@ -637,7 +639,9 @@ bool QAudioOutputPrivate::deviceReady() // Got some data to output if(deviceState != QAudio::ActiveState) return true; - write(audioBuffer,l); + qint64 bytesWritten = write(audioBuffer,l); + if (bytesWritten != l) + audioSource->seek(audioSource->pos()-(l-bytesWritten)); bytesAvailable = bytesFree(); } else if(l == 0) { @@ -645,9 +649,11 @@ bool QAudioOutputPrivate::deviceReady() bytesAvailable = bytesFree(); if(bytesAvailable > snd_pcm_frames_to_bytes(handle, buffer_frames-period_frames)) { // Underrun - errorState = QAudio::UnderrunError; - deviceState = QAudio::IdleState; - emit stateChanged(deviceState); + if (deviceState != QAudio::IdleState) { + errorState = QAudio::UnderrunError; + deviceState = QAudio::IdleState; + emit stateChanged(deviceState); + } } } else if(l < 0) { @@ -655,8 +661,17 @@ bool QAudioOutputPrivate::deviceReady() errorState = QAudio::IOError; emit stateChanged(deviceState); } - } else + } else { bytesAvailable = bytesFree(); + if(bytesAvailable > snd_pcm_frames_to_bytes(handle, buffer_frames-period_frames)) { + // Underrun + if (deviceState != QAudio::IdleState) { + errorState = QAudio::UnderrunError; + deviceState = QAudio::IdleState; + emit stateChanged(deviceState); + } + } + } if(deviceState != QAudio::ActiveState) return true; @@ -671,35 +686,10 @@ bool QAudioOutputPrivate::deviceReady() qint64 QAudioOutputPrivate::elapsedUSecs() const { - if(!handle) - return 0; - if (deviceState == QAudio::StoppedState) return 0; -#if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14) - snd_pcm_status_t* status; - snd_pcm_status_alloca(&status); - - snd_timestamp_t t1,t2; - if( snd_pcm_status(handle, status) >= 0) { - snd_pcm_status_get_tstamp(status,&t1); - snd_pcm_status_get_trigger_tstamp(status,&t2); - t1.tv_sec-=t2.tv_sec; - - signed long l = (signed long)t1.tv_usec - (signed long)t2.tv_usec; - if(l < 0) { - t1.tv_sec--; - l = -l; - l %= 1000000; - } - return ((t1.tv_sec * 1000000)+l); - } else - return 0; -#else return clockStamp.elapsed()*1000; -#endif - return 0; } void QAudioOutputPrivate::reset() diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index da47f06..4192dbb 100644 --- a/src/openvg/qpaintengine_vg.cpp +++ b/src/openvg/qpaintengine_vg.cpp @@ -131,8 +131,9 @@ public: void draw(VGPath path, const QPen& pen, const QBrush& brush, VGint rule = VG_EVEN_ODD); void stroke(VGPath path, const QPen& pen); void fill(VGPath path, const QBrush& brush, VGint rule = VG_EVEN_ODD); - VGPath vectorPathToVGPath(const QVectorPath& path); - VGPath painterPathToVGPath(const QPainterPath& path); + inline void releasePath(VGPath path); + VGPath vectorPathToVGPath(const QVectorPath& path, bool forceNewPath = false); + VGPath painterPathToVGPath(const QPainterPath& path, bool forceNewPath = false); VGPath roundedRectPath(const QRectF &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode); VGPaintType setBrush (VGPaint paint, const QBrush& brush, VGMatrixMode mode, @@ -178,6 +179,8 @@ public: VGPath roundRectPath; // Cached path for quick drawing of rounded rects. #endif + VGPath reusablePath; // Reusable path for vectorPathToVGPath(), etc. + QTransform transform; // Currently active transform. bool simpleTransform; // True if the transform is simple (non-projective). qreal penScale; // Pen scaling factor from "transform". @@ -350,6 +353,8 @@ void QVGPaintEnginePrivate::init() roundRectPath = 0; #endif + reusablePath = 0; + simpleTransform = true; pathTransformSet = false; penScale = 1.0; @@ -446,6 +451,15 @@ void QVGPaintEnginePrivate::initObjects() VG_PATH_CAPABILITY_ALL); vgAppendPathData(linePath, 2, segments, coords); #endif + + // This path can be reused over and over by calling vgClearPath(). + reusablePath = vgCreatePath(VG_PATH_FORMAT_STANDARD, + VG_PATH_DATATYPE_F, + 1.0f, // scale + 0.0f, // bias + 32 + 1, // segmentCapacityHint + 32 * 2, // coordCapacityHint + VG_PATH_CAPABILITY_ALL); } void QVGPaintEnginePrivate::destroy() @@ -465,6 +479,8 @@ void QVGPaintEnginePrivate::destroy() if (roundRectPath) vgDestroyPath(roundRectPath); #endif + if (reusablePath) + vgDestroyPath(reusablePath); #if !defined(QVG_NO_DRAW_GLYPHS) QVGFontCache::Iterator it; @@ -541,19 +557,32 @@ void QVGPaintEnginePrivate::updateTransform(QPaintDevice *pdev) qt_scaleForTransform(transform, &penScale); } -VGPath QVGPaintEnginePrivate::vectorPathToVGPath(const QVectorPath& path) +inline void QVGPaintEnginePrivate::releasePath(VGPath path) +{ + if (path == reusablePath) + vgClearPath(path, VG_PATH_CAPABILITY_ALL); + else + vgDestroyPath(path); +} + +VGPath QVGPaintEnginePrivate::vectorPathToVGPath(const QVectorPath& path, bool forceNewPath) { int count = path.elementCount(); const qreal *points = path.points(); const QPainterPath::ElementType *elements = path.elements(); - VGPath vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD, - VG_PATH_DATATYPE_F, - 1.0f, // scale - 0.0f, // bias - count + 1, // segmentCapacityHint - count * 2, // coordCapacityHint - VG_PATH_CAPABILITY_ALL); + VGPath vgpath; + if (forceNewPath) { + vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD, + VG_PATH_DATATYPE_F, + 1.0f, // scale + 0.0f, // bias + count + 1, // segmentCapacityHint + count * 2, // coordCapacityHint + VG_PATH_CAPABILITY_ALL); + } else { + vgpath = reusablePath; + } // Size is sufficient segments for drawRoundedRect() paths. QVarLengthArray<VGubyte, 20> segments; @@ -725,17 +754,22 @@ VGPath QVGPaintEnginePrivate::vectorPathToVGPath(const QVectorPath& path) return vgpath; } -VGPath QVGPaintEnginePrivate::painterPathToVGPath(const QPainterPath& path) +VGPath QVGPaintEnginePrivate::painterPathToVGPath(const QPainterPath& path, bool forceNewPath) { int count = path.elementCount(); - VGPath vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD, - VG_PATH_DATATYPE_F, - 1.0f, // scale - 0.0f, // bias - count + 1, // segmentCapacityHint - count * 2, // coordCapacityHint - VG_PATH_CAPABILITY_ALL); + VGPath vgpath; + if (forceNewPath) { + vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD, + VG_PATH_DATATYPE_F, + 1.0f, // scale + 0.0f, // bias + count + 1, // segmentCapacityHint + count * 2, // coordCapacityHint + VG_PATH_CAPABILITY_ALL); + } else { + vgpath = reusablePath; + } if (count == 0) return vgpath; @@ -954,13 +988,7 @@ VGPath QVGPaintEnginePrivate::roundedRectPath(const QRectF &rect, qreal xRadius, vgModifyPathCoords(vgpath, 0, 9, pts); } #else - VGPath vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD, - VG_PATH_DATATYPE_F, - 1.0f, // scale - 0.0f, // bias - 10, // segmentCapacityHint - 17 * 2, // coordCapacityHint - VG_PATH_CAPABILITY_ALL); + VGPath vgpath = reusablePath; vgAppendPathData(vgpath, 10, roundedrect_types, pts); #endif @@ -1516,7 +1544,7 @@ void QVGPaintEngine::draw(const QVectorPath &path) d->draw(vgpath, s->pen, s->brush, VG_EVEN_ODD); else d->draw(vgpath, s->pen, s->brush, VG_NON_ZERO); - vgDestroyPath(vgpath); + d->releasePath(vgpath); } void QVGPaintEngine::fill(const QVectorPath &path, const QBrush &brush) @@ -1527,7 +1555,7 @@ void QVGPaintEngine::fill(const QVectorPath &path, const QBrush &brush) d->fill(vgpath, brush, VG_EVEN_ODD); else d->fill(vgpath, brush, VG_NON_ZERO); - vgDestroyPath(vgpath); + d->releasePath(vgpath); } void QVGPaintEngine::stroke(const QVectorPath &path, const QPen &pen) @@ -1535,7 +1563,7 @@ void QVGPaintEngine::stroke(const QVectorPath &path, const QPen &pen) Q_D(QVGPaintEngine); VGPath vgpath = d->vectorPathToVGPath(path); d->stroke(vgpath, pen); - vgDestroyPath(vgpath); + d->releasePath(vgpath); } // Determine if a co-ordinate transform is simple enough to allow @@ -1731,7 +1759,7 @@ void QVGPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op) default: break; } - vgDestroyPath(vgpath); + d->releasePath(vgpath); vgSeti(VG_MASKING, VG_TRUE); d->maskValid = true; @@ -2048,7 +2076,7 @@ void QVGPaintEngine::clip(const QPainterPath &path, Qt::ClipOperation op) default: break; } - vgDestroyPath(vgpath); + d->releasePath(vgpath); vgSeti(VG_MASKING, VG_TRUE); d->maskValid = true; @@ -2487,7 +2515,7 @@ void QVGPaintEngine::drawRoundedRect(const QRectF &rect, qreal xrad, qreal yrad, VGPath vgpath = d->roundedRectPath(rect, xrad, yrad, mode); d->draw(vgpath, s->pen, s->brush); #if defined(QVG_NO_MODIFY_PATH) - vgDestroyPath(vgpath); + d->releasePath(vgpath); #endif } else { QPaintEngineEx::drawRoundedRect(rect, xrad, yrad, mode); @@ -2636,13 +2664,7 @@ void QVGPaintEngine::drawEllipse(const QRectF &r) Q_D(QVGPaintEngine); if (d->simpleTransform) { QVGPainterState *s = state(); - VGPath path = vgCreatePath(VG_PATH_FORMAT_STANDARD, - VG_PATH_DATATYPE_F, - 1.0f, // scale - 0.0f, // bias - 4, // segmentCapacityHint - 12, // coordCapacityHint - VG_PATH_CAPABILITY_ALL); + VGPath path = d->reusablePath; static VGubyte segments[4] = { VG_MOVE_TO_ABS, VG_SCCWARC_TO_REL, @@ -2666,7 +2688,7 @@ void QVGPaintEngine::drawEllipse(const QRectF &r) coords[11] = 0.0f; vgAppendPathData(path, 4, segments, coords); d->draw(path, s->pen, s->brush); - vgDestroyPath(path); + d->releasePath(path); } else { // The projective transform version of an ellipse is difficult. // Generate a QVectorPath containing cubic curves and transform that. @@ -2690,7 +2712,7 @@ void QVGPaintEngine::drawPath(const QPainterPath &path) d->draw(vgpath, s->pen, s->brush, VG_EVEN_ODD); else d->draw(vgpath, s->pen, s->brush, VG_NON_ZERO); - vgDestroyPath(vgpath); + d->releasePath(vgpath); } void QVGPaintEngine::drawPoints(const QPointF *points, int pointCount) @@ -2765,13 +2787,7 @@ void QVGPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonD { Q_D(QVGPaintEngine); QVGPainterState *s = state(); - VGPath path = vgCreatePath(VG_PATH_FORMAT_STANDARD, - VG_PATH_DATATYPE_F, - 1.0f, // scale - 0.0f, // bias - pointCount + 1, // segmentCapacityHint - pointCount * 2, // coordCapacityHint - VG_PATH_CAPABILITY_ALL); + VGPath path = d->reusablePath; QVarLengthArray<VGfloat, 16> coords; QVarLengthArray<VGubyte, 10> segments; for (int i = 0; i < pointCount; ++i, ++points) { @@ -2805,20 +2821,14 @@ void QVGPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonD d->draw(path, s->pen, s->brush, VG_EVEN_ODD); break; } - vgDestroyPath(path); + d->releasePath(path); } void QVGPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode) { Q_D(QVGPaintEngine); QVGPainterState *s = state(); - VGPath path = vgCreatePath(VG_PATH_FORMAT_STANDARD, - VG_PATH_DATATYPE_F, - 1.0f, // scale - 0.0f, // bias - pointCount + 1, // segmentCapacityHint - pointCount * 2, // coordCapacityHint - VG_PATH_CAPABILITY_ALL); + VGPath path = d->reusablePath; QVarLengthArray<VGfloat, 16> coords; QVarLengthArray<VGubyte, 10> segments; for (int i = 0; i < pointCount; ++i, ++points) { @@ -2852,7 +2862,7 @@ void QVGPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDr d->draw(path, s->pen, s->brush, VG_EVEN_ODD); break; } - vgDestroyPath(path); + d->releasePath(path); } void QVGPaintEnginePrivate::setImageOptions() @@ -3251,7 +3261,7 @@ void QVGFontGlyphCache::cacheGlyphs ti.fontEngine->getUnscaledGlyph(glyph, &path, &metrics); VGPath vgPath; if (!path.isEmpty()) { - vgPath = d->painterPathToVGPath(path); + vgPath = d->painterPathToVGPath(path, true); } else { // Probably a "space" character with no visible outline. vgPath = VG_INVALID_HANDLE; |