diff --git "a/win32ss/gdi/ntgdi/dibobj.c" "b/win32ss/gdi/ntgdi/dibobj.c" index 60eb419ca20..4bc85318183 100644 --- "a/win32ss/gdi/ntgdi/dibobj.c" +++ "b/win32ss/gdi/ntgdi/dibobj.c" @@ -36,6 +36,26 @@ static const RGBQUAD DefLogPaletteQuads[20] = /* Copy of Default Logical Palet { 0xff, 0xff, 0xff, 0x00 } }; +BOOL AlphaWithAll0xFF(PBYTE pb, INT Width, INT Height) +{ + BOOL All_xFF = TRUE; + PBYTE Pbyte = pb + 3; + for( int y = 0; y < Height; y++ ) + { + for( int x = 0; x < Width; x++ ) + { + if (Pbyte[0] != 0xff) + All_xFF = FALSE; + Pbyte += 4; + if (!All_xFF) + break; + } + if (!All_xFF) + break; + } + return All_xFF; +} + PPALETTE NTAPI CreateDIBPalette( @@ -498,6 +518,7 @@ NtGdiSetDIBitsToDeviceInternal( PPALETTE ppalDIB = NULL; LPBITMAPINFO pbmiSafe; BOOL bResult; + ROP4 rop4 = ROP4_SRCCOPY; if (!Bits) return 0; @@ -532,7 +553,10 @@ NtGdiSetDIBitsToDeviceInternal( { ScanLines = min(abs(Height), ScanLines); if (YSrc > 0) + { ScanLines += YSrc; + YSrc = 0; + } } else { @@ -582,7 +606,7 @@ NtGdiSetDIBitsToDeviceInternal( SourceSize.cx = bmi->bmiHeader.biWidth; SourceSize.cy = ScanLines; - if (YDest >= 0 && YSrc > 0) + if (YDest >= 0 && YSrc >= 0) { ScanLines += YSrc; } @@ -678,6 +702,20 @@ NtGdiSetDIBitsToDeviceInternal( ptSource.y -= SourceSize.cy; } + + /* Fix for some Delphi apps missing icons in the toolbars. + * It is most likely a HACK, but this works for most cases. */ + /* 1. Are Source & Destination start points all zero? */ + if (XDest == 0 && YDest == 0 && XSrc == 0 && YSrc == 0 && StartScan == 0 && + /* 2. Are Source & Destination heights the same? */ + Height == ScanLines && Height == abs(bmi->bmiHeader.biHeight) && + /* 3. Is the Source bitmap 32 Bit? */ + bmi->bmiHeader.biBitCount == 32 && + /* 4. Do we have Alpha channel with all 0xFF's, but test first Alpha + * value to possibly short circuit having to call test function. */ + Bits[3] == 0xff && AlphaWithAll0xFF(Bits, Width, Height)) + rop4 = ROP4_SRCAND; + bResult = IntEngBitBlt(pDestSurf, pSourceSurf, pMaskSurf, @@ -688,7 +726,7 @@ NtGdiSetDIBitsToDeviceInternal( pMaskSurf ? &ptSource : NULL, NULL, NULL, - pMaskSurf ? ROP4_MASK : ROP4_FROM_INDEX(R3_OPINDEX_SRCCOPY)); + pMaskSurf ? ROP4_MASK : rop4); /* Cleanup EXLATEOBJ */ EXLATEOBJ_vCleanup(&exlo);