📄 scdcrendimages_i.cpp
字号:
/*
* This file is part of the EMFexplorer projet.
* Copyright (C) 2004 Smith Charles.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*
* Extension: for commercial use, apply the Equity Public License, which
* adds to the normal terms of the GLPL a condition of donation to the author.
* If you are interested in support for this source code,
* contact Smith Charles <smith.charles@free.fr> for more information.
*/
#include "stdafx.h"
#include "SCEMFdcRenderer.h"
using namespace Gdiplus;
///////////////////////////////////////////////////////////////////////////////////////
// Images/Pixels management
//
///
/// Draw a DIB bitmap.
///
void CSCEMFdcRenderer::SCDrawImage(LPCRECT pDest, LPCRECT pSrc, LPCBYTE pBits,
LPCBITMAPINFO pBmi, DWORD dwUsage, DWORD dwRop3,
XFORM* pXForm/*=NULL*/)
{
ASSERT(m_pGraphics);
ASSERT(pBmi && pBits && pDest && pSrc);
// dwUsage can be: DIB_PAL_COLORS, DIB_PAL_INDICES, or DIB_RGB_COLORS
ASSERT(dwUsage==DIB_RGB_COLORS || dwUsage==DIB_PAL_COLORS); // the other ones are not managed for now
Bitmap* pBmp = NULL;
HBITMAP hNewBmp = NULL;
if (dwUsage==DIB_PAL_COLORS)
{// Convert bitmap. Otherwise, GDI+ would mess with the color table.
// Use a device-dependent bitmap + current palette combination
HPALETTE hPal = (HPALETTE)::GetCurrentObject(m_hDC, OBJ_PAL);
ASSERT(hPal);
#pragma message( __FILE__ "(43): TODO: create bitmap with destination DC instead of m_hDC ")
hNewBmp = CreateDIBitmap(m_hDC, (BITMAPINFOHEADER*)pBmi, CBM_INIT, pBits, pBmi, dwUsage);
pBmp = new Bitmap(hNewBmp, hPal);
} else
if (4==pBmi->bmiHeader.biBitCount)
{// I don't see why Bitmap(pBmi, (VOID*)pBits) fails. Yet another color table problem?
// tracking occurrences (4-bpp failure on w2k-xls/Tdb_fev00/page0013)
hNewBmp = CreateDIBitmap(m_hDC, (BITMAPINFOHEADER*)pBmi, CBM_INIT, pBits, pBmi, dwUsage);
pBmp = new Bitmap(hNewBmp, (HPALETTE)NULL);
} else
{
// tracking occurrences (8-bpp passed with w98, w95-bmp/swtchbrd,
// 1-bpp passed with "w98, w95-gif/santa workshop")
//ASSERT(pBmi->bmiHeader.biBitCount>8);
pBmp = new Bitmap(pBmi, (VOID*)pBits);
}
ASSERT(pBmp->GetLastStatus()==Ok);
// Note: very special stuff here.
// Convert sizes when a source transformation is present
Matrix SvdMatrix;
RECT rcSrc;
if (pXForm)
{
// save current transform
m_pGraphics->GetTransform(&SvdMatrix);
// Convert the source with the source transform only
// (because pXForm is the "world-space to page-space transformation of
// the source device context" -- not the destination device -- when the record was registered)
CopyRect(&rcSrc, pSrc);
pSrc = &rcSrc;
Matrix matrix(pXForm->eM11, pXForm->eM12, pXForm->eM21, pXForm->eM22,
pXForm->eDx, pXForm->eDy);
matrix.TransformPoints((Point*)pSrc, 2);
}
//
Rect destRect(pDest->left, pDest->top, PRECT_WIDTH(pDest), PRECT_HEIGHT(pDest));
// GDI+ 1.0: the ROP is simply let aside => unexpected results in perspective
// Good place to say: GDI+ does not work!
if (SRCCOPY==dwRop3)
{
// Copies the source rectangle directly to the destination rectangle.
m_pGraphics->DrawImage(pBmp, destRect,
pSrc->left, pSrc->top, PRECT_WIDTH(pSrc), PRECT_HEIGHT(pSrc), UnitPixel, m_pImgAttribs);
}
else
{// At the expense of some CPU time, GDI The Great will be called to do the job.
// Check popular rops
switch (dwRop3)
{
case BLACKNESS:
// Fills the destination rectangle using the color associated with index 0
// in the physical palette.
// (This color is black for the default physical palette.)
SCSysPaletteFillRect(this, destRect, 0);
goto enddraw;
case DSTINVERT:
// Inverts the destination rectangle.
break;
case MERGECOPY:
// Merges the colors of the source rectangle with the specified pattern
// by using the Boolean AND operator.
break;
case MERGEPAINT:
// Merges the colors of the inverted source rectangle with the colors
// of the destination rectangle by using the Boolean OR operator.
break;
case NOTSRCCOPY:
// Copies the inverted source rectangle to the destination.
break;
case NOTSRCERASE:
// Combines the colors of the source and destination rectangles by using
// the Boolean OR operator and then inverts the resultant color.
break;
case PATCOPY:
// Copies the specified pattern into the destination bitmap.
ASSERT(m_pBrush);
if (m_pBrush)
m_pGraphics->FillRectangle(m_pBrush, destRect);
goto enddraw;
case PATINVERT:
// Combines the colors of the specified pattern with the colors of the
// destination rectangle by using the Boolean XOR operator.
break;
case PATPAINT:
// Combines the colors of the pattern with the colors of the inverted
// source rectangle by using the Boolean OR operator. The result of this
// operation is combined with the colors of the destination rectangle by
// using the Boolean OR operator.
break;
case SRCAND:
// Combines the colors of the source and destination rectangles by using
// the Boolean AND operator.
break;
case SRCERASE:
// Combines the inverted colors of the destination rectangle with the
// colors of the source rectangle by using the Boolean AND operator.
break;
case SRCINVERT:
// Combines the colors of the source and destination rectangles by using
// the Boolean XOR operator.
break;
case SRCPAINT:
// Combines the colors of the source and destination rectangles by using
// the Boolean OR operator.
break;
case WHITENESS:
//Fills the destination rectangle using the color associated with index 1
// in the physical palette.
// (This color is white for the default physical palette.)
SCSysPaletteFillRect(this, destRect, 1);
goto enddraw;
//case SRCCOPY: // done
// // Copies the source rectangle directly to the destination rectangle.
// break;
}
// Wild, general rop management:
// 1. if the rop implies the destination we must copy it
// 2. if the rop implies the brush, we must use it
SCStretchDIBits(this,
destRect.X, destRect.Y, destRect.Width, destRect.Height,
pSrc->left, pSrc->top, PRECT_WIDTH(pSrc), PRECT_HEIGHT(pSrc),
pBits, pBmi, dwUsage, dwRop3);
}
enddraw:
if (pXForm)
m_pGraphics->SetTransform(&SvdMatrix);
if (hNewBmp)
DeleteObject(hNewBmp);
delete pBmp;
}
///
/// Draw GDI+ bitmap.
///
void CSCEMFdcRenderer::SCDrawBitmap(Bitmap* pBmp, Rect& rRcDest)
{
ASSERT(m_pGraphics);
ASSERT(pBmp);
m_pGraphics->DrawImage(pBmp, rRcDest,
0, 0, pBmp->GetWidth(), pBmp->GetHeight(), UnitPixel, m_pImgAttribs);
}
///
/// Draw a masked DIB bitmap into a parallelogram.
///
void CSCEMFdcRenderer::SCDrawImagePlg(LPCPOINTL p3PtDest,
LPCRECT pSrc, LPCBYTE pBits, LPCBITMAPINFO pBmi,
DWORD dwUsage, XFORM* pXForm, COLORREF crBkColorSrc,
LONG lxMask, LONG lyMask,
LPCBYTE pBitsMask, LPCBITMAPINFO pBmiMask, DWORD dwUsageMask)
{
ASSERT(m_pGraphics);
ASSERT(pBmi && pBits && p3PtDest && pSrc);
// dwUsage can be: DIB_PAL_COLORS, DIB_PAL_INDICES, or DIB_RGB_COLORS
ASSERT(dwUsage==DIB_RGB_COLORS); // the other ones are not managed for now
// The p3PtDest array contains three points in logical space that identify three
// corners of the destination parallelogram.
// In GDI the mapping is as follows: the upper-left corner of the source rectangle is mapped to
// the first point in this array, the upper-right corner to the second point in this array,
// and the lower-left corner to the third point. The lower-right corner of the source
// rectangle is mapped to the implicit fourth point in the parallelogram.
// In GDI+: destPoints[0] <=> top-left, destPoints[1] <=> top-right, destPoints[2] <=> bottom-left
Point destPoints[3];
for (INT i=0; (i<3); i++)
{
destPoints[i].X = p3PtDest[i].x;
destPoints[i].Y = p3PtDest[i].y;
}
if (!pBitsMask || !pBmiMask)
{// No mask: just blt.
Bitmap bmp(pBmi, (VOID*)pBits);
m_pGraphics->DrawImage(&bmp, destPoints, 3,
pSrc->left, pSrc->top, PRECT_WIDTH(pSrc), PRECT_HEIGHT(pSrc), UnitPixel, m_pImgAttribs);
} else
{// see the SCDrawImageMsk function for documentation.
INT iHeight = abs(pBmi->bmiHeader.biHeight);
INT iWidth = pBmi->bmiHeader.biWidth;
BOOL bFlip = (pBmi->bmiHeader.biHeight>0);
// lay out the mask on an array of bytes containg 0 or 1
BYTE* pExpandedMask = SCExpandMask(iWidth, iHeight,
lxMask, lyMask, pBitsMask, pBmiMask, dwUsageMask, !bFlip);
if (!pExpandedMask)
return;
// create alpha bitmap
HBITMAP hbm = SCBuildAlphaBitmap(pBits, pBmi, dwUsage, pExpandedMask, bFlip);
if (hbm)
{
DIBSECTION ds;
GetObject(hbm, sizeof(DIBSECTION), &ds);
Bitmap bmp(iWidth, iHeight, 4*iWidth,
PixelFormat32bppARGB, (BYTE*)ds.dsBm.bmBits);
// Draw the alpha bitmap
m_pGraphics->DrawImage(&bmp, destPoints, 3,
pSrc->left, pSrc->top, PRECT_WIDTH(pSrc), PRECT_HEIGHT(pSrc), UnitPixel, m_pImgAttribs);
DeleteObject(hbm);
}
delete [] pExpandedMask;
}
}
///
/// Mask Blt: uses a ROP4 to mask the source bitmap.
///
void CSCEMFdcRenderer::SCDrawImageMsk(LPCRECT pDest,
LPCRECT pSrc, LPCBYTE pBits, LPCBITMAPINFO pBmi,
DWORD dwUsage, DWORD dwRop4, XFORM* pXForm, COLORREF crBkColorSrc,
LONG lxMask, LONG lyMask,
LPCBYTE pBitsMask, LPCBITMAPINFO pBmiMask, DWORD dwUsageMask)
{
ASSERT(m_pGraphics);
ASSERT(pBmi && pBits && pDest && pSrc);
// dwUsage can be: DIB_PAL_COLORS, DIB_PAL_INDICES, or DIB_RGB_COLORS
ASSERT(dwUsage==DIB_RGB_COLORS); // the other ones are not managed for now
Bitmap bmp(pBmi, (VOID*)pBits);
if (!pBitsMask || !pBmiMask)
{// No mask: just blt, using the foreground ROP index as ROP3.
SCDrawImage(pDest, pSrc, pBits, pBmi, dwUsage,
SCRop4GetForegroundROP3(dwRop4), pXForm);
} else
{
INT iHeight = abs(pBmi->bmiHeader.biHeight);
INT iWidth = pBmi->bmiHeader.biWidth;
BOOL bFlip = (pBmi->bmiHeader.biHeight>0);
// Lay out the mask on an array of bytes containg 0 or 1
// Note: this layout must follow the same orientation as the bitmap (ie not flipped).
BYTE* pExpandedMask = SCExpandMask(iWidth, iHeight,
lxMask, lyMask, pBitsMask, pBmiMask, dwUsageMask, !bFlip);
if (!pExpandedMask)
return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -