QWindowsXPStylePrivate Class Reference

Inheritance diagram for QWindowsXPStylePrivate:

Inheritance graph
[legend]
Collaboration diagram for QWindowsXPStylePrivate:

Collaboration graph
[legend]
List of all members.

Detailed Description

Definition at line 317 of file qwindowsxpstyle.cpp.

Public Member Functions

 QWindowsXPStylePrivate ()
 ~QWindowsXPStylePrivate ()
void init (bool force=false)
void cleanup (bool force=false)
void cleanupHandleMap ()
const QPixmaptabBody (QWidget *widget)
HBITMAP buffer (int w=0, int h=0)
HDC bufferHDC ()
bool isTransparent (XPThemeData &themeData)
QRegion region (XPThemeData &themeData)
void setTransparency (QWidget *widget, XPThemeData &themeData)
void drawBackground (XPThemeData &themeData)
void drawBackgroundThruNativeBuffer (XPThemeData &themeData)
void drawBackgroundDirectly (XPThemeData &themeData)
bool hasAnyData (const QRect &rect)
bool hasAlphaChannel (const QRect &rect)
bool fixAlphaChannel (const QRect &rect)
bool swapAlphaChannel (const QRect &rect)

Static Public Member Functions

static HWND winId (const QWidget *widget)
static bool resolveSymbols ()
static bool useXP (bool update=false)

Public Attributes

QRgb groupBoxTextColor
QRgb groupBoxTextColorDisabled
QRgb sliderTickColor
bool hasInitColors
QIcon dockFloat
QIcon dockClose

Static Public Attributes

static QMap< QString, HTHEME > * handleMap

Private Attributes

QHash< ThemeMapKey, ThemeMapDataalphaCache
HDC bufferDC
HBITMAP bufferBitmap
HBITMAP nullBitmap
uchar * bufferPixels
int bufferW
int bufferH

Static Private Attributes

static QAtomic ref
static bool use_xp
static QWidgetlimboWidget
static QPixmaptabbody


Constructor & Destructor Documentation

QWindowsXPStylePrivate::QWindowsXPStylePrivate (  )  [inline]

Definition at line 321 of file qwindowsxpstyle.cpp.

References init().

00322         : QWindowsStylePrivate(), hasInitColors(false), bufferDC(0), bufferBitmap(0), nullBitmap(0),
00323           bufferPixels(0), bufferW(0), bufferH(0)
00324     { init(); }

Here is the call graph for this function:

QWindowsXPStylePrivate::~QWindowsXPStylePrivate (  )  [inline]

Definition at line 326 of file qwindowsxpstyle.cpp.

References cleanup().

00327     { cleanup(); }

Here is the call graph for this function:


Member Function Documentation

HWND QWindowsXPStylePrivate::winId ( const QWidget widget  )  [static]

Definition at line 534 of file qwindowsxpstyle.cpp.

References limboWidget, QObject::setObjectName(), QWidget::testAttribute(), Qt::WA_WState_Created, and QWidget::winId().

Referenced by XPThemeData::handle(), setTransparency(), and QWindowsXPStyle::subElementRect().

00535 {
00536     if (widget && widget->testAttribute(Qt::WA_WState_Created)) {
00537         return widget->winId();
00538     }
00539     if (!limboWidget) {
00540         limboWidget = new QWidget(0);
00541         limboWidget->setObjectName(QLatin1String("xp_limbo_widget"));
00542     }
00543 
00544     return limboWidget->winId();
00545 }

Here is the call graph for this function:

void QWindowsXPStylePrivate::init ( bool  force = false  ) 

Definition at line 475 of file qwindowsxpstyle.cpp.

References ref, QBasicAtomic::ref(), and useXP().

Referenced by QWindowsXPStylePrivate().

00476 {
00477     if (ref.ref() && !force)
00478         return;
00479     if (!force) // -1 based atomic refcounting
00480         ref.ref();
00481 
00482     useXP(true);
00483 }

Here is the call graph for this function:

void QWindowsXPStylePrivate::cleanup ( bool  force = false  ) 

Definition at line 488 of file qwindowsxpstyle.cpp.

References bufferBitmap, bufferDC, cleanupHandleMap(), QBasicAtomic::deref(), limboWidget, ref, tabbody, and use_xp.

Referenced by ~QWindowsXPStylePrivate().

00489 {
00490     if(bufferBitmap)
00491         DeleteObject(bufferBitmap);
00492     bufferBitmap = 0;
00493 
00494     if(bufferDC)
00495         DeleteDC(bufferDC);
00496     bufferDC = 0;
00497 
00498     if (ref.deref() && !force)
00499         return;
00500     if (!force)  // -1 based atomic refcounting
00501         ref.deref();
00502 
00503     use_xp = false;
00504     cleanupHandleMap();
00505     delete limboWidget;
00506     delete tabbody;
00507     limboWidget = 0;
00508     tabbody = 0;
00509 }

Here is the call graph for this function:

void QWindowsXPStylePrivate::cleanupHandleMap (  ) 

Definition at line 516 of file qwindowsxpstyle.cpp.

References QMap< Key, T >::begin(), QMap< Key, T >::end(), handleMap, pCloseThemeData, and QMap< Key, T >::value().

Referenced by cleanup().

00517 {
00518     if (!handleMap)
00519         return;
00520 
00521     QMap<QString, HTHEME>::Iterator it;
00522     for (it = handleMap->begin(); it != handleMap->end(); ++it)
00523         pCloseThemeData(it.value());
00524     delete handleMap;
00525     handleMap = 0;
00526 }

Here is the call graph for this function:

const QPixmap * QWindowsXPStylePrivate::tabBody ( QWidget widget  ) 

Definition at line 552 of file qwindowsxpstyle.cpp.

References QApplication::desktop(), drawBackground(), XPThemeData::handle(), QRect::height(), pGetThemePartSize, qt_win_display_dc(), XPThemeData::rect, QDesktopWidget::screenGeometry(), and tabbody.

00553 {
00554     if (!tabbody) {
00555         SIZE sz;
00556         XPThemeData theme(0, 0, "TAB", TABP_BODY);
00557         pGetThemePartSize(theme.handle(), qt_win_display_dc(), TABP_BODY, 0, 0, TS_TRUE, &sz);
00558 
00559         tabbody = new QPixmap(sz.cx, QApplication::desktop()->screenGeometry().height());
00560         QPainter painter(tabbody);
00561         theme.rect = QRect(0, 0, sz.cx, sz.cy);
00562         drawBackground(theme);
00563         // We fill with the last line of the themedata, that
00564         // way we don't get a tiled pixmap inside big tabs
00565         QPixmap temp(sz.cx, 1);
00566         painter.drawPixmap(0, 0, temp, 0, sz.cy-1, -1, -1);
00567         painter.drawTiledPixmap(0, sz.cy, sz.cx, tabbody->height()-sz.cy, temp);
00568     }
00569     return tabbody;
00570 }

Here is the call graph for this function:

HBITMAP QWindowsXPStylePrivate::buffer ( int  w = 0,
int  h = 0 
)

Definition at line 619 of file qwindowsxpstyle.cpp.

References bufferBitmap, bufferDC, bufferH, bufferPixels, bufferW, nullBitmap, qDebug(), qErrnoWarning(), qMax(), and qt_win_display_dc().

Referenced by drawBackgroundThruNativeBuffer(), fixAlphaChannel(), hasAlphaChannel(), hasAnyData(), and swapAlphaChannel().

00620 {
00621     // If we already have a HBITMAP which is of adequate size, just return that
00622     if (bufferBitmap) {
00623         if (bufferW >= w && bufferH >= h)
00624             return bufferBitmap;
00625         // Not big enough, discard the old one
00626         if (bufferDC && nullBitmap)
00627             SelectObject(bufferDC, nullBitmap);
00628         DeleteObject(bufferBitmap);
00629         bufferBitmap = 0;
00630     }
00631 
00632     w = qMax(bufferW, w);
00633     h = qMax(bufferH, h);
00634 
00635     if (!bufferDC)
00636         bufferDC = CreateCompatibleDC(qt_win_display_dc());
00637 
00638     // Define the header
00639     BITMAPINFO bmi;
00640     memset(&bmi, 0, sizeof(bmi));
00641     bmi.bmiHeader.biSize        = sizeof(BITMAPINFOHEADER);
00642     bmi.bmiHeader.biWidth       = w;
00643     bmi.bmiHeader.biHeight      = -h;
00644     bmi.bmiHeader.biPlanes      = 1;
00645     bmi.bmiHeader.biBitCount    = 32;
00646     bmi.bmiHeader.biCompression = BI_RGB;
00647 
00648     // Create the pixmap
00649     bufferPixels = 0;
00650     bufferBitmap = CreateDIBSection(bufferDC, &bmi, DIB_RGB_COLORS, (void **) &bufferPixels, 0, 0);
00651     GdiFlush();
00652     nullBitmap = (HBITMAP)SelectObject(bufferDC, bufferBitmap);
00653 
00654     if (!bufferBitmap) {
00655         qErrnoWarning("QWindowsXPStylePrivate::buffer(w,h), failed to create dibsection");
00656         bufferW = 0;
00657         bufferH = 0;
00658         return 0;
00659     }
00660     if (!bufferPixels) {
00661         qErrnoWarning("QWindowsXPStylePrivate::buffer(w,h), did not allocate pixel data");
00662         bufferW = 0;
00663         bufferH = 0;
00664         return 0;
00665     }
00666     bufferW = w;
00667     bufferH = h;
00668 #ifdef DEBUG_XP_STYLE
00669     qDebug("Creating new dib section (%d, %d)", w, h);
00670 #endif
00671     return bufferBitmap;
00672 }

Here is the call graph for this function:

HDC QWindowsXPStylePrivate::bufferHDC (  )  [inline]

Definition at line 337 of file qwindowsxpstyle.cpp.

References bufferDC.

Referenced by drawBackgroundThruNativeBuffer(), and region().

00338     { return bufferDC;}

bool QWindowsXPStylePrivate::resolveSymbols (  )  [static]

Definition at line 576 of file qwindowsxpstyle.cpp.

References pCloseThemeData, pDrawThemeBackground, pDrawThemeBackgroundEx, pGetCurrentThemeName, pGetThemeBackgroundRegion, pGetThemeBool, pGetThemeColor, pGetThemeDocumentationProperty, pGetThemeEnumValue, pGetThemeFilename, pGetThemeFont, pGetThemeInt, pGetThemeIntList, pGetThemeMargins, pGetThemeMetric, pGetThemePartSize, pGetThemePosition, pGetThemePropertyOrigin, pGetThemeRect, pGetThemeString, pIsAppThemed, pIsThemeActive, pIsThemeBackgroundPartiallyTransparent, pOpenThemeData, and QLibrary::resolve().

Referenced by useXP().

00577 {
00578     static bool tried = false;
00579     if (!tried) {
00580         tried = true;
00581         QLibrary themeLib("uxtheme");
00582         pIsAppThemed = (PtrIsAppThemed)themeLib.resolve("IsAppThemed");
00583         if (pIsAppThemed) {
00584             pIsThemeActive          = (PtrIsThemeActive         )themeLib.resolve("IsThemeActive");
00585             pGetThemePartSize       = (PtrGetThemePartSize      )themeLib.resolve("GetThemePartSize");
00586             pOpenThemeData          = (PtrOpenThemeData         )themeLib.resolve("OpenThemeData");
00587             pCloseThemeData         = (PtrCloseThemeData        )themeLib.resolve("CloseThemeData");
00588             pDrawThemeBackground    = (PtrDrawThemeBackground   )themeLib.resolve("DrawThemeBackground");
00589             pDrawThemeBackgroundEx  = (PtrDrawThemeBackgroundEx )themeLib.resolve("DrawThemeBackgroundEx");
00590             pGetCurrentThemeName    = (PtrGetCurrentThemeName   )themeLib.resolve("GetCurrentThemeName");
00591             pGetThemeBool           = (PtrGetThemeBool          )themeLib.resolve("GetThemeBool");
00592             pGetThemeColor          = (PtrGetThemeColor         )themeLib.resolve("GetThemeColor");
00593             pGetThemeEnumValue      = (PtrGetThemeEnumValue     )themeLib.resolve("GetThemeEnumValue");
00594             pGetThemeFilename       = (PtrGetThemeFilename      )themeLib.resolve("GetThemeFilename");
00595             pGetThemeFont           = (PtrGetThemeFont          )themeLib.resolve("GetThemeFont");
00596             pGetThemeInt            = (PtrGetThemeInt           )themeLib.resolve("GetThemeInt");
00597             pGetThemeIntList        = (PtrGetThemeIntList       )themeLib.resolve("GetThemeIntList");
00598             pGetThemeMargins        = (PtrGetThemeMargins       )themeLib.resolve("GetThemeMargins");
00599             pGetThemeMetric         = (PtrGetThemeMetric        )themeLib.resolve("GetThemeMetric");
00600             pGetThemePartSize       = (PtrGetThemePartSize      )themeLib.resolve("GetThemePartSize");
00601             pGetThemePosition       = (PtrGetThemePosition      )themeLib.resolve("GetThemePosition");
00602             pGetThemePropertyOrigin = (PtrGetThemePropertyOrigin)themeLib.resolve("GetThemePropertyOrigin");
00603             pGetThemeRect           = (PtrGetThemeRect          )themeLib.resolve("GetThemeRect");
00604             pGetThemeString         = (PtrGetThemeString        )themeLib.resolve("GetThemeString");
00605             pGetThemeBackgroundRegion              = (PtrGetThemeBackgroundRegion             )themeLib.resolve("GetThemeBackgroundRegion");
00606             pGetThemeDocumentationProperty         = (PtrGetThemeDocumentationProperty        )themeLib.resolve("GetThemeDocumentationProperty");
00607             pIsThemeBackgroundPartiallyTransparent = (PtrIsThemeBackgroundPartiallyTransparent)themeLib.resolve("IsThemeBackgroundPartiallyTransparent");
00608         }
00609     }
00610 
00611     return pIsAppThemed != 0;
00612 }

Here is the call graph for this function:

bool QWindowsXPStylePrivate::useXP ( bool  update = false  )  [inline, static]

Definition at line 464 of file qwindowsxpstyle.cpp.

References QCoreApplication::instance(), pIsAppThemed, pIsThemeActive, resolveSymbols(), and use_xp.

Referenced by QWindowsXPStyle::drawComplexControl(), QWindowsXPStyle::drawControl(), QWindowsXPStyle::drawPrimitive(), XPThemeData::handle(), init(), XPThemeData::isValid(), QWindowsXPStyle::pixelMetric(), QWindowsXPStyle::polish(), QWindowsXPStyle::sizeFromContents(), QWindowsXPStyle::standardIconImplementation(), QWindowsXPStyle::standardPixmap(), QWindowsXPStyle::styleHint(), QWindowsXPStyle::subControlRect(), QWindowsXPStyle::subElementRect(), and QWindowsXPStyle::unpolish().

00465 {
00466     if (!update)
00467         return use_xp;
00468     return (use_xp = resolveSymbols() && pIsThemeActive()
00469             && (pIsAppThemed() || !QApplication::instance()));
00470 }

Here is the call graph for this function:

bool QWindowsXPStylePrivate::isTransparent ( XPThemeData themeData  ) 

Definition at line 680 of file qwindowsxpstyle.cpp.

References XPThemeData::handle(), XPThemeData::partId, pIsThemeBackgroundPartiallyTransparent, and XPThemeData::stateId.

Referenced by drawBackgroundThruNativeBuffer().

00681 {
00682     return pIsThemeBackgroundPartiallyTransparent(themeData.handle(), themeData.partId,
00683                                                   themeData.stateId);
00684 }

Here is the call graph for this function:

QRegion QWindowsXPStylePrivate::region ( XPThemeData themeData  ) 

Definition at line 689 of file qwindowsxpstyle.cpp.

References bufferHDC(), XPThemeData::handle(), XPThemeData::partId, pGetThemeBackgroundRegion, XPThemeData::rect, XPThemeData::stateId, and XPThemeData::toRECT().

Referenced by drawBackgroundThruNativeBuffer().

00690 {
00691     HRGN hRgn = 0;
00692     RECT rect = themeData.toRECT(themeData.rect);
00693     if (!SUCCEEDED(pGetThemeBackgroundRegion(themeData.handle(), bufferHDC(), themeData.partId,
00694                                              themeData.stateId, &rect, &hRgn)))
00695         return QRegion();
00696 
00697     QRegion rgn = QRegion(0,0,1,1);
00698     CombineRgn(rgn.handle(), hRgn, 0, RGN_COPY);
00699     DeleteObject(hRgn);
00700     return rgn;
00701 }

Here is the call graph for this function:

void QWindowsXPStylePrivate::setTransparency ( QWidget widget,
XPThemeData themeData 
)

Definition at line 706 of file qwindowsxpstyle.cpp.

References XPThemeData::mask(), and winId().

00707 {
00708     HRGN hrgn = themeData.mask();
00709     if (hrgn)
00710         SetWindowRgn(winId(widget), hrgn, true);
00711 }

Here is the call graph for this function:

void QWindowsXPStylePrivate::drawBackground ( XPThemeData themeData  ) 

Definition at line 835 of file qwindowsxpstyle.cpp.

References drawBackgroundDirectly(), drawBackgroundThruNativeBuffer(), QRect::isEmpty(), m, QPainter::matrix(), XPThemeData::mirrorHorizontally, XPThemeData::mirrorVertically, QPainter::opacity(), QPainter::paintEngine(), XPThemeData::painter, pDrawThemeBackgroundEx, XPThemeData::rect, QPainter::restore(), XPThemeData::rotate, and QPainter::save().

Referenced by tabBody().

00836 {
00837     if (themeData.rect.isEmpty())
00838         return;
00839 
00840     QPainter *painter = themeData.painter;
00841     Q_ASSERT_X(painter != 0, "QWindowsXPStylePrivate::drawBackground()", "Trying to draw a theme part without a painter");
00842     if (!painter)
00843         return;
00844 
00845     painter->save();
00846 
00847     QMatrix m = painter->matrix();
00848     bool complexXForm = m.m11() != 1.0 || m.m22() != 1.0 || m.m12() != 0.0 || m.m21() != 0.0;
00849 
00850     bool useFallback = painter->paintEngine()->getDC() == 0
00851                        || painter->opacity() != 1.0
00852                        || themeData.rotate
00853                        || complexXForm
00854                  || themeData.mirrorVertically
00855                  || (themeData.mirrorHorizontally && pDrawThemeBackgroundEx == 0);
00856     if (!useFallback)
00857         drawBackgroundDirectly(themeData);
00858     else
00859         drawBackgroundThruNativeBuffer(themeData);
00860 
00861     painter->restore();
00862 }

Here is the call graph for this function:

void QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer ( XPThemeData themeData  ) 

Definition at line 947 of file qwindowsxpstyle.cpp.

References QRect::adjusted(), alphaCache, area(), QVector< T >::at(), BOOL, QRect::bottom(), buf, buffer(), bufferH, bufferHDC(), bufferPixels, bufferW, QPainter::clipRegion(), QPixmap::copy(), QImage::copy(), QVector< T >::count(), data, QPainter::drawImage(), QPainter::drawPixmap(), DTBG_CLIPRECT, DTBG_OMITBORDER, DTBG_OMITCONTENT, _DTBGOPTS::dwFlags, _DTBGOPTS::dwSize, QPixmapCache::find(), fixAlphaChannel(), QImage::Format_ARGB32_Premultiplied, QImage::Format_RGB32, QPixmap::fromImage(), GT_IMAGEGLYPH, GT_NONE, h, XPThemeData::handle(), hasAlphaChannel(), hasAnyData(), QRect::height(), i, QPixmapCache::insert(), QHash< Key, T >::insert(), Qt::IntersectClip, QRegion::isEmpty(), isTransparent(), key, MaskAlpha, QImage::mirrored(), XPThemeData::mirrorHorizontally, XPThemeData::mirrorVertically, QRect::moveTo(), XPThemeData::name, NoAlpha, XPThemeData::noBorder, XPThemeData::noContent, XPThemeData::painter, XPThemeData::partId, pDrawThemeBackground, pDrawThemeBackgroundEx, pGetThemeBool, pGetThemeColor, pGetThemeEnumValue, pGetThemeInt, pGetThemePropertyOrigin, printf, _DTBGOPTS::rcClip, XPThemeData::rect, QRegion::rects(), region(), QRect::right(), QMatrix::rotate(), XPThemeData::rotate, QPainter::setClipping(), QPainter::setClipRegion(), XPThemeData::stateId, swapAlphaChannel(), TMT_BORDERONLY, TMT_BORDERSIZE, TMT_CAPTIONMARGINS, TMT_GLYPHTYPE, TMT_TRANSPARENTCOLOR, QPixmap::toImage(), XPThemeData::toRECT(), QImage::transformed(), UnknownAlpha, QHash< Key, T >::value(), w, QRect::width(), QRect::x(), and QRect::y().

Referenced by drawBackground().

00948 {
00949     QPainter *painter = themeData.painter;
00950     QRect rect = themeData.rect;
00951 
00952     if ((themeData.rotate + 90) % 180 == 0) { // Catch 90,270,etc.. degree flips.
00953         rect = QRect(0, 0, rect.height(), rect.width());
00954     }
00955     rect.moveTo(0,0);
00956     int partId = themeData.partId;
00957     int stateId = themeData.stateId;
00958     int w = rect.width();
00959     int h = rect.height();
00960 
00961     // Values initialized later, either from cached values, or from function calls
00962     AlphaChannelType alphaType = UnknownAlpha;
00963     bool stateHasData = true; // We assume so;
00964     bool hasAlpha = false;
00965     bool partIsTransparent;
00966     bool inspectData;
00967     bool potentialInvalidAlpha;
00968 
00969     QString pixmapCacheKey = QString("$qt_xp_%1p%2s%3s%4b%5c%6w%7h").arg(themeData.name)
00970                              .arg(partId).arg(stateId).arg(!themeData.noBorder).arg(!themeData.noContent)
00971                              .arg(w).arg(h);
00972     QPixmap cachedPixmap;
00973     ThemeMapKey key(themeData);
00974     ThemeMapData data = alphaCache.value(key);
00975 
00976     bool haveCachedPixmap = false;
00977     bool isCached = data.dataValid;
00978     if (isCached) {
00979         if (!(stateHasData = data.hasAnyData))
00980             return; // Cached NOOP
00981         inspectData = data.wasAlphaSwapped;
00982         partIsTransparent = data.partIsTransparent;
00983         hasAlpha = data.hasAlphaChannel;
00984         alphaType = data.alphaType;
00985         potentialInvalidAlpha = data.hadInvalidAlpha;
00986 
00987         haveCachedPixmap = QPixmapCache::find(pixmapCacheKey, cachedPixmap);
00988 
00989 #ifdef DEBUG_XP_STYLE
00990         char buf[25];
00991         ::sprintf(buf, "+ Pixmap(%3d, %3d) ]", w, h);
00992         printf("---[ CACHED %s--------> Name(%-10s) Part(%d) State(%d)\n",
00993                haveCachedPixmap ? buf : "]-------------------",
00994                qPrintable(themeData.name), themeData.partId, themeData.stateId);
00995 #endif
00996     } else {
00997         // Not cached, so get values from Theme Engine
00998         BOOL tmt_borderonly = false;
00999         COLORREF tmt_transparentcolor = 0x0;
01000         PROPERTYORIGIN proporigin = PO_NOTFOUND;
01001         pGetThemeBool(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERONLY, &tmt_borderonly);
01002         pGetThemeColor(themeData.handle(), themeData.partId, themeData.stateId, TMT_TRANSPARENTCOLOR, &tmt_transparentcolor);
01003         pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_CAPTIONMARGINS, &proporigin);
01004         inspectData = (tmt_transparentcolor != 0 || tmt_borderonly || proporigin == PO_PART || proporigin == PO_STATE);
01005         partIsTransparent = isTransparent(themeData);
01006 
01007         potentialInvalidAlpha = false;
01008         pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_GLYPHTYPE, &proporigin);
01009         if (proporigin == PO_PART || proporigin == PO_STATE) {
01010             int tmt_glyphtype = GT_NONE;
01011             pGetThemeEnumValue(themeData.handle(), themeData.partId, themeData.stateId, TMT_GLYPHTYPE, &tmt_glyphtype);
01012             potentialInvalidAlpha = partIsTransparent && !inspectData && tmt_glyphtype == GT_IMAGEGLYPH;
01013         }
01014 
01015 #ifdef DEBUG_XP_STYLE
01016         printf("---[ NOT CACHED ]-----------------------> Name(%-10s) Part(%d) State(%d)\n",
01017                qPrintable(themeData.name), themeData.partId, themeData.stateId);
01018         printf("-->partIsTransparen      = %d\n", partIsTransparent);
01019         printf("-->inspectData           = %d\n", inspectData);
01020         printf("-->potentialInvalidAlpha = %d\n", potentialInvalidAlpha);
01021         showProperties(themeData);
01022 #endif
01023     }
01024     bool wasAlphaSwapped = false;
01025     bool wasAlphaFixed = false;
01026 
01027     // OLD PSDK Workaround ------------------------------------------------------------------------
01028     // See if we need extra clipping for the older PSDK, which does
01029     // not have a DrawThemeBackgroundEx function for DTGB_OMITBORDER
01030     // and DTGB_OMITCONTENT
01031     bool addBorderContentClipping = false;
01032     QRegion extraClip;
01033     QRect area = rect;
01034     if (themeData.noBorder || themeData.noContent) {
01035   extraClip = area;
01036   // We are running on a system where the uxtheme.dll does not have
01037   // the DrawThemeBackgroundEx function, so we need to clip away
01038   // borders or contents manually.
01039 
01040   int borderSize = 0;
01041   PROPERTYORIGIN origin = PO_NOTFOUND;
01042   pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &origin);
01043   pGetThemeInt(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &borderSize);
01044 
01045   // Clip away border region
01046   if ((origin == PO_CLASS || origin == PO_PART || origin == PO_STATE) && borderSize > 0) {
01047       if (themeData.noBorder) {
01048     extraClip &= area;
01049     area = area.adjusted(-borderSize, -borderSize, borderSize, borderSize);
01050       }
01051 
01052       // Clip away content region
01053       if (themeData.noContent) {
01054     QRegion content = area.adjusted(borderSize, borderSize, -borderSize, -borderSize);
01055     extraClip ^= content;
01056       }
01057   }
01058   addBorderContentClipping = (themeData.noBorder | themeData.noContent);
01059     }
01060 
01061     QImage img;
01062     if (!haveCachedPixmap) { // If the pixmap is not cached, generate it! -------------------------
01063         buffer(w, h); // Ensure a buffer of at least (w, h) in size
01064         HDC dc = bufferHDC();
01065 
01066         // Clear the buffer
01067         if (alphaType != NoAlpha) {
01068             // Consider have separate "memset" function for small chunks for more speedup
01069             memset(bufferPixels, inspectData ? 0xFF : 0x00, bufferW * h * 4);
01070         }
01071 
01072   // Difference between area and rect
01073   int dx = area.x() - rect.x();
01074   int dy = area.y() - rect.y();
01075   int dr = area.right() - rect.right();
01076   int db = area.bottom() - rect.bottom();
01077 
01078   // Adjust so painting rect starts from Origo
01079   rect.moveTo(0,0);
01080         area.moveTo(dx,dy);
01081   DTBGOPTS drawOptions;
01082         drawOptions.dwSize = sizeof(drawOptions);
01083         drawOptions.rcClip = themeData.toRECT(rect);
01084         drawOptions.dwFlags = DTBG_CLIPRECT
01085                             | (themeData.noBorder ? DTBG_OMITBORDER : 0)
01086                             | (themeData.noContent ? DTBG_OMITCONTENT : 0);
01087 
01088         // Drawing the part into the backing store
01089   if (pDrawThemeBackgroundEx != 0) {
01090             pDrawThemeBackgroundEx(themeData.handle(), dc, themeData.partId, themeData.stateId, &(themeData.toRECT(area)), &drawOptions);
01091   } else {
01092       // Set the clip region, if used..
01093       if (addBorderContentClipping) {
01094     SelectClipRgn(dc, extraClip.handle());
01095     // Compensate for the noBorder area difference (noContent has the same area)
01096     drawOptions.rcClip = themeData.toRECT(rect.adjusted(dx, dy, dr, db));
01097       }
01098 
01099       pDrawThemeBackground(themeData.handle(), dc, themeData.partId, themeData.stateId, &(drawOptions.rcClip), 0);
01100 
01101       if (addBorderContentClipping)
01102     SelectClipRgn(dc, 0);
01103   }
01104 
01105         // If not cached, analyze the buffer data to figure
01106         // out alpha type, and if it contains data
01107         if (!isCached) {
01108             if (inspectData)
01109                 stateHasData = hasAnyData(rect);
01110             // SHORTCUT: If the part's state has no data, cache it for NOOP later
01111             if (!stateHasData) {
01112                 memset(&data, 0, sizeof(data));
01113                 data.dataValid = true;
01114                 alphaCache.insert(key, data);
01115                 return;
01116             }
01117             hasAlpha = hasAlphaChannel(rect);
01118 #if defined(DEBUG_XP_STYLE) && 1
01119             dumpNativeDIB(w, h);
01120 #endif
01121         }
01122 
01123         // Swap alpha values, if needed
01124         if (inspectData)
01125             wasAlphaSwapped = swapAlphaChannel(rect);
01126 
01127         // Fix alpha values, if needed
01128         if (potentialInvalidAlpha)
01129             wasAlphaFixed = fixAlphaChannel(rect);
01130 
01131         QImage::Format format;
01132         if ((partIsTransparent && !wasAlphaSwapped) || (!partIsTransparent && hasAlpha)) {
01133             format = QImage::Format_ARGB32_Premultiplied;
01134             alphaType = RealAlpha;
01135         } else if (wasAlphaSwapped) {
01136             format = QImage::Format_ARGB32_Premultiplied;
01137             alphaType = MaskAlpha;
01138         } else {
01139             format = QImage::Format_RGB32;
01140             alphaType = NoAlpha;
01141         }
01142 #if defined(DEBUG_XP_STYLE) && 1
01143         printf("Image format is: %s\n", alphaType == RealAlpha ? "Real Alpha" : alphaType == MaskAlpha ? "Masked Alpha" : "No Alpha");
01144 #endif
01145         img = QImage(bufferPixels, bufferW, bufferH, format);
01146     }
01147 
01148     // Blitting backing store
01149     bool useRegion = partIsTransparent && !hasAlpha && !wasAlphaSwapped;
01150 
01151     QRegion newRegion;
01152     QRegion oldRegion;
01153     if (useRegion) {
01154         newRegion = region(themeData);
01155         oldRegion = painter->clipRegion();
01156         painter->setClipRegion(newRegion);
01157 #if defined(DEBUG_XP_STYLE) && 0
01158         printf("Using region:\n");
01159         QVector<QRect> rects = newRegion.rects();
01160         for (int i = 0; i < rects.count(); ++i) {
01161             const QRect &r = rects.at(i);
01162             printf("    (%d, %d, %d, %d)\n", r.x(), r.y(), r.right(), r.bottom());
01163         }
01164 #endif
01165     }
01166 
01167     if (addBorderContentClipping)
01168   painter->setClipRegion(extraClip, Qt::IntersectClip);
01169 
01170     if (!themeData.mirrorHorizontally && !themeData.mirrorVertically && !themeData.rotate) {
01171         if (!haveCachedPixmap)
01172             painter->drawImage(themeData.rect, img, rect);
01173         else
01174             painter->drawPixmap(themeData.rect, cachedPixmap);
01175     } else {
01176         // This is _slow_!
01177         // Make a copy containing only the necessary data, and mirror
01178         // on all wanted axes. Then draw the copy.
01179         // If cached, the normal pixmap is cached, instead of caching
01180         // all possible orientations for each part and state.
01181         QImage imgCopy;
01182         if (!haveCachedPixmap)
01183             imgCopy = img.copy(rect);
01184         else
01185             imgCopy = cachedPixmap.toImage();
01186 
01187         if (themeData.rotate) {
01188             QMatrix rotMatrix;
01189             rotMatrix.rotate(themeData.rotate);
01190             imgCopy = imgCopy.transformed(rotMatrix);
01191         }
01192         if (themeData.mirrorHorizontally || themeData.mirrorVertically) {
01193             imgCopy = imgCopy.mirrored(themeData.mirrorHorizontally, themeData.mirrorVertically);
01194         }
01195         painter->drawImage(themeData.rect,
01196                            imgCopy);
01197     }
01198 
01199     if (useRegion || addBorderContentClipping) {
01200         if (oldRegion.isEmpty())
01201             painter->setClipping(false);
01202         else
01203             painter->setClipRegion(oldRegion);
01204     }
01205 
01206     // Cache the pixmap to avoid expensive swapAlphaChannel() calls
01207     if (!haveCachedPixmap && ((w * h) < 2000) && w && h) {
01208         QPixmap pix = QPixmap::fromImage(img).copy(rect);
01209         QPixmapCache::insert(pixmapCacheKey, pix);
01210 #ifdef DEBUG_XP_STYLE
01211         printf("+++Adding pixmap to cache, size(%d, %d), wasAlphaSwapped(%d), wasAlphaFixed(%d), name(%s)\n",
01212                w, h, wasAlphaSwapped, wasAlphaFixed, qPrintable(pixmapCacheKey));
01213 #endif
01214     }
01215 
01216     // Add to theme part cache
01217     if (!isCached) {
01218         memset(&data, 0, sizeof(data));
01219         data.dataValid = true;
01220         data.partIsTransparent = partIsTransparent;
01221         data.alphaType = alphaType;
01222         data.hasAlphaChannel = hasAlpha;
01223         data.hasAnyData = stateHasData;
01224         data.wasAlphaSwapped = wasAlphaSwapped;
01225         data.hadInvalidAlpha = wasAlphaFixed;
01226         alphaCache.insert(key, data);
01227     }
01228 }

Here is the call graph for this function:

void QWindowsXPStylePrivate::drawBackgroundDirectly ( XPThemeData themeData  ) 

Definition at line 869 of file qwindowsxpstyle.cpp.

References area(), QRegion::boundingRect(), QPainter::clipRegion(), QPainter::deviceMatrix(), DTBG_CLIPRECT, DTBG_MIRRORDC, DTBG_OMITBORDER, DTBG_OMITCONTENT, _DTBGOPTS::dwFlags, _DTBGOPTS::dwSize, QMatrix::dx(), QMatrix::dy(), XPThemeData::handle(), QPainter::hasClipping(), QRegion::isEmpty(), XPThemeData::mirrorHorizontally, XPThemeData::name, XPThemeData::noBorder, XPThemeData::noContent, QPainter::paintEngine(), XPThemeData::painter, XPThemeData::partId, pDrawThemeBackground, pDrawThemeBackgroundEx, pGetThemeInt, pGetThemePropertyOrigin, printf, _DTBGOPTS::rcClip, XPThemeData::rect, XPThemeData::stateId, QPaintEngine::systemClip(), TMT_BORDERSIZE, XPThemeData::toRECT(), QRegion::translated(), and QRect::translated().

Referenced by drawBackground().

00870 {
00871     QPainter *painter = themeData.painter;
00872     HDC dc = painter->paintEngine()->getDC();
00873 
00874     QPoint redirectionDelta(int(painter->deviceMatrix().dx()),
00875                             int(painter->deviceMatrix().dy()));
00876     QRect area = themeData.rect.translated(redirectionDelta);
00877 
00878     QRegion sysRgn = painter->paintEngine()->systemClip();
00879     if (sysRgn.isEmpty())
00880         sysRgn = area;
00881     else
00882         sysRgn &= area;
00883     if (painter->hasClipping())
00884         sysRgn &= painter->clipRegion().translated(redirectionDelta);
00885     SelectClipRgn(dc, sysRgn.handle());
00886 
00887 #ifdef DEBUG_XP_STYLE
00888         printf("---[ DIRECT PAINTING ]------------------> Name(%-10s) Part(%d) State(%d)\n",
00889                qPrintable(themeData.name), themeData.partId, themeData.stateId);
00890         showProperties(themeData);
00891 #endif
00892 
00893     RECT drawRECT = themeData.toRECT(area);
00894     DTBGOPTS drawOptions;
00895     drawOptions.dwSize = sizeof(drawOptions);
00896     drawOptions.rcClip = themeData.toRECT(sysRgn.boundingRect());
00897     drawOptions.dwFlags = DTBG_CLIPRECT
00898                           | (themeData.noBorder ? DTBG_OMITBORDER : 0)
00899                           | (themeData.noContent ? DTBG_OMITCONTENT : 0)
00900                           | (themeData.mirrorHorizontally ? DTBG_MIRRORDC : 0);
00901 
00902     if (pDrawThemeBackgroundEx != 0) {
00903         pDrawThemeBackgroundEx(themeData.handle(), dc, themeData.partId, themeData.stateId, &(drawRECT), &drawOptions);
00904     } else {
00905   // We are running on a system where the uxtheme.dll does not have
00906   // the DrawThemeBackgroundEx function, so we need to clip away
00907   // borders or contents manually. All flips and mirrors uses the
00908   // fallback implementation
00909 
00910   int borderSize = 0;
00911   PROPERTYORIGIN origin = PO_NOTFOUND;
00912   pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &origin);
00913         pGetThemeInt(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &borderSize);
00914 
00915   // Clip away border region
00916         QRegion extraClip = sysRgn;
00917   if ((origin == PO_CLASS || origin == PO_PART || origin == PO_STATE) && borderSize > 0) {
00918       if (themeData.noBorder) {
00919     // extraClip &= area is already done
00920     drawRECT = themeData.toRECT(area.adjusted(-borderSize, -borderSize, borderSize, borderSize));
00921       }
00922 
00923       // Clip away content region
00924       if (themeData.noContent) {
00925     QRegion content = area.adjusted(borderSize, borderSize, -borderSize, -borderSize);
00926     extraClip ^= content;
00927       }
00928 
00929       // Set the clip region, if used..
00930       if (themeData.noBorder || themeData.noContent)
00931     SelectClipRgn(dc, extraClip.handle());
00932         }
00933 
00934   pDrawThemeBackground(themeData.handle(), dc, themeData.partId, themeData.stateId, &(drawRECT), &(drawOptions.rcClip));
00935     }
00936     SelectClipRgn(dc, 0);
00937 }

Here is the call graph for this function:

bool QWindowsXPStylePrivate::hasAnyData ( const QRect rect  ) 

Definition at line 719 of file qwindowsxpstyle.cpp.

References alpha, buffer(), bufferPixels, bufferW, h, QRect::height(), QRect::left(), QRect::top(), w, QRect::width(), x, and y.

Referenced by drawBackgroundThruNativeBuffer().

00720 {
00721     const int startX = rect.left();
00722     const int startY = rect.top();
00723     const int w = rect.width();
00724     const int h = rect.height();
00725 
00726     for (int y = startY; y < h; ++y) {
00727         register DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);
00728         for (int x = startX; x < w; ++x, ++buffer) {
00729             int alpha = (*buffer) >> 24;
00730             if (alpha != 0xFF) // buffer has been touched
00731                 return true;
00732         }
00733     }
00734     return false;
00735 }

Here is the call graph for this function:

bool QWindowsXPStylePrivate::hasAlphaChannel ( const QRect rect  ) 

Definition at line 741 of file qwindowsxpstyle.cpp.

References alpha, buffer(), bufferPixels, bufferW, h, QRect::height(), QRect::left(), QRect::top(), w, QRect::width(), x, and y.

Referenced by drawBackgroundThruNativeBuffer().

00742 {
00743     const int startX = rect.left();
00744     const int startY = rect.top();
00745     const int w = rect.width();
00746     const int h = rect.height();
00747 
00748     int firstAlpha = -1;
00749     for (int y = startY; y < h/2; ++y) {
00750         register DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);
00751         for (int x = startX; x < w; ++x, ++buffer) {
00752             int alpha = (*buffer) >> 24;
00753             if (firstAlpha == -1)
00754                 firstAlpha = alpha;
00755             else if (alpha != firstAlpha)
00756                 return true;
00757         }
00758     }
00759     return false;
00760 }

Here is the call graph for this function:

bool QWindowsXPStylePrivate::fixAlphaChannel ( const QRect rect  ) 

Definition at line 770 of file qwindowsxpstyle.cpp.

References alpha, buffer(), bufferPixels, bufferW, h, QRect::height(), QRect::left(), qAlpha(), qBlue(), qGreen(), qRed(), QRect::top(), w, QRect::width(), x, and y.

Referenced by drawBackgroundThruNativeBuffer().

00771 {
00772     const int startX = rect.left();
00773     const int startY = rect.top();
00774     const int w = rect.width();
00775     const int h = rect.height();
00776     bool hasFixedAlphaValue = false;
00777 
00778     for (int y = startY; y < h; ++y) {
00779         register DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);
00780         for (register int x = startX; x < w; ++x, ++buffer) {
00781             uint pixel = *buffer;
00782             int alpha = qAlpha(pixel);
00783             if (qRed(pixel) > alpha || qGreen(pixel) > alpha || qBlue(pixel) > alpha) {
00784                 *buffer |= 0xff000000;
00785                 hasFixedAlphaValue = true;
00786             }
00787         }
00788     }
00789     return hasFixedAlphaValue;
00790 }

Here is the call graph for this function:

bool QWindowsXPStylePrivate::swapAlphaChannel ( const QRect rect  ) 

Definition at line 801 of file qwindowsxpstyle.cpp.

References buffer(), bufferPixels, bufferW, h, QRect::height(), QRect::left(), QRect::top(), w, QRect::width(), x, and y.

Referenced by drawBackgroundThruNativeBuffer().

00802 {
00803     const int startX = rect.left();
00804     const int startY = rect.top();
00805     const int w = rect.width();
00806     const int h = rect.height();
00807     bool valueChange = false;
00808 
00809     // Flip the alphas, so that 255-alpha pixels are 0, and 0-alpha are 255.
00810     for (int y = startY; y < h; ++y) {
00811         register DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);
00812         for (register int x = startX; x < w; ++x, ++buffer) {
00813             register unsigned int alphaValue = (*buffer) & 0xFF000000;
00814             if (alphaValue == 0xFF000000) {
00815                 *buffer &= 0x00FFFFFF;
00816                 valueChange = true;
00817             } else if (alphaValue == 0) {
00818                 *buffer |= 0xFF000000;
00819                 valueChange = true;
00820             }
00821         }
00822     }
00823     return valueChange;
00824 }

Here is the call graph for this function:


Member Data Documentation

QRgb QWindowsXPStylePrivate::groupBoxTextColor

Definition at line 356 of file qwindowsxpstyle.cpp.

QRgb QWindowsXPStylePrivate::groupBoxTextColorDisabled

Definition at line 357 of file qwindowsxpstyle.cpp.

QRgb QWindowsXPStylePrivate::sliderTickColor

Definition at line 358 of file qwindowsxpstyle.cpp.

bool QWindowsXPStylePrivate::hasInitColors

Definition at line 359 of file qwindowsxpstyle.cpp.

QMap< QString, HTHEME > * QWindowsXPStylePrivate::handleMap [static]

Definition at line 361 of file qwindowsxpstyle.cpp.

Referenced by cleanupHandleMap(), and XPThemeData::handle().

QIcon QWindowsXPStylePrivate::dockFloat

Definition at line 363 of file qwindowsxpstyle.cpp.

QIcon QWindowsXPStylePrivate::dockClose

Definition at line 363 of file qwindowsxpstyle.cpp.

QAtomic QWindowsXPStylePrivate::ref [static, private]

Definition at line 371 of file qwindowsxpstyle.cpp.

Referenced by cleanup(), and init().

bool QWindowsXPStylePrivate::use_xp [static, private]

Definition at line 372 of file qwindowsxpstyle.cpp.

Referenced by cleanup(), and useXP().

QWidget * QWindowsXPStylePrivate::limboWidget [static, private]

Definition at line 373 of file qwindowsxpstyle.cpp.

Referenced by cleanup(), and winId().

QPixmap * QWindowsXPStylePrivate::tabbody [static, private]

Definition at line 374 of file qwindowsxpstyle.cpp.

Referenced by cleanup(), and tabBody().

QHash<ThemeMapKey, ThemeMapData> QWindowsXPStylePrivate::alphaCache [private]

Definition at line 376 of file qwindowsxpstyle.cpp.

Referenced by drawBackgroundThruNativeBuffer().

HDC QWindowsXPStylePrivate::bufferDC [private]

Definition at line 377 of file qwindowsxpstyle.cpp.

Referenced by buffer(), bufferHDC(), and cleanup().

HBITMAP QWindowsXPStylePrivate::bufferBitmap [private]

Definition at line 378 of file qwindowsxpstyle.cpp.

Referenced by buffer(), and cleanup().

HBITMAP QWindowsXPStylePrivate::nullBitmap [private]

Definition at line 379 of file qwindowsxpstyle.cpp.

Referenced by buffer().

uchar* QWindowsXPStylePrivate::bufferPixels [private]

Definition at line 380 of file qwindowsxpstyle.cpp.

Referenced by buffer(), drawBackgroundThruNativeBuffer(), fixAlphaChannel(), hasAlphaChannel(), hasAnyData(), and swapAlphaChannel().

int QWindowsXPStylePrivate::bufferW [private]

Definition at line 381 of file qwindowsxpstyle.cpp.

Referenced by buffer(), drawBackgroundThruNativeBuffer(), fixAlphaChannel(), hasAlphaChannel(), hasAnyData(), and swapAlphaChannel().

int QWindowsXPStylePrivate::bufferH [private]

Definition at line 381 of file qwindowsxpstyle.cpp.

Referenced by buffer(), and drawBackgroundThruNativeBuffer().


The documentation for this class was generated from the following file:
Generated on Thu Mar 15 19:53:16 2007 for Qt 4.2 User's Guide by  doxygen 1.5.1