📄 gdiblt.cpp
字号:
/* ***** BEGIN LICENSE BLOCK *****
* Version: RCSL 1.0/RPSL 1.0
*
* Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
*
* The contents of this file, and the files included with this file, are
* subject to the current version of the RealNetworks Public Source License
* Version 1.0 (the "RPSL") available at
* http://www.helixcommunity.org/content/rpsl unless you have licensed
* the file under the RealNetworks Community Source License Version 1.0
* (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
* in which case the RCSL will apply. You may also obtain the license terms
* directly from RealNetworks. You may not use this file except in
* compliance with the RPSL or, if you have a valid RCSL with RealNetworks
* applicable to this file, the RCSL. Please see the applicable RPSL or
* RCSL for the rights, obligations and limitations governing use of the
* contents of the file.
*
* This file is part of the Helix DNA Technology. RealNetworks is the
* developer of the Original Code and owns the copyrights in the portions
* it created.
*
* This file, and the files included with this file, is distributed and made
* available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
*
* Technology Compatibility Kit Test Suite(s) Location:
* http://www.helixcommunity.org/content/tck
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
#include "hxcom.h"
#include "hxtypes.h"
#include "hxwintyp.h"
#ifndef _WINCE
#include <ddraw.h>
#endif
#include "colormap.h"
#if defined (HELIX_FEATURE_CC_RGB8out)
#include "colorlib.h"
#endif
#include "gdiblt.h"
CGDIBlt::CGDIBlt()
: CWinBlt()
, m_pGdiSurface(NULL)
#if defined (HELIX_FEATURE_CC_RGB8out)
, m_nSystemColors(0)
#endif
{
memset(&m_gdiInfo, 0, sizeof(m_gdiInfo));
}
CGDIBlt::~CGDIBlt()
{
DestroySurface(0);
}
HX_RESULT CGDIBlt::CreateSurface(int cidIn, int& cidOut,
int nWidth, int nHeight,
int nFlags, HWND hWnd,
int nCountIn, int& nCountOut)
{
HANDLE hMapping; // handle to mapped object
HBITMAP hBitmap; // DIB section bitmap handle
BYTE *pBase; // pointer to the actual image
BITMAPINFO *pbmi;
BYTE *pbmiBuf = NULL;
int nSize = sizeof(BITMAPINFO);
int nColors = 0;
void *pPalette = NULL;
HX_RESULT hr = HXR_OK;
m_hWnd = hWnd;
#if defined (HELIX_FEATURE_CC_RGB32out)
m_nCID = CID_RGB32;
#elif defined (HELIX_FEATURE_CC_RGB24out)
m_nCID = CID_RGB24;
#elif defined (HELIX_FEATURE_CC_RGB565out)
m_nCID = CID_RGB565;
nSize += 3 * sizeof(ULONG32);
#elif defined (HELIX_FEATURE_CC_RGB555out)
m_nCID = CID_RGB555;
nSize += 3 * sizeof(ULONG32);
#elif defined (HELIX_FEATURE_CC_RGB444out)
m_nCID = CID_RGB444;
nSize += 3 * sizeof(ULONG32);
#elif defined (HELIX_FEATURE_CC_RGB8out)
m_nCID = CID_RGB8;
nColors = 256;
nSize += nColors * sizeof(PALETTEENTRY);
// get system palette first
HDC hDC = GetDC(NULL);
PALETTEENTRY SystemPalette[256];
if (hDC)
{
m_nSystemColors = GetSystemPaletteEntries (hDC, 0, 256, SystemPalette);
ReleaseDC (NULL,hDC);
// generate palette index
for (int i=0; i<m_nSystemColors; i++)
{
m_SystemPaletteIndices[i] = i;
m_SystemPaletteRGB[i].rgbBlue = SystemPalette[i].peBlue;
m_SystemPaletteRGB[i].rgbGreen = SystemPalette[i].peGreen;
m_SystemPaletteRGB[i].rgbRed = SystemPalette[i].peRed;
m_SystemPaletteRGB[i].rgbReserved = 0;
}
// update color converter's palette with the current system palette entries
SetDestRGB8Palette(m_nSystemColors, (unsigned int *)SystemPalette, m_SystemPaletteIndices);
pPalette = SystemPalette;
}
#endif
cidOut = m_nCID;
// allocate the buffer for the BITMAPINFO
pbmiBuf = new BYTE[nSize];
if (!pbmiBuf)
return HXR_OUTOFMEMORY;
memset(pbmiBuf, 0, nSize);
pbmi = (BITMAPINFO*)pbmiBuf;
// initialize the BITMAPINFO values
MakeBitmap (pbmi, nSize, cidOut, nWidth, nHeight, (PALETTEENTRY*)pPalette, nColors);
// allocate a new GDISURFACE structure to use:
m_pGdiSurface = new GDISURFACE;
if (m_pGdiSurface != NULL)
{
// create a file mapping object and map into our address space
#ifndef WINCE
hMapping = CreateFileMapping ((HANDLE) 0xFFFFFFFF,
NULL, PAGE_READWRITE,
(DWORD) 0,
pbmi->bmiHeader.biSizeImage, NULL);
if (hMapping != NULL)
#else
hMapping = NULL;
#endif
{
// create a DIB section using given image format
#ifdef WINCE
pBase = NULL;
#endif
hBitmap = CreateDIBSection ((HDC) NULL, pbmi, DIB_RGB_COLORS, (VOID **) &pBase, hMapping, (DWORD) 0);
if (hBitmap != NULL && pBase != NULL)
{
// initialise the GDISURFACE structure
m_pGdiSurface->hBitMap = hBitmap;
m_pGdiSurface->lpBase = pBase;
m_pGdiSurface->nPitch = nWidth*pbmi->bmiHeader.biBitCount/8;
m_pGdiSurface->nPitch = -((m_pGdiSurface->nPitch + 3) & ~3);
// m_pGdiSurface->PaletteVersion = PALETTE_VERSION
GetObject (hBitmap, sizeof (DIBSECTION), (VOID *)& (m_pGdiSurface->DibSection));
}
// close file mapping
#ifndef WINCE
CloseHandle (hMapping);
#endif
m_gdiInfo.hDC = GetDC(m_hWnd);
m_gdiInfo.hMemoryDC = CreateCompatibleDC(m_gdiInfo.hDC);
}
}
#ifndef WINCE
else
hr = HXR_FAIL;
#endif
HX_VECTOR_DELETE(pbmi);
return hr;
}
HX_RESULT CGDIBlt::LockSurface(UCHAR** ppDestPtr,
LONG32* pnDestPitch,
int& cid,
REF(HXxSize) dstSize,
int nIndex)
{
*ppDestPtr = m_pGdiSurface->lpBase;
*pnDestPitch = m_pGdiSurface->nPitch;
cid = m_nCID;
return HXR_OK;
}
HX_RESULT CGDIBlt::FillSurface(int cidIn,
UCHAR* pSrcBuffer,
HXxSize* pSrcSize,
HXxRect* prSrcRect,
UCHAR* pDstBuffer,
LONG32 nDstPitch,
HXxRect* prDestRect)
{
return HXR_NOTIMPL;
}
HX_RESULT CGDIBlt::UnlockSurface(UCHAR* pSurfPtr, int nIndex)
{
return HXR_OK;
}
HX_RESULT CGDIBlt::RenderSurface(HXxSize* pSrcSize,
HXxRect* prSrcRect,
HXxRect* prDestRect,
int nIndex)
{
// Map to screen coordinates
//POINT po = {0,0};
//ClientToScreen(m_hWnd, &po);
RECT rc;
GetClientRect(m_hWnd, &rc);
/*rc.left += po.x;
rc.right += po.x;
rc.top += po.y;
rc.bottom += po.y;*/
BOOL bResult;
HBITMAP hOldBitmap;
/* get sizes of source/destination rectangles: */
LONG lTargetWidth = rc.right - rc.left;
LONG lTargetHeight = rc.bottom - rc.top;
LONG lSourceWidth = prSrcRect->right - prSrcRect->left;
LONG lSourceHeight = prSrcRect->bottom - prSrcRect->top;
/* select bitmap to blit: */
hOldBitmap = (HBITMAP) SelectObject (m_gdiInfo.hMemoryDC, m_pGdiSurface->hBitMap);
#if defined (HELIX_FEATURE_CC_RGB8out)
SetDIBColorTable(m_gdiInfo.hMemoryDC, 0, m_nSystemColors, m_SystemPaletteRGB);
#endif
/* is the window the same size as the video: */
if (lTargetWidth == lSourceWidth && lTargetHeight == lSourceHeight)
{
/* put the image straight into the window: */
bResult = BitBlt (
m_gdiInfo.hDC, /* target device HDC */
rc.left, /* x sink position */
rc.top, /* y sink position */
lTargetWidth, /* destination width */
lTargetHeight, /* destination height */
m_gdiInfo.hMemoryDC, /* source device context */
prSrcRect->left, /* x source position */
prSrcRect->top, /* y source position */
SRCCOPY); /* simple copy */
} else {
/* stretch the image when copying to the window: */
bResult = StretchBlt (
m_gdiInfo.hDC, /* target device HDC */
rc.left, /* x sink position */
rc.top, /* y sink position */
lTargetWidth, /* destination width */
lTargetHeight, /* destination height */
m_gdiInfo.hMemoryDC, /* source device HDC */
prSrcRect->left, /* x source position */
prSrcRect->top, /* y source position */
lSourceWidth, /* source width */
lSourceHeight, /* source height */
SRCCOPY); /* simple copy */
}
/* put the old bitmap back into the device context so we don't leak */
SelectObject (m_gdiInfo.hMemoryDC, hOldBitmap);
return HXR_OK;
}
HX_RESULT CGDIBlt::DestroySurface(int cid)
{
if (m_gdiInfo.hDC)
ReleaseDC (m_hWnd, m_gdiInfo.hDC);
if (m_gdiInfo.hMemoryDC)
DeleteDC (m_gdiInfo.hMemoryDC);
memset(&m_gdiInfo, 0, sizeof(m_gdiInfo));
if (m_pGdiSurface)
{
DeleteObject (m_pGdiSurface->hBitMap);
HX_DELETE(m_pGdiSurface);
}
return HXR_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -