if (pd->devType() == QInternal::Widget)
rpd = static_cast<QWidget *>(pd)->d_func()->redirected(&redirectionOffset);
- if (!rpd)
- rpd = redirected(pd, &redirectionOffset);
if (rpd)
pd = rpd;
Q_DUMMY_COMPARISON_OPERATOR(QPaintDeviceRedirection)
};
-typedef QList<QPaintDeviceRedirection> QPaintDeviceRedirectionList;
-Q_GLOBAL_STATIC(QPaintDeviceRedirectionList, globalRedirections)
-Q_GLOBAL_STATIC(QMutex, globalRedirectionsMutex)
-Q_GLOBAL_STATIC(QAtomicInt, globalRedirectionAtomic)
-
-/*!
- \threadsafe
-
- \obsolete
-
- Please use QWidget::render() instead.
-
- Redirects all paint commands for the given paint \a device, to the
- \a replacement device. The optional point \a offset defines an
- offset within the source device.
-
- The redirection will not be effective until the begin() function
- has been called; make sure to call end() for the given \a
- device's painter (if any) before redirecting. Call
- restoreRedirected() to restore the previous redirection.
-
- \warning Making use of redirections in the QPainter API implies
- that QPainter::begin() and QPaintDevice destructors need to hold
- a mutex for a short period. This can impact performance. Use of
- QWidget::render is strongly encouraged.
-
- \sa redirected(), restoreRedirected()
-*/
-void QPainter::setRedirected(const QPaintDevice *device,
- QPaintDevice *replacement,
- const QPoint &offset)
-{
- Q_ASSERT(device != 0);
-
- bool hadInternalWidgetRedirection = false;
- if (device->devType() == QInternal::Widget) {
- const QWidgetPrivate *widgetPrivate = static_cast<const QWidget *>(device)->d_func();
- // This is the case when the widget is in a paint event.
- if (widgetPrivate->redirectDev) {
- // Remove internal redirection and put it back into the global redirection list.
- QPoint oldOffset;
- QPaintDevice *oldReplacement = widgetPrivate->redirected(&oldOffset);
- const_cast<QWidgetPrivate *>(widgetPrivate)->restoreRedirected();
- setRedirected(device, oldReplacement, oldOffset);
- hadInternalWidgetRedirection = true;
- }
- }
-
- QPoint roffset;
- QPaintDevice *rdev = redirected(replacement, &roffset);
-
- QMutexLocker locker(globalRedirectionsMutex());
- QPaintDeviceRedirectionList *redirections = globalRedirections();
- Q_ASSERT(redirections != 0);
- *redirections += QPaintDeviceRedirection(device, rdev ? rdev : replacement, offset + roffset,
- hadInternalWidgetRedirection ? redirections->size() - 1 : -1);
- globalRedirectionAtomic()->ref();
-}
-
-/*!
- \threadsafe
-
- \obsolete
-
- Using QWidget::render() obsoletes the use of this function.
-
- Restores the previous redirection for the given \a device after a
- call to setRedirected().
-
- \warning Making use of redirections in the QPainter API implies
- that QPainter::begin() and QPaintDevice destructors need to hold
- a mutex for a short period. This can impact performance. Use of
- QWidget::render is strongly encouraged.
-
- \sa redirected()
- */
-void QPainter::restoreRedirected(const QPaintDevice *device)
-{
- Q_ASSERT(device != 0);
- QMutexLocker locker(globalRedirectionsMutex());
- QPaintDeviceRedirectionList *redirections = globalRedirections();
- Q_ASSERT(redirections != 0);
- for (int i = redirections->size()-1; i >= 0; --i) {
- if (redirections->at(i) == device) {
- globalRedirectionAtomic()->deref();
- const int internalWidgetRedirectionIndex = redirections->at(i).internalWidgetRedirectionIndex;
- redirections->removeAt(i);
- // Restore the internal widget redirection, i.e. remove it from the global
- // redirection list and put it back into QWidgetPrivate. The index is only set when
- // someone call QPainter::setRedirected in a widget's paint event and we internally
- // have a redirection set (typically set in QWidgetPrivate::drawWidget).
- if (internalWidgetRedirectionIndex >= 0) {
- Q_ASSERT(internalWidgetRedirectionIndex < redirections->size());
- const QPaintDeviceRedirection &redirectionDevice = redirections->at(internalWidgetRedirectionIndex);
- QWidget *widget = static_cast<QWidget *>(const_cast<QPaintDevice *>(device));
- widget->d_func()->setRedirected(redirectionDevice.replacement, redirectionDevice.offset);
- redirections->removeAt(internalWidgetRedirectionIndex);
- }
- return;
- }
- }
-}
-
-/*!
- \threadsafe
-
- \obsolete
-
- Using QWidget::render() obsoletes the use of this function.
-
- Returns the replacement for given \a device. The optional out
- parameter \a offset returns the offset within the replaced device.
-
- \warning Making use of redirections in the QPainter API implies
- that QPainter::begin() and QPaintDevice destructors need to hold
- a mutex for a short period. This can impact performance. Use of
- QWidget::render is strongly encouraged.
-
- \sa setRedirected(), restoreRedirected()
-*/
-QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset)
-{
- Q_ASSERT(device != 0);
-
- if (device->devType() == QInternal::Widget) {
- const QWidgetPrivate *widgetPrivate = static_cast<const QWidget *>(device)->d_func();
- if (widgetPrivate->redirectDev)
- return widgetPrivate->redirected(offset);
- }
-
- if (!globalRedirectionAtomic() || *globalRedirectionAtomic() == 0)
- return 0;
-
- QMutexLocker locker(globalRedirectionsMutex());
- QPaintDeviceRedirectionList *redirections = globalRedirections();
- Q_ASSERT(redirections != 0);
- for (int i = redirections->size()-1; i >= 0; --i)
- if (redirections->at(i) == device) {
- if (offset)
- *offset = redirections->at(i).offset;
- return redirections->at(i).replacement;
- }
- if (offset)
- *offset = QPoint(0, 0);
- return 0;
-}
-
-
-void qt_painter_removePaintDevice(QPaintDevice *dev)
-{
- if (!globalRedirectionAtomic() || *globalRedirectionAtomic() == 0)
- return;
-
- QMutex *mutex = 0;
- QT_TRY {
- mutex = globalRedirectionsMutex();
- } QT_CATCH(...) {
- // ignore the missing mutex, since we could be called from
- // a destructor, and destructors shall not throw
- }
- QMutexLocker locker(mutex);
- QPaintDeviceRedirectionList *redirections = 0;
- QT_TRY {
- redirections = globalRedirections();
- } QT_CATCH(...) {
- // do nothing - code below is safe with redirections being 0.
- }
- if (redirections) {
- for (int i = 0; i < redirections->size(); ) {
- if(redirections->at(i) == dev || redirections->at(i).replacement == dev)
- redirections->removeAt(i);
- else
- ++i;
- }
- }
-}
-
void qt_format_text(const QFont &fnt, const QRectF &_r,
int tf, const QString& str, QRectF *brect,
int tabstops, int *ta, int tabarraylen,