// Note we only support 8bpp DIBs here, and.. // there is no regard for color table matching between the DIBs //************************************************************************ void CDib::DibBlt(PDIB pdibDst, int dstLeft, int dstTop, int dstWidth, int dstHeight, int srcLeft, int srcTop, int srcWidth, int srcHeight, BOOL bTransparent, LPRGBTRIPLE lpRGB, LPTR lpLut, HPALETTE hPal ) //************************************************************************ { HPTR pSrc, pDst; int iScanS, iScanD, iOverrun; if ( !pdibDst ) return; if ( GetBitCount() != 8 ) return; if ( pdibDst->GetBitCount() != 8 ) return; // Check the coordinate bounds, to avoid an out of range pointer if ( srcLeft < 0 ) { dstLeft -= srcLeft; srcWidth += srcLeft; dstWidth += srcLeft; srcLeft = 0; } if ( srcTop < 0 ) { dstTop -= srcTop; srcHeight += srcTop; dstHeight += srcTop; srcTop = 0; } if ( dstLeft < 0 ) { srcLeft -= dstLeft; srcWidth += dstLeft; dstWidth += dstLeft; dstLeft = 0; } if ( dstTop < 0 ) { srcTop -= dstTop; srcHeight += dstTop; dstHeight += dstTop; dstTop = 0; } if ( srcWidth <= 0 || srcHeight <= 0 || dstWidth <= 0 || dstHeight <= 0 ) return; if ( srcLeft - GetWidth() >= 0 ) return; if ( srcTop - abs(GetHeight()) >= 0 ) return; if ( dstLeft - pdibDst->GetWidth() >= 0 ) return; if ( dstTop - abs(pdibDst->GetHeight()) >= 0 ) return; if ( (iOverrun = srcLeft + srcWidth - GetWidth()) > 0 ) { srcWidth -= iOverrun; dstWidth -= iOverrun; } if ( (iOverrun = srcTop + srcHeight - abs(GetHeight())) > 0 ) { srcHeight -= iOverrun; dstHeight -= iOverrun; } if ( (iOverrun = dstLeft + dstWidth - pdibDst->GetWidth()) > 0 ) { dstWidth -= iOverrun; srcWidth -= iOverrun; } if ( (iOverrun = dstTop + dstHeight - abs(pdibDst->GetHeight())) > 0 ) { dstHeight -= iOverrun; srcHeight -= iOverrun; } if ( srcWidth <= 0 || srcHeight <= 0 || dstWidth <= 0 || dstHeight <= 0 ) return; // Get pointers to the start points in the source and destination if ( !(pSrc = GetXY( srcLeft, srcTop )) ) return; if ( !(pDst = pdibDst->GetXY( dstLeft, dstTop )) ) return; // Get the scan line widths of each DIB. iScanS = GetWidthBytes(); iScanD = pdibDst->GetWidthBytes(); // Upside down DIBs have to move backwards if ( GetHeight() > 0 ) iScanS = -iScanS; if ( pdibDst->GetHeight() > 0 ) iScanD = -iScanD; if ( !bTransparent ) { // Copy the lines. while ( --srcHeight >= 0 ) { hmemcpy( pDst, pSrc, srcWidth ); pSrc += iScanS; pDst += iScanD; } } else if (lpRGB) { // Copy lines with transparency mask WORD src, dst, wMini; BYTE dstPixel, srcColor, red, green, blue; int iSinc, iDinc, iCount; LPRGBQUAD pTable = GetColors(); if (lpLut) { wMini = RGB3toMiniRGB(lpRGB->rgbtRed, lpRGB->rgbtGreen, lpRGB->rgbtBlue); srcColor = lpLut[wMini]; } else if (hPal) { srcColor = (BYTE)GetNearestPaletteIndex( hPal, RGB(lpRGB->rgbtRed, lpRGB->rgbtGreen, lpRGB->rgbtBlue) ); } else srcColor = 0; iSinc = iScanS - srcWidth; // Source increment value iDinc = iScanD - srcWidth; // Destination increment value while ( --srcHeight >= 0 ) { iCount = srcWidth; // Number of pixels to scan. while ( --iCount >= 0 ) { src = (WORD)(*pSrc++); // Copy pixel only if it isn't transparent. if (src == 0) pDst++; else if (src == 255) *pDst++ = srcColor; else { if (src > 127) ++src; dst = 256-src; dstPixel = *pDst; red = (BYTE)((((WORD)lpRGB->rgbtRed * src) + ((WORD)pTable[dstPixel].rgbRed * dst)) >> 8); green = (BYTE)((((WORD)lpRGB->rgbtGreen * src) + ((WORD)pTable[dstPixel].rgbGreen * dst)) >> 8); blue = (BYTE)((((WORD)lpRGB->rgbtBlue * src) + ((WORD)pTable[dstPixel].rgbBlue * dst)) >> 8); if (lpLut) { wMini = RGB3toMiniRGB(red, green, blue); *pDst++ = lpLut[wMini]; } else if (hPal) { *pDst++ = (BYTE)GetNearestPaletteIndex( hPal, RGB(red, green, blue) ); } else { pDst++; } } } pSrc += iSinc; pDst += iDinc; } } else { // Copy lines with transparency.
BOOL CAliasApp::AntiAliasDib(PDIB pForeDib, PDIB pCompDib) { #ifndef CPO if (pForeDib->GetHeight() != pCompDib->GetHeight() || pForeDib->GetWidth() != pCompDib->GetWidth()) { MessageBox(NULL, "Bitmaps are different sizes", "Error", MB_ICONSTOP|MB_OK); return(FALSE); } if (pForeDib->GetBitCount() != 24 || pCompDib->GetBitCount() != 24) { MessageBox(NULL, "Bitmaps must both be 24-bits", "Error", MB_ICONSTOP|MB_OK); return(FALSE); } RGBS rgb; BOOL fColor; LPTR lpFore = pForeDib->GetPtr(); if (FALSE) rgb.red = rgb.green = rgb.blue = 148; else rgb = *((LPRGB)pForeDib->GetXY(0, 0)); BYTE r = rgb.red; BYTE g = rgb.green; BYTE b = rgb.blue; fColor = ((r == 255 && g == 0 && b == 0) || // red (r == 0 && g == 255 && b == 0) || // green (r == 0 && g == 0 && b == 255) || // blue (r == 0 && g == 255 && b == 255) || // cyan (r == 255 && g == 0 && b == 255) || // magenta (r == 255 && g == 255 && b == 0)); // yellow if (!fColor) { m_rgbTrans.red = 255; m_rgbTrans.green = 0; m_rgbTrans.blue = 255; } else { m_rgbTrans = rgb; } #endif LPTR lpComp = pCompDib->GetPtr(); UINT uWidthBytes = pCompDib->GetWidthBytes(); int iHeight = abs(pCompDib->GetHeight()); while (--iHeight >= 0) { int iWidth = pCompDib->GetWidth(); LPRGB lpC = (LPRGB)lpComp; m_Quantize.CountFrequencies((LPRGBTRIPLE)lpComp, iWidth); #ifndef CPO LPRGB lpF = (LPRGB)lpFore; while (--iWidth >= 0) { if (lpF->red != r || lpF->green != g || lpF->blue != b) { *lpF++ = *lpC++; } else { if (!fColor) { lpF->red = 255; lpF->green = 0; lpF->blue = 255; } ++lpF; ++lpC; } } lpFore += uWidthBytes; #endif lpComp += uWidthBytes; } return(TRUE); }