|
|
/****************************************************************************\
* * Dirty region calculation * * 14-Feb-1995 mikeke Created * * Copyright (c) 1994 Microsoft Corporation \****************************************************************************/
#include "precomp.h"
#pragma hdrstop
/****************************************************************************/
PXLIST XLISTAlloc( __GLGENbuffers *buffers) { PXLIST pxlist;
if (buffers->pxlist != NULL) { pxlist = buffers->pxlist; buffers->pxlist = pxlist->pnext; } else { pxlist = (PXLIST)ALLOC(sizeof(XLIST)); if (pxlist == NULL) return NULL; }
pxlist->pnext = NULL; return pxlist; }
/****************************************************************************/
void XLISTFree( __GLGENbuffers *buffers, PXLIST pxlist) { pxlist->pnext = buffers->pxlist; buffers->pxlist = pxlist; }
/****************************************************************************/
PXLIST XLISTCopy( __GLGENbuffers *buffers, PXLIST pxlist) { PXLIST pxlistNew = XLISTAlloc(buffers);
if (pxlistNew != NULL) { pxlistNew->s = pxlist->s; pxlistNew->e = pxlist->e; }
return pxlistNew; }
/****************************************************************************/
BOOL YLISTAddSpan( __GLGENbuffers *buffers, PYLIST pylist, int xs, int xe) { PXLIST *ppxlist = &(pylist->pxlist); PXLIST pxlist = XLISTAlloc(buffers);
if (pxlist == NULL) return FALSE;
//
// Create new x span
//
pxlist->s = xs; pxlist->e = xe;
//
// Insert it in sorted order
//
while ( ((*ppxlist) != NULL) && ((*ppxlist)->s < xs) ) { ppxlist = &((*ppxlist)->pnext); } pxlist->pnext = *ppxlist; *ppxlist = pxlist;
//
// Combine any overlapping spans
//
pxlist = pylist->pxlist; while (TRUE) { PXLIST pxlistNext = pxlist->pnext;
if (pxlistNext == NULL) return TRUE;
if (pxlist->e >= pxlistNext->s) { if (pxlistNext->e > pxlist->e) { pxlist->e = pxlistNext->e; } pxlist->pnext = pxlistNext->pnext; XLISTFree(buffers, pxlistNext); } else { pxlist = pxlist->pnext; } }
return TRUE; }
/****************************************************************************/
PYLIST YLISTAlloc( __GLGENbuffers *buffers) { PYLIST pylist;
if (buffers->pylist != NULL) { pylist = buffers->pylist; buffers->pylist = pylist->pnext; } else { pylist = (PYLIST)ALLOC(sizeof(YLIST)); if (pylist == NULL) return NULL; }
pylist->pxlist = NULL; pylist->pnext = NULL; return pylist; }
/****************************************************************************/
void YLISTFree( __GLGENbuffers *buffers, PYLIST pylist) { PXLIST pxlist = pylist->pxlist; PXLIST pxlistKill;
while (pxlist != NULL) { pxlistKill = pxlist; pxlist = pxlist->pnext; XLISTFree(buffers, pxlistKill); }
pylist->pnext = buffers->pylist; buffers->pylist = pylist; }
/****************************************************************************/
PYLIST YLISTCopy( __GLGENbuffers *buffers, PYLIST pylist) { PXLIST pxlist = pylist->pxlist; PXLIST *ppxlist; PYLIST pylistNew = YLISTAlloc(buffers);
if (pylistNew != NULL) { pylistNew->s = pylist->s; pylistNew->e = pylist->e;
ppxlist = &(pylistNew->pxlist); while (pxlist != NULL) { *ppxlist = XLISTCopy(buffers, pxlist); if (*ppxlist == NULL) { YLISTFree(buffers, pylistNew); return NULL; } ppxlist = &((*ppxlist)->pnext); pxlist = pxlist->pnext; } *ppxlist = NULL; }
return pylistNew; }
/****************************************************************************/
void RECTLISTAddRect( PRECTLIST prl, int xs, int ys, int xe, int ye) { __GLGENbuffers *buffers = (__GLGENbuffers *)(prl->buffers); PYLIST* ppylist; PYLIST pylistNew;
ppylist = &(prl->pylist); while ((*ppylist) != NULL) { if (ys < (*ppylist)->e) break; ppylist = &((*ppylist)->pnext); }
while ((*ppylist) != NULL) { if (ys < (*ppylist)->s) { PYLIST pylistNew = YLISTAlloc(buffers); if (pylistNew == NULL) { OutOfMemory: RECTLISTSetEmpty(prl); return; }
pylistNew->s = ys; pylistNew->e = ye; if (!YLISTAddSpan(buffers, pylistNew, xs, xe)) { goto OutOfMemory; }
pylistNew->pnext = *ppylist; *ppylist = pylistNew; ppylist = &((*ppylist)->pnext);
if (ye <= (*ppylist)->s) { return; }
pylistNew->e = (*ppylist)->s; ys = (*ppylist)->s; } else if (ys == (*ppylist)->s) { if (ye >= (*ppylist)->e) { if (!YLISTAddSpan(buffers, *ppylist, xs, xe)) { goto OutOfMemory; }
ys = (*ppylist)->e; if (ys == ye) return; ppylist = &((*ppylist)->pnext); } else { PYLIST pylistNew = YLISTCopy(buffers, *ppylist); if (pylistNew == NULL) { goto OutOfMemory; }
pylistNew->e = ye; if (!YLISTAddSpan(buffers, pylistNew, xs, xe)) { goto OutOfMemory; }
(*ppylist)->s = ye;
pylistNew->pnext = *ppylist; *ppylist = pylistNew;
return; } } else { PYLIST pylistNew = YLISTCopy(buffers, *ppylist); if (pylistNew == NULL) { goto OutOfMemory; }
pylistNew->e = ys; (*ppylist)->s = ys;
pylistNew->pnext = *ppylist; *ppylist = pylistNew; ppylist = &((*ppylist)->pnext); } }
pylistNew = YLISTAlloc(buffers); if (pylistNew == NULL) { goto OutOfMemory; }
pylistNew->s = ys; pylistNew->e = ye; if (!YLISTAddSpan(buffers, pylistNew, xs, xe)) { goto OutOfMemory; }
pylistNew->pnext = *ppylist; *ppylist = pylistNew; }
/****************************************************************************/
#ifdef LATER
// these functions are not required in the server implementation
#define MAXRECTS 1024
HRGN RECTLISTCreateRegion( PRECTLIST prl) { __GLGENbuffers *buffers = (__GLGENbuffers *)(prl->buffers); PYLIST pylist = prl->pylist; int irect = 0; PRGNDATA prgndata; PRECT prc; HRGN hrgn;
prgndata = (PRGNDATA)ALLOC(sizeof(RGNDATAHEADER) + MAXRECTS * sizeof(RECT)); if (prgndata == NULL) return NULL;
prc = (PRECT)(prgndata->Buffer);
while (pylist != NULL) { PXLIST pxlist = pylist->pxlist; while (pxlist != NULL) { prc->left = pxlist->s; prc->right = pxlist->e; prc->top = pylist->s; prc->bottom = pylist->e; prc++; irect++; if (irect == MAXRECTS) { //Error("maxrect");
goto done; }
pxlist = pxlist->pnext; } pylist = pylist->pnext; }
done: prgndata->rdh.dwSize = sizeof(RGNDATAHEADER); prgndata->rdh.iType = RDH_RECTANGLES; prgndata->rdh.nCount = irect; prgndata->rdh.nRgnSize = 0; prgndata->rdh.rcBound.left = 0; prgndata->rdh.rcBound.right = 4096; prgndata->rdh.rcBound.top = 0; prgndata->rdh.rcBound.bottom = 4096;
hrgn = GreExtCreateRegion(NULL, irect * sizeof(RECT) + sizeof(RGNDATAHEADER), prgndata);
#ifdef LATER
if (hrgn == NULL) { Error1("ExtCreateRegion() Error %d\n", GetLastError()); Error1("%d rects\n", irect); prc = (PRECT)(prgndata->Buffer); for (;irect>0; irect--) { //printf("(%5d, %5d, %5d, %5d)\n", prc->left, prc->right, prc->top, prc->bottom);
prc++; } } #endif
FREE(prgndata);
return hrgn; }
/****************************************************************************/
//
// !!! make this do everything in one pass
//
void RECTLISTOr( PRECTLIST prl1, PRECTLIST prl2) { __GLGENbuffers *buffers = (__GLGENbuffers *)(prl1->buffers); PYLIST pylist = prl2->pylist;
while (pylist != NULL) { PXLIST pxlist = pylist->pxlist;
while (pxlist != NULL) { RECTLISTAddRect(prl1, pxlist->s, pylist->s, pxlist->e, pylist->e); pxlist = pxlist->pnext; } pylist = pylist->pnext; } }
/****************************************************************************/
void RECTLISTOrAndClear( PRECTLIST prl1, PRECTLIST prl2) { __GLGENbuffers *buffers = (__GLGENbuffers *)(prl1->buffers);
if (RECTLISTIsMax(prl2)) { RECTLISTSetMax(prl1); RECTLISTSetEmpty(prl2); } else { if (RECTLISTIsEmpty(prl1)) { //
// If the clear region is empty just swap them
//
RECTLISTSwap(prl1, prl2); } else { //
// The clear region isn't empty so maximize it.
//
RECTLISTSetMax(prl1); RECTLISTSetEmpty(prl2); } } }
/****************************************************************************/
void RECTLISTSwap( PRECTLIST prl1, PRECTLIST prl2) { __GLGENbuffers *buffers = (__GLGENbuffers *)(prl1->buffers); RECTLIST rlTemp = *prl1;
*prl1 = *prl2; *prl2 = rlTemp; } #endif
/****************************************************************************/
void RECTLISTSetEmpty( PRECTLIST prl) { __GLGENbuffers *buffers = (__GLGENbuffers *)(prl->buffers); PYLIST pylist = prl->pylist; PYLIST pylistKill;
while (pylist != NULL) { pylistKill = pylist; pylist = pylist->pnext; YLISTFree(buffers, pylistKill); }
prl->pylist = NULL; }
/****************************************************************************/
BOOL RECTLISTIsEmpty( PRECTLIST prl) { return (prl->pylist == NULL); }
|