📄 dxhelper.h
字号:
t2 = ((((S1 >> 8) & 0x00ff00ff) * Wgt) + (((S2 >> 8) & 0x00ff00ff) * InvWgt )) + 0x00800080;
t2 = (t2 + ((t2 >> 8) & 0x00ff00ff)) & 0xff00ff00;
return (t1 | t2);
} /* DXWeightedAverage */
inline void DXWeightedAverageArray( DXBASESAMPLE* pS1, DXBASESAMPLE* pS2, ULONG Wgt,
DXBASESAMPLE* pResults, DWORD dwCount )
{
_ASSERT( pS1 && pS2 && pResults && dwCount );
for( DWORD i = 0; i < dwCount; ++i )
{
pResults[i] = DXWeightedAverage( pS1[i], pS2[i], Wgt );
}
} /* DXWeightedAverageArray */
inline void DXWeightedAverageArrayOver( DXPMSAMPLE* pS1, DXPMSAMPLE* pS2, ULONG Wgt,
DXPMSAMPLE* pResults, DWORD dwCount )
{
_ASSERT( pS1 && pS2 && pResults && dwCount );
DWORD i;
if( Wgt == 255 )
{
for( i = 0; i < dwCount; ++i )
{
DXCompositeOver( pResults[i], pS1[i] );
}
}
else
{
for( i = 0; i < dwCount; ++i )
{
DXPMSAMPLE Avg = DXWeightedAverage( (DXBASESAMPLE)pS1[i],
(DXBASESAMPLE)pS2[i], Wgt );
DXCompositeOver( pResults[i], Avg );
}
}
} /* DXWeightedAverageArrayOver */
inline void DXScalePremultArray(DXPMSAMPLE *pBuffer, ULONG cSamples, BYTE Weight)
{
for (DXPMSAMPLE *pBuffLimit = pBuffer + cSamples; pBuffer < pBuffLimit; pBuffer++)
{
*pBuffer = DXScaleSample(*pBuffer, Weight);
}
}
//
//
inline HRESULT DXClipToOutputWithPlacement(CDXDBnds & LogicalOutBnds, const CDXDBnds * pClipBnds, CDXDBnds & PhysicalOutBnds, const CDXDVec *pPlacement)
{
if(pClipBnds && (!LogicalOutBnds.IntersectBounds(*pClipBnds)))
{
return S_FALSE; // no intersect, we're done
}
else
{
CDXDVec vClipPos(false);
LogicalOutBnds.GetMinVector( vClipPos );
if (pPlacement)
{
vClipPos -= *pPlacement;
}
PhysicalOutBnds += vClipPos;
if (!LogicalOutBnds.IntersectBounds(PhysicalOutBnds))
{
return S_FALSE;
}
PhysicalOutBnds = LogicalOutBnds;
PhysicalOutBnds -= vClipPos;
}
return S_OK;
}
//
// Helper for converting a color ref to a DXSAMPLE
//
inline DWORD DXSampleFromColorRef(COLORREF cr)
{
DXSAMPLE Samp(0xFF, GetRValue(cr), GetGValue(cr), GetBValue(cr));
return Samp;
}
//
// Fill an entire surface with a color
//
inline HRESULT DXFillSurface( IDXSurface *pSurface, DXPMSAMPLE Color,
BOOL bDoOver = FALSE, ULONG ulTimeOut = 10000 )
{
IDXARGBReadWritePtr * pPtr;
HRESULT hr = pSurface->LockSurface( NULL, ulTimeOut, DXLOCKF_READWRITE,
IID_IDXARGBReadWritePtr, (void **)&pPtr, NULL);
if( SUCCEEDED(hr) )
{
pPtr->FillRect(NULL, Color, bDoOver);
pPtr->Release();
}
return hr;
} /* DXFillSurface */
//
// Fill a specified sub-rectangle of a surface with a color.
//
inline HRESULT DXFillSurfaceRect( IDXSurface *pSurface, RECT & rect, DXPMSAMPLE Color,
BOOL bDoOver = FALSE, ULONG ulTimeOut = 10000 )
{
CDXDBnds bnds(rect);
IDXARGBReadWritePtr * pPtr;
HRESULT hr = pSurface->LockSurface( &bnds, ulTimeOut, DXLOCKF_READWRITE,
IID_IDXARGBReadWritePtr, (void **)&pPtr, NULL);
if( SUCCEEDED(hr) )
{
pPtr->FillRect(NULL, Color, bDoOver);
pPtr->Release();
}
return hr;
} /* DXFillSurfaceRect */
//
// The DestBnds height and width must be greater than or equal to the source bounds.
//
// The dwFlags parameter uses the flags defined by IDXSurfaceFactory::BitBlt:
//
// DXBOF_DO_OVER
// DXBOF_DITHER
//
inline HRESULT DXBitBlt(IDXSurface * pDest, const CDXDBnds & DestBnds, IDXSurface * pSrc, const CDXDBnds & SrcBnds, DWORD dwFlags, ULONG ulTimeout)
{
IDXARGBReadPtr * pIn;
HRESULT hr;
hr = pSrc->LockSurface( &SrcBnds, INFINITE,
(dwFlags & DXBOF_DO_OVER) ? (DXLOCKF_READ | DXLOCKF_WANTRUNINFO) : DXLOCKF_READ,
IID_IDXARGBReadPtr, (void**)&pIn, NULL);
if(SUCCEEDED(hr))
{
IDXARGBReadWritePtr * pOut;
hr = pDest->LockSurface( &DestBnds, INFINITE, DXLOCKF_READWRITE,
IID_IDXARGBReadWritePtr, (void**)&pOut, NULL );
if (SUCCEEDED(hr))
{
DXSAMPLEFORMATENUM InNativeType = pIn->GetNativeType(NULL);
DXSAMPLEFORMATENUM OutNativeType = pOut->GetNativeType(NULL);
BOOL bSrcIsOpaque = !(InNativeType & (DXPF_TRANSLUCENCY | DXPF_TRANSPARENCY));
const ULONG Width = SrcBnds.Width();
DXPMSAMPLE *pSrcBuff = NULL;
if( InNativeType != DXPF_PMARGB32 )
{
pSrcBuff = DXPMSAMPLE_Alloca(Width);
}
//
// Don't dither unless the dest has a greater error term than the source.
//
if ((dwFlags & DXBOF_DITHER) &&
((OutNativeType & DXPF_ERRORMASK) <= (InNativeType & DXPF_ERRORMASK)))
{
dwFlags &= (~DXBOF_DITHER);
}
if ((dwFlags & DXBOF_DITHER) || ((dwFlags & DXBOF_DO_OVER) && bSrcIsOpaque== 0))
{
//--- Allocate a working output buffer if necessary
DXPMSAMPLE *pDestBuff = NULL;
if( OutNativeType != DXPF_PMARGB32 )
{
pDestBuff = DXPMSAMPLE_Alloca(Width);
}
//--- Process each output row
// Note: Output coordinates are relative to the lock region
const ULONG Height = SrcBnds.Height();
if (dwFlags & DXBOF_DITHER)
{
DXPMSAMPLE * pSrcDitherBuff = pSrcBuff;
if (pSrcDitherBuff == NULL)
{
pSrcDitherBuff = DXPMSAMPLE_Alloca(Width);
}
const BOOL bCopy = ((dwFlags & DXBOF_DO_OVER) == 0);
//
// Set up the dither descriptor (some things are constant)
//
DXDITHERDESC dd;
dd.pSamples = pSrcDitherBuff;
dd.DestSurfaceFmt = OutNativeType;
for(ULONG Y = 0; Y < Height; ++Y )
{
dd.x = DestBnds.Left();
dd.y = DestBnds.Top() + Y;
const DXRUNINFO *pRunInfo;
ULONG cRuns = pIn->MoveAndGetRunInfo(Y, &pRunInfo);
pOut->MoveToRow( Y );
do
{
ULONG ulRunLen = pRunInfo->Count;
if (pRunInfo->Type == DXRUNTYPE_CLEAR)
{
pIn->Move(ulRunLen);
if (bCopy)
{
//
// The only way to avoid calling a constructor function to create
// a pmsample from 0 is to declare a variable and then assign it!
//
DXPMSAMPLE NullColor;
NullColor = 0;
pOut->FillAndMove(pSrcDitherBuff, NullColor, ulRunLen, FALSE);
}
else
{
pOut->Move(ulRunLen);
}
dd.x += ulRunLen;
}
else
{
pIn->UnpackPremult(pSrcDitherBuff, ulRunLen, TRUE);
dd.cSamples = ulRunLen;
DXDitherArray(&dd);
dd.x += ulRunLen;
if (bCopy || pRunInfo->Type == DXRUNTYPE_OPAQUE)
{
pOut->PackPremultAndMove(pSrcDitherBuff, ulRunLen);
}
else
{
pOut->OverArrayAndMove(pDestBuff, pSrcDitherBuff, ulRunLen);
}
}
pRunInfo++;
cRuns--;
} while (cRuns);
}
}
else
{
for(ULONG Y = 0; Y < Height; ++Y )
{
const DXRUNINFO *pRunInfo;
ULONG cRuns = pIn->MoveAndGetRunInfo(Y, &pRunInfo);
pOut->MoveToRow( Y );
do
{
ULONG ulRunLen = pRunInfo->Count;
switch (pRunInfo->Type)
{
case DXRUNTYPE_CLEAR:
pIn->Move(ulRunLen);
pOut->Move(ulRunLen);
break;
case DXRUNTYPE_OPAQUE:
pOut->CopyAndMoveBoth(pDestBuff, pIn, ulRunLen, TRUE);
break;
case DXRUNTYPE_TRANS:
{
DXPMSAMPLE *pSrc = pIn->UnpackPremult(pSrcBuff, ulRunLen, TRUE);
DXPMSAMPLE *pDest = pOut->UnpackPremult(pDestBuff, ulRunLen, FALSE);
DXOverArrayMMX(pDest, pSrc, ulRunLen);
pOut->PackPremultAndMove(pDestBuff, ulRunLen);
break;
}
case DXRUNTYPE_UNKNOWN:
{
pOut->OverArrayAndMove(pDestBuff,
pIn->UnpackPremult(pSrcBuff, ulRunLen, TRUE),
ulRunLen);
break;
}
}
pRunInfo++;
cRuns--;
} while (cRuns);
}
}
}
else
{
pOut->CopyRect( pSrcBuff, NULL, pIn, NULL, bSrcIsOpaque );
}
pOut->Release();
}
pIn->Release();
}
return hr;
}
inline HRESULT DXSrcCopy(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight,
IDXSurface *pSrcSurface, int nXSrc, int nYSrc)
{
IDXDCLock *pDCLock;
HRESULT hr = pSrcSurface->LockSurfaceDC(NULL, INFINITE, DXLOCKF_READ, &pDCLock);
if (SUCCEEDED(hr))
{
::BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, pDCLock->GetDC(), nXSrc, nYSrc, SRCCOPY);
pDCLock->Release();
}
return hr;
}
//
//=== Pointer validation functions
//
inline BOOL DXIsBadReadPtr( const void* pMem, UINT Size )
{
#if !defined( _DEBUG ) && defined( DXTRANS_NOROBUST )
return false;
#else
return ::IsBadReadPtr( pMem, Size );
#endif
}
inline BOOL DXIsBadWritePtr( void* pMem, UINT Size )
{
#if !defined( _DEBUG ) && defined( DXTRANS_NOROBUST )
return false;
#else
return ::IsBadWritePtr( pMem, Size );
#endif
}
inline BOOL DXIsBadInterfacePtr( const IUnknown* pUnknown )
{
#if !defined( _DEBUG ) && defined( DXTRANS_NOROBUST )
return false;
#else
return ( ::IsBadReadPtr( pUnknown, sizeof( *pUnknown ) ) ||
::IsBadCodePtr( (FARPROC)((PDWORD)pUnknown)[0] ))?
(true):(false);
#endif
}
#define DX_IS_BAD_OPTIONAL_WRITE_PTR(p) ((p) && DXIsBadWritePtr(p, sizeof(p)))
#define DX_IS_BAD_OPTIONAL_READ_PTR(p) ((p) && DXIsBadReadPtr(p, sizeof(p)))
#define DX_IS_BAD_OPTIONAL_INTERFACE_PTR(p) ((p) && DXIsBadInterfacePtr(p))
#pragma option pop /*P_O_Pop*/
#endif /* This must be the last line in the file */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -