src/gui/painting/qpainter.cpp
changeset 7 f7bc934e204c
parent 3 41300fa6a67c
child 25 e24348a560a6
--- a/src/gui/painting/qpainter.cpp	Tue Feb 02 00:43:10 2010 +0200
+++ b/src/gui/painting/qpainter.cpp	Wed Mar 31 11:06:36 2010 +0300
@@ -1,6 +1,6 @@
 /****************************************************************************
 **
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 ** All rights reserved.
 ** Contact: Nokia Corporation (qt-info@nokia.com)
 **
@@ -708,13 +708,14 @@
         bool penTextureAlpha = false;
         if (penBrush.style() == Qt::TexturePattern)
             penTextureAlpha = qHasPixmapTexture(penBrush)
-                              ? penBrush.texture().hasAlpha()
+                              ? (penBrush.texture().depth() > 1) && penBrush.texture().hasAlpha()
                               : penBrush.textureImage().hasAlphaChannel();
         bool brushTextureAlpha = false;
-        if (s->brush.style() == Qt::TexturePattern)
+        if (s->brush.style() == Qt::TexturePattern) {
             brushTextureAlpha = qHasPixmapTexture(s->brush)
-                                ? s->brush.texture().hasAlpha()
+                                ? (s->brush.texture().depth() > 1) && s->brush.texture().hasAlpha()
                                 : s->brush.textureImage().hasAlphaChannel();
+        }
         if (((penBrush.style() == Qt::TexturePattern && penTextureAlpha)
              || (s->brush.style() == Qt::TexturePattern && brushTextureAlpha))
             && !engine->hasFeature(QPaintEngine::MaskedBrush))
@@ -1329,7 +1330,7 @@
     of composition modes, brushes, clipping, transformation, etc, is
     close to an impossible task because of the number of
     permutations. As a compromise we have selected a subset of the
-    QPainter API and backends, were performance is guaranteed to be as
+    QPainter API and backends, where performance is guaranteed to be as
     good as we can sensibly get it for the given combination of
     hardware and software.
 
@@ -1374,9 +1375,6 @@
     opacity with non-smooth transformation mode
     (\c QPainter::SmoothPixmapTransform not enabled as a render hint).
 
-    \o Text drawing with regular font sizes with simple
-    transformations with solid colors using no or 8-bit antialiasing.
-
     \o Rectangle fills with solid color, two-color linear gradients
     and simple transforms.
 
@@ -1984,12 +1982,30 @@
 /*!
     \since 4.6
 
-    Flushes the painting pipeline and prepares for the user issuing
-    commands directly to the underlying graphics context. Must be
-    followed by a call to endNativePainting().
-
-    Here is an example that shows intermixing of painter commands
-    and raw OpenGL commands:
+    Flushes the painting pipeline and prepares for the user issuing commands
+    directly to the underlying graphics context. Must be followed by a call to
+    endNativePainting().
+
+    Note that only the states the underlying paint engine changes will be reset
+    to their respective default states. The states we reset may change from
+    release to release. The following states are currently reset in the OpenGL
+    2 engine:
+
+    \list
+    \i blending is disabled
+    \i the depth, stencil and scissor tests are disabled
+    \i the active texture unit is reset to 0
+    \i the depth mask, depth function and the clear depth are reset to their
+    default values
+    \i the stencil mask, stencil operation and stencil function are reset to
+    their default values
+     \i the current color is reset to solid white
+    \endlist
+
+    If, for example, the OpenGL polygon mode is changed by the user inside a
+    beginNativePaint()/endNativePainting() block, it will not be reset to the
+    default state by endNativePainting(). Here is an example that shows
+    intermixing of painter commands and raw OpenGL commands:
 
     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 21
 
@@ -2010,9 +2026,9 @@
 /*!
     \since 4.6
 
-    Restores the painter after manually issuing native painting commands.
-    Lets the painter restore any native state that it relies on before
-    calling any other painter commands.
+    Restores the painter after manually issuing native painting commands. Lets
+    the painter restore any native state that it relies on before calling any
+    other painter commands.
 
     \sa beginNativePainting()
 */
@@ -7380,10 +7396,15 @@
 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.
@@ -7393,9 +7414,10 @@
     device's painter (if any) before redirecting. Call
     restoreRedirected() to restore the previous redirection.
 
-    In general, you'll probably find that calling
-    QPixmap::grabWidget() or QPixmap::grabWindow() is an easier
-    solution.
+    \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()
 */
@@ -7427,14 +7449,24 @@
     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)
@@ -7445,6 +7477,7 @@
     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
@@ -7466,9 +7499,18 @@
 /*!
     \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)
@@ -7481,6 +7523,9 @@
             return widgetPrivate->redirected(offset);
     }
 
+    if (!globalRedirectionAtomic() || *globalRedirectionAtomic() == 0)
+        return 0;
+
     QMutexLocker locker(globalRedirectionsMutex());
     QPaintDeviceRedirectionList *redirections = globalRedirections();
     Q_ASSERT(redirections != 0);
@@ -7498,6 +7543,9 @@
 
 void qt_painter_removePaintDevice(QPaintDevice *dev)
 {
+    if (!globalRedirectionAtomic() || *globalRedirectionAtomic() == 0)
+        return;
+
     QMutex *mutex = 0;
     QT_TRY {
         mutex = globalRedirectionsMutex();