

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 QPixmap * | tabBody (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, ThemeMapData > | alphaCache |
| HDC | bufferDC |
| HBITMAP | bufferBitmap |
| HBITMAP | nullBitmap |
| uchar * | bufferPixels |
| int | bufferW |
| int | bufferH |
Static Private Attributes | |
| static QAtomic | ref |
| static bool | use_xp |
| static QWidget * | limboWidget |
| static QPixmap * | tabbody |
| 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:

| 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:

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:

Definition at line 356 of file qwindowsxpstyle.cpp.
Definition at line 357 of file qwindowsxpstyle.cpp.
Definition at line 358 of file qwindowsxpstyle.cpp.
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().
Definition at line 363 of file qwindowsxpstyle.cpp.
Definition at line 363 of file qwindowsxpstyle.cpp.
QAtomic QWindowsXPStylePrivate::ref [static, private] |
bool QWindowsXPStylePrivate::use_xp [static, private] |
QWidget * QWindowsXPStylePrivate::limboWidget [static, private] |
QPixmap * QWindowsXPStylePrivate::tabbody [static, private] |
HDC QWindowsXPStylePrivate::bufferDC [private] |
Definition at line 377 of file qwindowsxpstyle.cpp.
Referenced by buffer(), bufferHDC(), and cleanup().
HBITMAP QWindowsXPStylePrivate::bufferBitmap [private] |
HBITMAP QWindowsXPStylePrivate::nullBitmap [private] |
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().
1.5.1