X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/d80f416f62c1fa60f020a785bee98ce71c749a42..41b78190adf985fa6e91a34aba76b1693a8ffc72:/src/msw/dc.cpp diff --git a/src/msw/dc.cpp b/src/msw/dc.cpp index e36e35dfc8..ad43d3aa01 100644 --- a/src/msw/dc.cpp +++ b/src/msw/dc.cpp @@ -45,6 +45,10 @@ #include "wx/module.h" #include "wx/dynload.h" +#ifdef wxHAVE_RAW_BITMAP +#include "wx/rawbmp.h" +#endif + #include #include @@ -58,6 +62,10 @@ #include #endif +#ifndef AC_SRC_ALPHA +#define AC_SRC_ALPHA 1 +#endif + /* Quaternary raster codes */ #ifndef MAKEROP4 #define MAKEROP4(fore,back) (DWORD)((((back) << 8) & 0xFF000000) | (fore)) @@ -109,6 +117,13 @@ static const int MM_METRIC = 10; // convert degrees to radians static inline double DegToRad(double deg) { return (deg * M_PI) / 180.0; } + +#ifdef wxHAVE_RAW_BITMAP +// our (limited) AlphaBlend() replacement +static void +wxAlphaBlend(wxDC& dc, int x, int y, int w, int h, const wxBitmap& bmp); +#endif + // ---------------------------------------------------------------------------- // private classes // ---------------------------------------------------------------------------- @@ -647,7 +662,7 @@ void wxDC::DoDrawCheckMark(wxCoord x1, wxCoord y1, wxCoord x2 = x1 + width, y2 = y1 + height; -#if defined(__WIN32__) && !defined(__SC__) && !defined(__WXMICROWIN__) +#if defined(__WIN32__) && !defined(__SYMANTEC__) && !defined(__WXMICROWIN__) RECT rect; rect.left = x1; rect.top = y1; @@ -983,26 +998,29 @@ void wxDC::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask MemoryHDC hdcMem; SelectInHDC select(hdcMem, GetHbitmapOf(bmp)); -#ifndef AC_SRC_ALPHA - #define AC_SRC_ALPHA 1 -#endif - BLENDFUNCTION bf; bf.BlendOp = AC_SRC_OVER; bf.BlendFlags = 0; bf.SourceConstantAlpha = 0xff; bf.AlphaFormat = AC_SRC_ALPHA; - if ( !pfnAlphaBlend(GetHdc(), x, y, width, height, - hdcMem, 0, 0, width, height, - bf) ) + if ( pfnAlphaBlend(GetHdc(), x, y, width, height, + hdcMem, 0, 0, width, height, + bf) ) { - wxLogLastError(_T("AlphaBlend")); + // skip wxAlphaBlend() call below + return; } - return; + wxLogLastError(_T("AlphaBlend")); } - //else: AlphaBlend() not available + + // use our own (probably much slower) implementation +#ifdef wxHAVE_RAW_BITMAP + wxAlphaBlend(*this, x, y, width, height, bmp); +#endif // wxHAVE_RAW_BITMAP + + return; } #endif // defined(AC_SRC_OVER) @@ -2146,6 +2164,10 @@ void wxDC::SetLogicalScale(double x, double y) m_logicalScaleY = y; } +// ---------------------------------------------------------------------------- +// DC caching +// ---------------------------------------------------------------------------- + #if wxUSE_DC_CACHEING /* @@ -2186,10 +2208,10 @@ wxDCCacheEntry::~wxDCCacheEntry() wxDCCacheEntry* wxDC::FindBitmapInCache(WXHDC dc, int w, int h) { int depth = ::GetDeviceCaps((HDC) dc, PLANES) * ::GetDeviceCaps((HDC) dc, BITSPIXEL); - wxNode* node = sm_bitmapCache.First(); + wxNode* node = sm_bitmapCache.GetFirst(); while (node) { - wxDCCacheEntry* entry = (wxDCCacheEntry*) node->Data(); + wxDCCacheEntry* entry = (wxDCCacheEntry*) node->GetData(); if (entry->m_depth == depth) { @@ -2207,7 +2229,7 @@ wxDCCacheEntry* wxDC::FindBitmapInCache(WXHDC dc, int w, int h) return entry; } - node = node->Next(); + node = node->GetNext(); } WXHBITMAP hBitmap = (WXHBITMAP) ::CreateCompatibleBitmap((HDC) dc, w, h); if ( !hBitmap) @@ -2222,10 +2244,10 @@ wxDCCacheEntry* wxDC::FindBitmapInCache(WXHDC dc, int w, int h) wxDCCacheEntry* wxDC::FindDCInCache(wxDCCacheEntry* notThis, WXHDC dc) { int depth = ::GetDeviceCaps((HDC) dc, PLANES) * ::GetDeviceCaps((HDC) dc, BITSPIXEL); - wxNode* node = sm_dcCache.First(); + wxNode* node = sm_dcCache.GetFirst(); while (node) { - wxDCCacheEntry* entry = (wxDCCacheEntry*) node->Data(); + wxDCCacheEntry* entry = (wxDCCacheEntry*) node->GetData(); // Don't return the same one as we already have if (!notThis || (notThis != entry)) @@ -2236,7 +2258,7 @@ wxDCCacheEntry* wxDC::FindDCInCache(wxDCCacheEntry* notThis, WXHDC dc) } } - node = node->Next(); + node = node->GetNext(); } WXHDC hDC = (WXHDC) ::CreateCompatibleDC((HDC) dc); if ( !hDC) @@ -2281,6 +2303,66 @@ private: IMPLEMENT_DYNAMIC_CLASS(wxDCModule, wxModule) -#endif - // wxUSE_DC_CACHEING +#endif // wxUSE_DC_CACHEING + +// ---------------------------------------------------------------------------- +// wxAlphaBlend: our fallback if ::AlphaBlend() is unavailable +// ---------------------------------------------------------------------------- + +#ifdef wxHAVE_RAW_BITMAP +static void +wxAlphaBlend(wxDC& dc, int xDst, int yDst, int w, int h, const wxBitmap& bmpSrc) +{ + // get the destination DC pixels + wxBitmap bmpDst(w, h, 32 /* force creating RGBA DIB */); + MemoryHDC hdcMem; + SelectInHDC select(hdcMem, GetHbitmapOf(bmpDst)); + + if ( !::BitBlt(hdcMem, 0, 0, w, h, GetHdcOf(dc), 0, 0, SRCCOPY) ) + { + wxLogLastError(_T("BitBlt")); + } + + // combine them with the source bitmap using alpha + wxAlphaPixelData dataDst(bmpDst), + dataSrc((wxBitmap &)bmpSrc); + + wxCHECK_RET( dataDst && dataSrc, + _T("failed to get raw data in wxAlphaBlend") ); + + wxAlphaPixelData::Iterator pDst(dataDst), + pSrc(dataSrc); + + for ( int y = 0; y < h; y++ ) + { + wxAlphaPixelData::Iterator pDstRowStart = pDst, + pSrcRowStart = pSrc; + + for ( int x = 0; x < w; x++ ) + { + // note that source bitmap uses premultiplied alpha (as required by + // the real AlphaBlend) + const unsigned beta = 255 - pSrc.Alpha(); + + pDst.Red() = pSrc.Red() + (beta * pDst.Red() + 127) / 255; + pDst.Blue() = pSrc.Blue() + (beta * pDst.Blue() + 127) / 255; + pDst.Green() = pSrc.Green() + (beta * pDst.Green() + 127) / 255; + + ++pDst; + ++pSrc; + } + + pDst = pDstRowStart; + pSrc = pSrcRowStart; + pDst.OffsetY(dataDst, 1); + pSrc.OffsetY(dataSrc, 1); + } + + // and finally blit them back to the destination DC + if ( !::BitBlt(GetHdcOf(dc), xDst, yDst, w, h, hdcMem, 0, 0, SRCCOPY) ) + { + wxLogLastError(_T("BitBlt")); + } +} +#endif // #ifdef wxHAVE_RAW_BITMAP