src/gui/painting/qpainter.cpp
branchRCL_3
changeset 5 d3bac044e0f0
parent 4 3b1da2848fc7
child 8 3f74d0d4af4c
equal deleted inserted replaced
4:3b1da2848fc7 5:d3bac044e0f0
  7380 };
  7380 };
  7381 
  7381 
  7382 typedef QList<QPaintDeviceRedirection> QPaintDeviceRedirectionList;
  7382 typedef QList<QPaintDeviceRedirection> QPaintDeviceRedirectionList;
  7383 Q_GLOBAL_STATIC(QPaintDeviceRedirectionList, globalRedirections)
  7383 Q_GLOBAL_STATIC(QPaintDeviceRedirectionList, globalRedirections)
  7384 Q_GLOBAL_STATIC(QMutex, globalRedirectionsMutex)
  7384 Q_GLOBAL_STATIC(QMutex, globalRedirectionsMutex)
       
  7385 Q_GLOBAL_STATIC(QAtomicInt, globalRedirectionAtomic)
  7385 
  7386 
  7386 /*!
  7387 /*!
  7387     \threadsafe
  7388     \threadsafe
       
  7389 
       
  7390     \obsolete
       
  7391 
       
  7392     Please use QWidget::render() instead.
  7388 
  7393 
  7389     Redirects all paint commands for the given paint \a device, to the
  7394     Redirects all paint commands for the given paint \a device, to the
  7390     \a replacement device. The optional point \a offset defines an
  7395     \a replacement device. The optional point \a offset defines an
  7391     offset within the source device.
  7396     offset within the source device.
  7392 
  7397 
  7393     The redirection will not be effective until the begin() function
  7398     The redirection will not be effective until the begin() function
  7394     has been called; make sure to call end() for the given \a
  7399     has been called; make sure to call end() for the given \a
  7395     device's painter (if any) before redirecting. Call
  7400     device's painter (if any) before redirecting. Call
  7396     restoreRedirected() to restore the previous redirection.
  7401     restoreRedirected() to restore the previous redirection.
  7397 
  7402 
  7398     In general, you'll probably find that calling
  7403     \warning Making use of redirections in the QPainter API implies
  7399     QPixmap::grabWidget() or QPixmap::grabWindow() is an easier
  7404     that QPainter::begin() and QPaintDevice destructors need to hold
  7400     solution.
  7405     a mutex for a short period. This can impact performance. Use of
       
  7406     QWidget::render is strongly encouraged.
  7401 
  7407 
  7402     \sa redirected(), restoreRedirected()
  7408     \sa redirected(), restoreRedirected()
  7403 */
  7409 */
  7404 void QPainter::setRedirected(const QPaintDevice *device,
  7410 void QPainter::setRedirected(const QPaintDevice *device,
  7405                              QPaintDevice *replacement,
  7411                              QPaintDevice *replacement,
  7427     QMutexLocker locker(globalRedirectionsMutex());
  7433     QMutexLocker locker(globalRedirectionsMutex());
  7428     QPaintDeviceRedirectionList *redirections = globalRedirections();
  7434     QPaintDeviceRedirectionList *redirections = globalRedirections();
  7429     Q_ASSERT(redirections != 0);
  7435     Q_ASSERT(redirections != 0);
  7430     *redirections += QPaintDeviceRedirection(device, rdev ? rdev : replacement, offset + roffset,
  7436     *redirections += QPaintDeviceRedirection(device, rdev ? rdev : replacement, offset + roffset,
  7431                                              hadInternalWidgetRedirection ? redirections->size() - 1 : -1);
  7437                                              hadInternalWidgetRedirection ? redirections->size() - 1 : -1);
       
  7438     globalRedirectionAtomic()->ref();
  7432 }
  7439 }
  7433 
  7440 
  7434 /*!
  7441 /*!
  7435     \threadsafe
  7442     \threadsafe
       
  7443 
       
  7444     \obsolete
       
  7445 
       
  7446     Using QWidget::render() obsoletes the use of this function.
  7436 
  7447 
  7437     Restores the previous redirection for the given \a device after a
  7448     Restores the previous redirection for the given \a device after a
  7438     call to setRedirected().
  7449     call to setRedirected().
       
  7450 
       
  7451     \warning Making use of redirections in the QPainter API implies
       
  7452     that QPainter::begin() and QPaintDevice destructors need to hold
       
  7453     a mutex for a short period. This can impact performance. Use of
       
  7454     QWidget::render is strongly encouraged.
  7439 
  7455 
  7440     \sa redirected()
  7456     \sa redirected()
  7441  */
  7457  */
  7442 void QPainter::restoreRedirected(const QPaintDevice *device)
  7458 void QPainter::restoreRedirected(const QPaintDevice *device)
  7443 {
  7459 {
  7445     QMutexLocker locker(globalRedirectionsMutex());
  7461     QMutexLocker locker(globalRedirectionsMutex());
  7446     QPaintDeviceRedirectionList *redirections = globalRedirections();
  7462     QPaintDeviceRedirectionList *redirections = globalRedirections();
  7447     Q_ASSERT(redirections != 0);
  7463     Q_ASSERT(redirections != 0);
  7448     for (int i = redirections->size()-1; i >= 0; --i) {
  7464     for (int i = redirections->size()-1; i >= 0; --i) {
  7449         if (redirections->at(i) == device) {
  7465         if (redirections->at(i) == device) {
       
  7466             globalRedirectionAtomic()->deref();
  7450             const int internalWidgetRedirectionIndex = redirections->at(i).internalWidgetRedirectionIndex;
  7467             const int internalWidgetRedirectionIndex = redirections->at(i).internalWidgetRedirectionIndex;
  7451             redirections->removeAt(i);
  7468             redirections->removeAt(i);
  7452             // Restore the internal widget redirection, i.e. remove it from the global
  7469             // Restore the internal widget redirection, i.e. remove it from the global
  7453             // redirection list and put it back into QWidgetPrivate. The index is only set when
  7470             // redirection list and put it back into QWidgetPrivate. The index is only set when
  7454             // someone call QPainter::setRedirected in a widget's paint event and we internally
  7471             // someone call QPainter::setRedirected in a widget's paint event and we internally
  7466 }
  7483 }
  7467 
  7484 
  7468 /*!
  7485 /*!
  7469     \threadsafe
  7486     \threadsafe
  7470 
  7487 
       
  7488     \obsolete
       
  7489 
       
  7490     Using QWidget::render() obsoletes the use of this function.
       
  7491 
  7471     Returns the replacement for given \a device. The optional out
  7492     Returns the replacement for given \a device. The optional out
  7472     parameter \a offset returns the offset within the replaced device.
  7493     parameter \a offset returns the offset within the replaced device.
       
  7494 
       
  7495     \warning Making use of redirections in the QPainter API implies
       
  7496     that QPainter::begin() and QPaintDevice destructors need to hold
       
  7497     a mutex for a short period. This can impact performance. Use of
       
  7498     QWidget::render is strongly encouraged.
  7473 
  7499 
  7474     \sa setRedirected(), restoreRedirected()
  7500     \sa setRedirected(), restoreRedirected()
  7475 */
  7501 */
  7476 QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset)
  7502 QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset)
  7477 {
  7503 {
  7480     if (device->devType() == QInternal::Widget) {
  7506     if (device->devType() == QInternal::Widget) {
  7481         const QWidgetPrivate *widgetPrivate = static_cast<const QWidget *>(device)->d_func();
  7507         const QWidgetPrivate *widgetPrivate = static_cast<const QWidget *>(device)->d_func();
  7482         if (widgetPrivate->redirectDev)
  7508         if (widgetPrivate->redirectDev)
  7483             return widgetPrivate->redirected(offset);
  7509             return widgetPrivate->redirected(offset);
  7484     }
  7510     }
       
  7511 
       
  7512     if (*globalRedirectionAtomic() == 0)
       
  7513         return 0;
  7485 
  7514 
  7486     QMutexLocker locker(globalRedirectionsMutex());
  7515     QMutexLocker locker(globalRedirectionsMutex());
  7487     QPaintDeviceRedirectionList *redirections = globalRedirections();
  7516     QPaintDeviceRedirectionList *redirections = globalRedirections();
  7488     Q_ASSERT(redirections != 0);
  7517     Q_ASSERT(redirections != 0);
  7489     for (int i = redirections->size()-1; i >= 0; --i)
  7518     for (int i = redirections->size()-1; i >= 0; --i)
  7498 }
  7527 }
  7499 
  7528 
  7500 
  7529 
  7501 void qt_painter_removePaintDevice(QPaintDevice *dev)
  7530 void qt_painter_removePaintDevice(QPaintDevice *dev)
  7502 {
  7531 {
       
  7532     if (*globalRedirectionAtomic() == 0)
       
  7533         return;
       
  7534 
  7503     QMutex *mutex = 0;
  7535     QMutex *mutex = 0;
  7504     QT_TRY {
  7536     QT_TRY {
  7505         mutex = globalRedirectionsMutex();
  7537         mutex = globalRedirectionsMutex();
  7506     } QT_CATCH(...) {
  7538     } QT_CATCH(...) {
  7507         // ignore the missing mutex, since we could be called from
  7539         // ignore the missing mutex, since we could be called from