diff --git a/dll/win32/gdiplus/metafile.c b/dll/win32/gdiplus/metafile.c index 08dde2fec62..3e318a676f7 100644 --- a/dll/win32/gdiplus/metafile.c +++ b/dll/win32/gdiplus/metafile.c @@ -2517,6 +2517,10 @@ GpStatus WINGDIPAPI GdipPlayMetafileRecord(GDIPCONST GpMetafile *metafile, return Ok; } + case EMR_BITBLT: + case EMR_STRETCHBLT: + SetStretchBltMode(metafile->playback_dc,HALFTONE); + break; default: { ENHMETARECORD *record = heap_alloc_zero(dataSize + 8); diff --git a/win32ss/gdi/dib/dib32bpp.c b/win32ss/gdi/dib/dib32bpp.c index 2b752556cda..79e57986ee6 100644 --- a/win32ss/gdi/dib/dib32bpp.c +++ b/win32ss/gdi/dib/dib32bpp.c @@ -810,17 +810,22 @@ DIB_32BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect, while (++Cols <= DestRect->right - DestRect->left) { SrcPixel.ul = DIB_GetSource(Source, SrcX, SrcY, ColorTranslation); + DstPixel.ul = *Dst; + SrcPixel.col.red = (SrcPixel.col.red * BlendFunc.SourceConstantAlpha) / 255; SrcPixel.col.green = (SrcPixel.col.green * BlendFunc.SourceConstantAlpha) / 255; - SrcPixel.col.blue = (SrcPixel.col.blue * BlendFunc.SourceConstantAlpha) / 255; - SrcPixel.col.alpha = (32 == SrcBpp) ? + SrcPixel.col.blue = ( SrcPixel.col.blue * BlendFunc.SourceConstantAlpha) / 255; + if(BlendFunc.AlphaFormat & AC_SRC_ALPHA && BlendFunc.SourceConstantAlpha == 0xFF && DstPixel.col.alpha == 0 && SrcPixel.col.alpha == 0 && (SrcPixel.col.red + SrcPixel.col.blue + SrcPixel.col.green) > 0) + //FIXME! Not really sure how this condition prevent new icons on tdx + SrcPixel.col.alpha = 0xFF; + else + SrcPixel.col.alpha = (32 == SrcBpp) ? (SrcPixel.col.alpha * BlendFunc.SourceConstantAlpha) / 255 : BlendFunc.SourceConstantAlpha ; Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ? SrcPixel.col.alpha : BlendFunc.SourceConstantAlpha ; - DstPixel.ul = *Dst; DstPixel.col.red = Clamp8((DstPixel.col.red * (255 - Alpha)) / 255 + SrcPixel.col.red) ; DstPixel.col.green = Clamp8((DstPixel.col.green * (255 - Alpha)) / 255 + SrcPixel.col.green) ; DstPixel.col.blue = Clamp8((DstPixel.col.blue * (255 - Alpha)) / 255 + SrcPixel.col.blue) ; diff --git a/win32ss/gdi/gdi32/objects/bitmap.c b/win32ss/gdi/gdi32/objects/bitmap.c index 438521f69e9..86651b6629a 100644 --- a/win32ss/gdi/gdi32/objects/bitmap.c +++ b/win32ss/gdi/gdi32/objects/bitmap.c @@ -621,7 +621,7 @@ SetDIBits( dwWidth = lpbmi->bmiHeader.biWidth; dwHeight = abs(lpbmi->bmiHeader.biHeight); } - + LinesCopied = SetDIBitsToDevice(SavehDC, 0, 0, dwWidth, dwHeight, 0, 0, uStartScan, cScanLines, (void *) lpvBits, (LPBITMAPINFO) lpbmi, fuColorUse); @@ -669,6 +669,9 @@ SetDIBitsToDevice( if (!ScanLines || !lpbmi || !Bits) return 0; + + if (StartScan > ScanLines) + return 0; if (ColorUse && ColorUse != DIB_PAL_COLORS && ColorUse != DIB_PAL_COLORS + 1) return 0; @@ -729,7 +732,7 @@ SetDIBitsToDevice( ScanLines = pConvertedInfo->bmiHeader.biHeight; } - cjBmpScanSize = DIB_BitmapMaxBitsSize((LPBITMAPINFO) lpbmi, ScanLines); + cjBmpScanSize = DIB_BitmapMaxBitsSize((LPBITMAPINFO) lpbmi, (Height == 0 ? ScanLines: min(abs(Height),ScanLines)) + abs(YSrc)); pvSafeBits = RtlAllocateHeap(GetProcessHeap(), 0, cjBmpScanSize); if (pvSafeBits) @@ -742,16 +745,20 @@ SetDIBitsToDevice( { Hit = TRUE; } - _SEH2_END + _SEH2_END; if (Hit) { // We don't die, we continue on with a allocated safe pointer to kernel // space..... - DPRINT1("SetDIBitsToDevice fail to read BitMapInfo: %p or Bits: %p & Size: %u\n", - pConvertedInfo, Bits, cjBmpScanSize); + DPRINT1("SetDIBitsToDevice fail to read BitMapInfo: %p or Bits: %p & Size: %u Height: %u ScanLines: %u.\n", + pConvertedInfo, pvSafeBits, cjBmpScanSize, Height, ScanLines); + + LinesCopied = 0; + goto Exit; } - DPRINT("SetDIBitsToDevice Allocate Bits %u!!!\n", cjBmpScanSize); + else + DPRINT("SetDIBitsToDevice Allocate Bits %u!!!\n", cjBmpScanSize); } if (!GdiGetHandleUserData(hdc, GDI_OBJECT_TYPE_DC, (PVOID) & pDc_Attr)) diff --git a/win32ss/gdi/ntgdi/bitblt.c b/win32ss/gdi/ntgdi/bitblt.c index 2e3eaeef0b2..4fe8bf9c1b2 100644 --- a/win32ss/gdi/ntgdi/bitblt.c +++ b/win32ss/gdi/ntgdi/bitblt.c @@ -112,24 +112,43 @@ NtGdiAlphaBlend( /* Determine surfaces to be used in the bitblt */ BitmapDest = DCDest->dclevel.pSurface; - if (!BitmapDest) + BitmapSrc = DCSrc->dclevel.pSurface; + if (!BitmapDest || !BitmapSrc) { bResult = FALSE ; goto leave ; } - BitmapSrc = DCSrc->dclevel.pSurface; - if (!BitmapSrc) - { - bResult = FALSE; - goto leave; + if(BitmapDest == BitmapSrc && SourceRect.left < DestRect.right && SourceRect.right > DestRect.left && SourceRect.top > DestRect.bottom && SourceRect.bottom < DestRect.top ){ + bResult = FALSE ; + goto leave ; } + if(abs(DestRect.right - DestRect.left) != abs(SourceRect.right - SourceRect.left) || abs(DestRect.top - DestRect.bottom) != abs(SourceRect.top - SourceRect.bottom)){ + DCDest->pdcattr->lStretchBltMode = DCDest->pdcattr->jStretchBltMode; + DCDest->pdcattr->jStretchBltMode = COLORONCOLOR; + + NtGdiStretchBlt(hDCSrc, + XOriginDest, + YOriginDest, + WidthDest, + HeightDest, + hDCSrc, + 0, + 0, + WidthSrc, + HeightSrc, + SRCCOPY, + 0); + SourceRect = DestRect; + } + /* Create the XLATEOBJ. */ EXLATEOBJ_vInitXlateFromDCs(&exlo, DCSrc, DCDest); /* Perform the alpha blend operation */ TRACE("Performing the alpha blend\n"); + bResult = IntEngAlphaBlend(&BitmapDest->SurfObj, &BitmapSrc->SurfObj, (CLIPOBJ *)&DCDest->co, @@ -296,10 +315,21 @@ NtGdiTransparentBlt( EXLATEOBJ_vInitXlateFromDCs(&exlo, DCSrc, DCDest); + int old_mode = DCDest->pdcattr->lStretchBltMode; + if(DCSrc->dcattr.jStretchBltMode == WHITEONBLACK || DCSrc->dcattr.jStretchBltMode == BLACKONWHITE){ + DCDest->pdcattr->lStretchBltMode = DCSrc->pdcattr->jStretchBltMode; + DCDest->pdcattr->jStretchBltMode = COLORONCOLOR; + } + Ret = IntEngTransparentBlt(&BitmapDest->SurfObj, &BitmapSrc->SurfObj, (CLIPOBJ *)&DCDest->co, &exlo.xlo, &rcDest, &rcSrc, TransparentColor, 0); + if (!Ret){ + DCDest->pdcattr->jStretchBltMode = DCDest->pdcattr->lStretchBltMode; + DCDest->pdcattr->lStretchBltMode = old_mode; + } + EXLATEOBJ_vCleanup(&exlo); done: diff --git a/win32ss/gdi/ntgdi/dclife.c b/win32ss/gdi/ntgdi/dclife.c index caa66eda073..99bcfe6fa6f 100644 --- a/win32ss/gdi/ntgdi/dclife.c +++ b/win32ss/gdi/ntgdi/dclife.c @@ -119,7 +119,6 @@ DC_InitHack(PDC pdc) TextIntRealizeFont(pdc->pdcattr->hlfntNew,NULL); pdc->pdcattr->iCS_CP = ftGdiGetTextCharsetInfo(pdc,NULL,0); - /* This should never fail */ ASSERT(pdc->dclevel.ppal); } @@ -298,8 +297,8 @@ DC_vInitDc( pdc->dcattr.lBkMode = 2; pdc->dcattr.jFillMode = ALTERNATE; pdc->dcattr.lFillMode = 1; - pdc->dcattr.jStretchBltMode = 1; - pdc->dcattr.lStretchBltMode = 1; + pdc->dcattr.jStretchBltMode = STRETCH_ANDSCANS; + pdc->dcattr.lStretchBltMode = STRETCH_ANDSCANS; pdc->ptlFillOrigin.x = 0; pdc->ptlFillOrigin.y = 0; diff --git a/win32ss/gdi/ntgdi/dibobj.c b/win32ss/gdi/ntgdi/dibobj.c index 6c6dd53e941..70985269f91 100644 --- a/win32ss/gdi/ntgdi/dibobj.c +++ b/win32ss/gdi/ntgdi/dibobj.c @@ -495,6 +495,15 @@ NtGdiSetDIBitsToDeviceInternal( BOOL bResult; if (!Bits) return 0; + + ScanLines = (Height == 0 ? ScanLines: min(abs(Height),ScanLines)) + abs(YSrc); + + if (ScanLines == 0) + { + DPRINT1("ScanLines == 0\n"); + ret = 0; + goto Exit; + } pbmiSafe = ExAllocatePoolWithTag(PagedPool, cjMaxInfo, 'pmTG'); if (!pbmiSafe) return 0; @@ -513,14 +522,6 @@ NtGdiSetDIBitsToDeviceInternal( } _SEH2_END; - ScanLines = min(ScanLines, abs(bmi->bmiHeader.biHeight) - StartScan); - if (ScanLines == 0) - { - DPRINT1("ScanLines == 0\n"); - ret = 0; - goto Exit; - } - pDC = DC_LockDc(hDC); if (!pDC) { @@ -561,7 +562,7 @@ NtGdiSetDIBitsToDeviceInternal( //DIBWidth = WIDTH_BYTES_ALIGN32(SourceSize.cx, bmi->bmiHeader.biBitCount); hSourceBitmap = GreCreateBitmapEx(bmi->bmiHeader.biWidth, - ScanLines, + ScanLines + abs(YSrc), 0, BitmapFormat(bmi->bmiHeader.biBitCount, bmi->bmiHeader.biCompression), @@ -608,6 +609,7 @@ NtGdiSetDIBitsToDeviceInternal( /* Create a palette for the DIB */ ppalDIB = CreateDIBPalette(bmi, pDC, ColorUse); + if (!ppalDIB) { EngSetLastError(ERROR_NO_SYSTEM_RESOURCES); @@ -634,13 +636,13 @@ NtGdiSetDIBitsToDeviceInternal( RGB(0xff, 0xff, 0xff), pDC->pdcattr->crBackgroundClr, pDC->pdcattr->crForegroundClr); - + pDestSurf = &pSurf->SurfObj; /* Copy the bits */ - DPRINT("BitsToDev with rcDest=(%d|%d) (%d|%d), ptSource=(%d|%d) w=%d h=%d\n", + DPRINT("BitsToDev with rcDest=(%d|%d) (%d|%d), ptSource=(%d|%d) w=%d h=%d ScanLines=%lu Height=%lu Width=%lu pDC->ptlDCOrig.x=%lu pDC->ptlDCOrig.y=%lu bmi->bmiHeader.biCompression=%lu XSrc=%d YSrc=%d Width=%lu Height=%lu StartScan=%lu XDest=%d YDest=%d\n", rcDest.left, rcDest.top, rcDest.right, rcDest.bottom, - ptSource.x, ptSource.y, SourceSize.cx, SourceSize.cy); + ptSource.x, ptSource.y, SourceSize.cx, SourceSize.cy,ScanLines,Height,Width,pDC->ptlDCOrig.x,pDC->ptlDCOrig.y, bmi->bmiHeader.biCompression,XSrc,YSrc,Width,Height,StartScan,XDest,YDest); /* This fixes the large Google text on Google.com from being upside down */ if (rcDest.top > rcDest.bottom) @@ -649,6 +651,12 @@ NtGdiSetDIBitsToDeviceInternal( ptSource.y -= SourceSize.cy; } + ROP4 rop4; + if(ppalDIB->flFlags == (PAL_BGR | PAL_BITFIELDS) && pSurf->ppal->flFlags == (PAL_BGR | PAL_BITFIELDS)) + rop4 = ROP4_SRCAND; + else + rop4 = ROP4_SRCCOPY; + bResult = IntEngBitBlt(pDestSurf, pSourceSurf, pMaskSurf, @@ -659,8 +667,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); @@ -677,7 +684,7 @@ Exit: if (pMaskSurf) EngUnlockSurface(pMaskSurf); if (hMaskBitmap) EngDeleteSurface((HSURF)hMaskBitmap); if (pDC) DC_UnlockDc(pDC); - ExFreePoolWithTag(pbmiSafe, 'pmTG'); + if (pbmiSafe) ExFreePoolWithTag(pbmiSafe, 'pmTG'); return ret; } @@ -1378,6 +1385,7 @@ NtGdiStretchDIBitsInternal( } else { + NtGdiStretchBlt(hdc, xDst, yDst, cxDst, cyDst, hdcMem, xSrc, abs(pbmiSafe->bmiHeader.biHeight) - cySrc - ySrc, cxSrc, cySrc, dwRop, 0); @@ -1463,8 +1471,8 @@ NtGdiStretchDIBitsInternal( RGB(0xff, 0xff, 0xff), pdc->pdcattr->crBackgroundClr, pdc->pdcattr->crForegroundClr); - - /* Perform the stretch operation */ + + /* Perform the stretch operation */ IntEngStretchBlt(&psurfDst->SurfObj, &psurfTmp->SurfObj, NULL, @@ -1899,9 +1907,9 @@ DIB_CreateDIBSection( //SIZEL Size; HANDLE hSecure; - DPRINT("format (%ld,%ld), planes %u, bpp %u, size %lu, colors %lu (%s)\n", + DPRINT("format (%ld,%ld), planes %u, bpp %u, size %lu, colors %lu (%s) offset (%lu)\n", bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount, - bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB"); + bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB",offset); /* CreateDIBSection should fail for compressed formats */ if (bi->biCompression == BI_RLE4 || bi->biCompression == BI_RLE8) @@ -1910,7 +1918,8 @@ DIB_CreateDIBSection( return (HBITMAP)NULL; } - effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight; + + effHeight = abs(bi->biHeight); bm.bmType = 0; bm.bmWidth = bi->biWidth; bm.bmHeight = effHeight; @@ -1989,7 +1998,7 @@ DIB_CreateDIBSection( //Size.cx = bm.bmWidth; //Size.cy = abs(bm.bmHeight); res = GreCreateBitmapEx(bm.bmWidth, - abs(bm.bmHeight), + bm.bmHeight, bm.bmWidthBytes, BitmapFormat(bi->biBitCount * bi->biPlanes, bi->biCompression), BMF_DONTCACHE | BMF_USERMEM | BMF_NOZEROINIT |