⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qwindowsxpstyle.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    const int w = rect.width();    const int h = rect.height();    for (int y = startY; y < h; ++y) {        register DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);        for (int x = startX; x < w; ++x, ++buffer) {            int alpha = (*buffer) >> 24;            if (alpha != 0xFF) // buffer has been touched                return true;        }    }    return false;}/*! \internal    Returns true if the native doublebuffer contains pixels with    varying alpha value.*/bool QWindowsXPStylePrivate::hasAlphaChannel(const QRect &rect){    const int startX = rect.left();    const int startY = rect.top();    const int w = rect.width();    const int h = rect.height();    int firstAlpha = -1;    for (int y = startY; y < h/2; ++y) {        register DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);        for (int x = startX; x < w; ++x, ++buffer) {            int alpha = (*buffer) >> 24;            if (firstAlpha == -1)                firstAlpha = alpha;            else if (alpha != firstAlpha)                return true;        }    }    return false;}/*! \internal    When the theme engine paints both a true alpha pixmap and a glyph    into our buffer, the glyph might not contain a proper alpha value.    The rule of thumb for premultiplied pixmaps is that the color    values of a pixel can never be higher than the alpha values, so    we use this to our advantage here, and fix all instances where    this occures.*/bool QWindowsXPStylePrivate::fixAlphaChannel(const QRect &rect){    const int startX = rect.left();    const int startY = rect.top();    const int w = rect.width();    const int h = rect.height();    bool hasFixedAlphaValue = false;    for (int y = startY; y < h; ++y) {        register DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);        for (register int x = startX; x < w; ++x, ++buffer) {            uint pixel = *buffer;            int alpha = qAlpha(pixel);            if (qRed(pixel) > alpha || qGreen(pixel) > alpha || qBlue(pixel) > alpha) {                *buffer |= 0xff000000;                hasFixedAlphaValue = true;            }        }    }    return hasFixedAlphaValue;}/*! \internal    Swaps the alpha values on certain pixels:        0xFF?????? -> 0x00??????        0x00?????? -> 0xFF??????    Used to determin the mask of a non-alpha transparent pixmap in    the native doublebuffer, and swap the alphas so we may paint    the image as a Premultiplied QImage with drawImage(), and obtain    the mask transparency.*/bool QWindowsXPStylePrivate::swapAlphaChannel(const QRect &rect){    const int startX = rect.left();    const int startY = rect.top();    const int w = rect.width();    const int h = rect.height();    bool valueChange = false;    // Flip the alphas, so that 255-alpha pixels are 0, and 0-alpha are 255.    for (int y = startY; y < h; ++y) {        register DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);        for (register int x = startX; x < w; ++x, ++buffer) {            register unsigned int alphaValue = (*buffer) & 0xFF000000;            if (alphaValue == 0xFF000000) {                *buffer &= 0x00FFFFFF;                valueChange = true;            } else if (alphaValue == 0) {                *buffer |= 0xFF000000;                valueChange = true;            }        }    }    return valueChange;}/*! \internal    Main theme drawing function.    Determines the correct lowlevel drawing method depending on several    factors.        Use drawBackgroundThruNativeBuffer() if:            - Painter does not have an HDC            - Theme part is flipped (mirrored horizontally)        else use drawBackgroundDirectly().*/void QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData){    if (themeData.rect.isEmpty())        return;    QPainter *painter = themeData.painter;    Q_ASSERT_X(painter != 0, "QWindowsXPStylePrivate::drawBackground()", "Trying to draw a theme part without a painter");    if (!painter)        return;    painter->save();    QMatrix m = painter->matrix();    bool complexXForm = m.m11() != 1.0 || m.m22() != 1.0 || m.m12() != 0.0 || m.m21() != 0.0;    bool useFallback = painter->paintEngine()->getDC() == 0                       || themeData.rotate                       || complexXForm	               || themeData.mirrorVertically	               || (themeData.mirrorHorizontally && pDrawThemeBackgroundEx == 0);    if (!useFallback)        drawBackgroundDirectly(themeData);    else        drawBackgroundThruNativeBuffer(themeData);    painter->restore();}/*! \internal    This function draws the theme parts directly to the paintengines HDC.    Do not use this if you need to perform other transformations on the    resulting data.*/void QWindowsXPStylePrivate::drawBackgroundDirectly(XPThemeData &themeData){    QPainter *painter = themeData.painter;    HDC dc = painter->paintEngine()->getDC();    QPoint redirectionDelta(int(painter->deviceMatrix().dx()),                            int(painter->deviceMatrix().dy()));    QRect area = themeData.rect.translated(redirectionDelta);    QRegion sysRgn = painter->paintEngine()->systemClip();    if (sysRgn.isEmpty())        sysRgn = area;    else        sysRgn &= area;    if (painter->hasClipping())        sysRgn &= painter->clipRegion().translated(redirectionDelta);    SelectClipRgn(dc, sysRgn.handle());#ifdef DEBUG_XP_STYLE        printf("---[ DIRECT PAINTING ]------------------> Name(%-10s) Part(%d) State(%d)\n",               qPrintable(themeData.name), themeData.partId, themeData.stateId);        showProperties(themeData);#endif    RECT drawRECT = themeData.toRECT(area);    DTBGOPTS drawOptions;    drawOptions.dwSize = sizeof(drawOptions);    drawOptions.rcClip = themeData.toRECT(sysRgn.boundingRect());    drawOptions.dwFlags = DTBG_CLIPRECT                          | (themeData.noBorder ? DTBG_OMITBORDER : 0)                          | (themeData.noContent ? DTBG_OMITCONTENT : 0)                          | (themeData.mirrorHorizontally ? DTBG_MIRRORDC : 0);    if (pDrawThemeBackgroundEx != 0) {        pDrawThemeBackgroundEx(themeData.handle(), dc, themeData.partId, themeData.stateId, &(drawRECT), &drawOptions);    } else {	// We are running on a system where the uxtheme.dll does not have	// the DrawThemeBackgroundEx function, so we need to clip away	// borders or contents manually. All flips and mirrors uses the	// fallback implementation	int borderSize = 0;	PROPERTYORIGIN origin = PO_NOTFOUND;	pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &origin);        pGetThemeInt(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &borderSize);	// Clip away border region        QRegion extraClip = sysRgn;	if ((origin == PO_CLASS || origin == PO_PART || origin == PO_STATE) && borderSize > 0) {	    if (themeData.noBorder) {		// extraClip &= area is already done		drawRECT = themeData.toRECT(area.adjusted(-borderSize, -borderSize, borderSize, borderSize));	    }	    // Clip away content region	    if (themeData.noContent) {		QRegion content = area.adjusted(borderSize, borderSize, -borderSize, -borderSize);		extraClip ^= content;	    }	    // Set the clip region, if used..	    if (themeData.noBorder || themeData.noContent)		SelectClipRgn(dc, extraClip.handle());        }	pDrawThemeBackground(themeData.handle(), dc, themeData.partId, themeData.stateId, &(drawRECT), &(drawOptions.rcClip));    }    SelectClipRgn(dc, 0);}/*! \internal    This function uses a secondary Native doublebuffer for painting parts.    It should only be used when the painteengine doesn't provide a proper    HDC for direct painting (e.g. when doing a grabWidget(), painting to    other pixmaps etc), or when special transformations are needed (e.g.    flips (horizonal mirroring only, vertical are handled by the theme    engine).*/void QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeData){    QPainter *painter = themeData.painter;    QRect rect = themeData.rect;    if ((themeData.rotate + 90) % 180 == 0) { // Catch 90,270,etc.. degree flips.        rect = QRect(0, 0, rect.height(), rect.width());    }    rect.moveTo(0,0);    int partId = themeData.partId;    int stateId = themeData.stateId;    int w = rect.width();    int h = rect.height();    // Values initialized later, either from cached values, or from function calls    AlphaChannelType alphaType = UnknownAlpha;    bool stateHasData = true; // We assume so;    bool hasAlpha = false;    bool partIsTransparent;    bool inspectData;    bool potentialInvalidAlpha;    QString pixmapCacheKey = QString("$qt_xp_%1p%2s%3s%4b%5c%6w%7h").arg(themeData.name)                             .arg(partId).arg(stateId).arg(!themeData.noBorder).arg(!themeData.noContent)                             .arg(w).arg(h);    QPixmap cachedPixmap;    ThemeMapKey key(themeData);    ThemeMapData data = alphaCache.value(key);    bool haveCachedPixmap = false;    bool isCached = data.dataValid;    if (isCached) {        if (!(stateHasData = data.hasAnyData))            return; // Cached NOOP        inspectData = data.wasAlphaSwapped;        partIsTransparent = data.partIsTransparent;        hasAlpha = data.hasAlphaChannel;        alphaType = data.alphaType;        potentialInvalidAlpha = data.hadInvalidAlpha;        haveCachedPixmap = QPixmapCache::find(pixmapCacheKey, cachedPixmap);#ifdef DEBUG_XP_STYLE        char buf[25];        ::sprintf(buf, "+ Pixmap(%3d, %3d) ]", w, h);        printf("---[ CACHED %s--------> Name(%-10s) Part(%d) State(%d)\n",               haveCachedPixmap ? buf : "]-------------------",               qPrintable(themeData.name), themeData.partId, themeData.stateId);#endif    } else {        // Not cached, so get values from Theme Engine        BOOL tmt_borderonly = false;        COLORREF tmt_transparentcolor = 0x0;        PROPERTYORIGIN proporigin = PO_NOTFOUND;        pGetThemeBool(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERONLY, &tmt_borderonly);        pGetThemeColor(themeData.handle(), themeData.partId, themeData.stateId, TMT_TRANSPARENTCOLOR, &tmt_transparentcolor);        pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_CAPTIONMARGINS, &proporigin);        inspectData = (tmt_transparentcolor != 0 || tmt_borderonly || proporigin == PO_PART || proporigin == PO_STATE);        partIsTransparent = isTransparent(themeData);        potentialInvalidAlpha = false;        pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_GLYPHTYPE, &proporigin);        if (proporigin == PO_PART || proporigin == PO_STATE) {            int tmt_glyphtype = GT_NONE;            pGetThemeEnumValue(themeData.handle(), themeData.partId, themeData.stateId, TMT_GLYPHTYPE, &tmt_glyphtype);            potentialInvalidAlpha = partIsTransparent && !inspectData && tmt_glyphtype == GT_IMAGEGLYPH;        }#ifdef DEBUG_XP_STYLE        printf("---[ NOT CACHED ]-----------------------> Name(%-10s) Part(%d) State(%d)\n",               qPrintable(themeData.name), themeData.partId, themeData.stateId);        printf("-->partIsTransparen      = %d\n", partIsTransparent);        printf("-->inspectData           = %d\n", inspectData);        printf("-->potentialInvalidAlpha = %d\n", potentialInvalidAlpha);        showProperties(themeData);#endif    }    bool wasAlphaSwapped = false;    bool wasAlphaFixed = false;    // OLD PSDK Workaround ------------------------------------------------------------------------    // See if we need extra clipping for the older PSDK, which does    // not have a DrawThemeBackgroundEx function for DTGB_OMITBORDER    // and DTGB_OMITCONTENT    bool addBorderContentClipping = false;    QRegion extraClip;    QRect area = rect;    if (themeData.noBorder || themeData.noContent) {	extraClip = area;	// We are running on a system where the uxtheme.dll does not have	// the DrawThemeBackgroundEx function, so we need to clip away	// borders or contents manually.	int borderSize = 0;	PROPERTYORIGIN origin = PO_NOTFOUND;	pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &origin);	pGetThemeInt(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &borderSize);	// Clip away border region	if ((origin == PO_CLASS || origin == PO_PART || origin == PO_STATE) && borderSize > 0) {	    if (themeData.noBorder) {		extraClip &= area;		area = area.adjusted(-borderSize, -borderSize, borderSize, borderSize);	    }	    // Clip away content region	    if (themeData.noContent) {		QRegion content = area.adjusted(borderSize, borderSize, -borderSize, -borderSize);		extraClip ^= content;	    }	}	addBorderContentClipping = (themeData.noBorder | themeData.noContent);    }    QImage img;    if (!haveCachedPixmap) { // If the pixmap is not cached, generate it! -------------------------        buffer(w, h); // Ensure a buffer of at least (w, h) in size        HDC dc = bufferHDC();        // Clear the buffer        if (alphaType != NoAlpha) {            // Consider have separate "memset" function for small chunks for more speedup            memset(bufferPixels, inspectData ? 0xFF : 0x00, bufferW * h * 4);        }	// Difference between area and rect	int dx = area.x() - rect.x();	int dy = area.y() - rect.y();	int dr = area.right() - rect.right();	int db = area.bottom() - rect.bottom();	// Adjust so painting rect starts from Origo	rect.moveTo(0,0);        area.moveTo(dx,dy);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -