📄 reg09.c
字号:
goto StoreNewRect;
}
break;
case 2: /* Do Subtraction */
alTest = edgeState & 0xff;
ahTest = edgeState >> 8;
while (snPtr != bePtr)
{
if(snPtr->rList == RECT_LST1)
{
alTest += snPtr->rDir;
if( (alTest == 0) || (ahTest != 0))
{
snPtr = snPtr->NextBlock;
continue;
}
}
else
{
ahTest += snPtr->rDir;
if( (ahTest != 0) || (alTest == 0))
{
snPtr = snPtr->NextBlock;
continue;
}
}
temNUM = (short) snPtr->rX;
snPtr = snPtr->NextBlock;
if (snPtr == bePtr) break;
if (snPtr->rList == RECT_LST1)
{
alTest += (short) snPtr->rDir;
}
else
{
ahTest += (short) snPtr->rDir;
}
edgeState = (ahTest << 8) + alTest;
goto StoreNewRect;
}
break;
case 3: /* Do XOR */
alTest = edgeState & 0xff;
ahTest = edgeState >> 8;
while (snPtr != bePtr)
{
if(snPtr->rList == RECT_LST1)
{
alTest += snPtr->rDir;
if(alTest == 0)
{
if (ahTest == 0)
{
snPtr = snPtr->NextBlock;
continue;
}
}
else
{
if (ahTest != 0)
{
snPtr = snPtr->NextBlock;
continue;
}
}
}
else
{
ahTest += snPtr->rDir;
if(ahTest == 0)
{
if (alTest == 0)
{
snPtr = snPtr->NextBlock;
continue;
}
}
else
{
if (alTest != 0)
{
snPtr = snPtr->NextBlock;
continue;
}
}
}
temNUM = (short) snPtr->rX;
snPtr = snPtr->NextBlock;
if (snPtr == bePtr) break;
if (snPtr->rList == RECT_LST1)
{
alTest += (short) snPtr->rDir;
}
else
{
ahTest += (short) snPtr->rDir;
}
edgeState = (ahTest << 8) + alTest;
goto StoreNewRect;
}
}
}
/* Use goto command to get back to StorenewRect */
destScanMax = destPtr;
regionSize += ((long) destPtr - (long) destSave);
if(regionSize > 32767)
{
grafErrValue = c_RectList + c_RgnOflow;
nuGrafErr(grafErrValue);
SetupEmptyRegion(destRGN, makeRegion, sizeRGN);
return(0);
}
AETScanDone:
if( ((numRects1 | numRects2) != 0) ||
( aetHead.NextBlock != &aetHead) )
/* if not goto FinishRegion */
/***********************************************************/
/*Main Loop for Constructing YX banded list from rect list */
/***********************************************************/
/* Length in AET, distance to top of next rect in build rect list)
(one of the two distances is guaranteed to exist, because we can
only get here from bottom of loop, which checks for exactly the
condition that there's either an AET or remaining build rects) */
{
/* Find shortest distance in AET */
snPtr = aetHead.NextBlock;
/* BobB 5/5/98 - corrected the following line to provide for
case of two non-overlapping rectangles in the list.
temNUM = snPtr->rCount; */
temNUM = 32767;
while(snPtr != &aetHead)
{
if(snPtr->rCount < temNUM)
temNUM = (short) snPtr->rCount;
snPtr = snPtr->NextBlock;
}
/* Find shortest distance in RectList1 or RectList2 */
if((numRects1 | numRects2) != 0)
{
if(numRects1 != 0 )
{
if((numRects2 != 0) && (rectList2->Ymin <
rectList1->Ymin))
{
RLmin = rectList2->Ymin;
}
else
{
RLmin = rectList1->Ymin;
}
}
else
{
RLmin = rectList2->Ymin;
}
/* temNUM has the shortest AET or RectList distance */
RLmin -= curtY;
/* BobB 5/5/98 - changed the following line for minor performance improvement.
if(RLmin <= temNUM) temNUM = RLmin; */
if(RLmin < temNUM) temNUM = RLmin;
}
/* Shortest AET or RectList distance to advance */
curtY += temNUM; /* Advance Y to the top of the band */
snPtr = aetHead.NextBlock;
dnPtr = &aetHead;
while(snPtr != &aetHead)
{
snPtr->rCount -= temNUM;
if(snPtr->rCount == 0) /* Still length remain */
{
/* Link the previous block to the next block */
bePtr = snPtr->NextBlock;
dnPtr->NextBlock = bePtr;
curtLeftEdge = snPtr;
snPtr->NextBlock = (struct RBlock *) freeBlocks;
freeBlocks = (long) curtLeftEdge;
snPtr = bePtr;
}
else
{
dnPtr = snPtr;
snPtr = snPtr->NextBlock;
}
}
goto ScanOutFirst;
}
/* ------------------------------------------------------ */
/* ====================================================== */
FinishRegion:
/* Done building YX banded rect list form input rect list
add the tail sentinel and fill in the region structure */
if(makeRegion == 1)
{
destSizeLeft -= sizeof(rect);
if(destSizeLeft < 0)
{ /* Not enough space for the end rect */
grafErrValue = c_RectList + c_RgnOflow;
nuGrafErr(grafErrValue);
/* Set up the end rect */
SetupEmptyRegion(destRGN, makeRegion, sizeRGN);
return(0);
}
/* Fill the last rect */
destSave->Xmin = rgnEOS;
destSave->Xmax = rgnEOS;
destSave->Ymin = rgnEOS;
destSave->Ymax = rgnEOS;
}
/* Count the tail sentinel */
regionSize += sizeof(rect);
if(regionSize > 32767)
{
grafErrValue = c_RectList + c_RgnOflow;
nuGrafErr(grafErrValue);
SetupEmptyRegion(destRGN, makeRegion, sizeRGN);
return(0);
}
/* Set up more space before return */
if( (rXmin > rXmax) || (regionSize == (sizeof(region) + 2*sizeof(rect))) )
SetupEmptyRegion(destRGN, makeRegion, sizeRGN);
else
{
if(makeRegion != 0)
{
if(regionSize == (sizeof(region) + 3*sizeof(rect)))
{
destRGN->rgnFlags = rfRect;
}
else
{
destRGN->rgnFlags = 0;
}
destRGN->rgnSize = regionSize;
/* set bounding rects */
destRGN->rgnRect.Xmin = rXmin;
destRGN->rgnRect.Xmax = rXmax;
temRect = (rect *)((long) destRGN +
sizeof(region) + sizeof(rect));
destRGN->rgnRect.Ymin = temRect->Ymin;
destRGN->rgnList = (rect *) ((long) destRGN
+ sizeof(region) + sizeof(rect));
destRGN->rgnListEnd = destPtr - 1;
destRGN->rgnRect.Ymax = destRGN->rgnListEnd->Ymax;
}
}
return(regionSize);
}
/* =========================================================*/
/* If region building is enabled, makes a NULL region at
DESTRGN, followed by a NULL region list, if there's enough
room. */
/* ----------------SetupEmptyRegion to return----------- */
void SetupEmptyRegion(region *destRGN, int makeRegion,
int sizeRGN)
{
region *tem;
if(makeRegion == 1)
{
if(sizeRGN >= sizeof(region))
{
destRGN->rgnSize = sizeof(region);
/* It is a null region (empty) */
destRGN->rgnFlags = (short) rfNull;
destRGN->rgnRect.Xmin = 0;
destRGN->rgnRect.Xmax = 0;
destRGN->rgnRect.Ymin = 0;
destRGN->rgnRect.Ymax = 0;
/* No viable pointers to region data */
destRGN->rgnList = 0;
destRGN->rgnListEnd = 0;
if( sizeRGN >= (sizeof(region) + 2*sizeof(rect)) )
{
destRGN->rgnSize = (sizeof(region) + 2*sizeof(rect));
/* point to initial and tail sentinel */
tem = destRGN + 1;
destRGN->rgnListEnd = (rect *) tem;
destRGN->rgnList = (rect *) ((long)tem + sizeof(rect));
/* Fill the tail sentinel */
destRGN->rgnList->Xmin = rgnEOS;
destRGN->rgnList->Xmax = rgnEOS;
destRGN->rgnList->Ymin = rgnEOS;
destRGN->rgnList->Ymax = rgnEOS;
}
}
}
return;
}
/* ===================================================== */
/* To be called immediately when it is detected that the current YX band
differs from the previous YX band. Finishes setting the previous band (sets
Ymax), copies the identical portion of the previous band to a new band,
sets the new band's Ymin, and adjusts pointers.
On entry, ES:DN points to the rect after the last rect in the previous YX
band that matched the corresponding rect in the current YX band.
On exit, ES:DN points to storage location for next YX band rect. DS is
preserved. Other registers are not preserved.
Returns AE = 0 for success, = error code for GrafErr if error occurred */
int HandleChange(region *destRGN, int *destSizeLeft, rect *destScanMax,
int baseDestSize, int curtY, int makeRegion )
{
long temNUM;
short grafErrValue;
rect *tmpDestPtr;
temNUM = ((long) destPtr - (long) destSave);
if(makeRegion == 0)
{
*destSizeLeft = baseDestSize - temNUM;
return(0);/* return only to local haschanged success */
}
else
{
*destSizeLeft -= temNUM;
if(*destSizeLeft < 0)
{
grafErrValue = c_RectList + c_RgnOflow;
return(grafErrValue);
}
else
{
tmpDestPtr = destSave;
destPtr = destSave;
while(destPtr != destScanMax)
{
destPtr->Ymax = curtY;
destPtr++;
}
destSave = destScanMax;
while(temNUM > 0)
{
*destPtr = *tmpDestPtr;
destPtr->Ymin = curtY;
destPtr++;
tmpDestPtr++;
temNUM -= sizeof(rect);
}
}
}
return(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -