Microsoft-3D-Movie-Maker/kauai/SRC/CURSOR.CPP
2022-05-03 16:31:19 -07:00

154 lines
3.5 KiB
C++

/* Copyright (c) Microsoft Corporation.
Licensed under the MIT License. */
/***************************************************************************
Author: ShonK
Project: Kauai
Reviewed:
Copyright (c) Microsoft Corporation
Cursor class.
***************************************************************************/
#include "frame.h"
ASSERTNAME
RTCLASS(CURS)
/***************************************************************************
Destructor for the cursor class.
***************************************************************************/
CURS::~CURS(void)
{
#ifdef WIN
if (hNil != _hcrs)
DestroyCursor(_hcrs);
#endif //WIN
}
/***************************************************************************
Read a cursor out of a CRF.
***************************************************************************/
bool CURS::FReadCurs(PCRF pcrf, CTG ctg, CNO cno, PBLCK pblck,
PBACO *ppbaco, long *pcb)
{
PGG pggcurf;
long icurf, icurfBest;
CURF curf;
short bo;
long dxp, dyp, dzpT;
long dzpBest;
long cbRowDst, cbRowSrc, cbT;
byte *prgb, *qrgb;
PCURS pcurs = pvNil;
*pcb = size(CURS);
if (pvNil == ppbaco)
return fTrue;
if (pvNil == (pggcurf = GG::PggRead(pblck, &bo)) || pggcurf->IvMac() == 0)
{
ReleasePpo(&pggcurf);
return fFalse;
}
#ifdef MAC
dxp = dyp = 16;
#endif //MAC
#ifdef WIN
dxp = GetSystemMetrics(SM_CXCURSOR);
dyp = GetSystemMetrics(SM_CYCURSOR);
#endif //WIN
icurfBest = 0;
dzpBest = klwMax;
for (icurf = 0; icurf < pggcurf->IvMac(); icurf++)
{
pggcurf->GetFixed(icurf, &curf);
if (kboOther == bo)
SwapBytesBom(&curf, kbomCurf);
if (curf.dxp > dxp || curf.dyp > dyp || curf.curt != curtMonochrome ||
pggcurf->Cb(icurf) != (long)curf.dxp * curf.dyp / 4)
{
continue;
}
dzpT = (dxp - curf.dxp) + (dyp - curf.dyp);
if (dzpBest > dzpT)
{
icurfBest = icurf;
if (dzpT == 0)
break;
dzpBest = dzpT;
}
}
AssertIn(icurfBest, 0, pggcurf->IvMac());
pggcurf->GetFixed(icurfBest, &curf);
if (kboOther == bo)
SwapBytesBom(&curf, kbomCurf);
cbRowSrc = LwRoundAway(LwDivAway(curf.dxp, 8), 2);
cbRowDst = LwRoundAway(LwDivAway(dxp, 8), 2);
if (!FAllocPv((void **)&prgb, LwMul(cbRowDst, 2 * dyp), fmemClear, mprNormal))
goto LFail;
if (pvNil == (pcurs = NewObj CURS))
goto LFail;
FillPb(prgb, LwMul(cbRowDst, dyp), 0xFF);
qrgb = (byte *)pggcurf->QvGet(icurfBest);
cbT = LwMin(cbRowSrc, cbRowDst);
for (dzpT = LwMin(dyp, curf.dyp); dzpT-- > 0; )
{
CopyPb(qrgb + LwMul(dzpT, cbRowSrc), prgb + LwMul(dzpT, cbRowDst), cbT);
CopyPb(qrgb + LwMul(curf.dyp + dzpT, cbRowSrc),
prgb + LwMul(dyp + dzpT, cbRowDst), cbT);
}
#ifdef WIN
pcurs->_hcrs = CreateCursor(vwig.hinst, curf.xp, curf.yp,
dxp, dyp, prgb, prgb + LwMul(dxp, cbRowDst));
if (hNil == pcurs->_hcrs)
ReleasePpo(&pcurs);
#endif //WIN
#ifdef MAC
Assert(dxp == 16, 0);
long *plwAnd, *plwXor;
long ilw;
plwAnd = (long *)prgb;
plwXor = plwAnd + 8;
pcurs->_crs.hotSpot.h = curf.xp;
pcurs->_crs.hotSpot.v = curf.yp;
for (ilw = 0; ilw < 8; ilw++)
{
((long *)pcurs->_crs.mask)[ilw] = ~*plwAnd;
((long *)pcurs->_crs.data)[ilw] = ~*plwAnd++ ^ *plwXor++;
}
#endif //MAC
LFail:
FreePpv((void **)&prgb);
ReleasePpo(&pggcurf);
*ppbaco = pcurs;
return pvNil != pcurs;
}
/***************************************************************************
Set the cursor.
***************************************************************************/
void CURS::Set(void)
{
#ifdef WIN
SetCursor(_hcrs);
#endif //WIN
#ifdef MAC
SetCursor(&_crs);
#endif //MAC
}