📄 xpol6.c
字号:
if (relPoint.Y < minPoint_Y)
{
minPoint_Y = relPoint.Y;
minIndexLPtr = lPoints; /* update minIndexLPtr */
leftEdgeStartX = relPoint.X; /* remember the X coord of
the minimum Y point */
}
else
{
if (relPoint.Y > maxPoint_Y)
{
maxPoint_Y = relPoint.Y;
/* BobB 11/9/99 - removed the following line since maxIndexPtr is never used
maxIndexPtr = lPoints; */ /* update maxIndexPtr */
}
}
lPoints++; /* point to next vertex */
}
lastPointX = relPoint.X; /* remember the X & Y coordinates */
lastPointY = relPoint.Y; /* of the last point */
}
else
{ /* coord mode is origin (absolute) */
for (; npoints >= 1; npoints--)
{
if (lPoints->X < minX)
{
minX = lPoints->X;
}
else
{
if (lPoints->X > maxX) maxX = lPoints->X;
}
if (lPoints->Y < minPoint_Y)
{
minPoint_Y = lPoints->Y;
minIndexLPtr = lPoints; /* update minIndexLPtr */
leftEdgeStartX = lPoints->X; /* remember the X coord of
the minimum Y point */
}
else
{
if (lPoints->Y > maxPoint_Y)
{
maxPoint_Y = lPoints->Y;
/* BobB 11/9/99 - removed the following line since maxIndexPtr is never used
maxIndexPtr = lPoints; */ /* update maxIndexPtr */
}
}
lPoints++; /* point to next vertex */
}
}
if (minPoint_Y == maxPoint_Y) return; /* return if there's
nothing to draw (flat polygon) */
vertexListEnd = (long) lPoints; /* remember where the vertex
list ends */
/* reject the polygon if it's fully out of the visible area */
if (((minX + lclXAdjust) >= clpR.Xmax) ||
((maxX + lclXAdjust) <= clpR.Xmin) ||
((minPoint_Y + lclYAdjust) >= clpR.Ymax) ||
((maxPoint_Y + lclYAdjust) <= clpR.Ymin)) return;
/* now find the two ends of the top edge */
lPoints = minIndexLPtr;
minIndexRPtr = minIndexLPtr;
if (mode == coordModePrevious) /* which coord mode? */
{ /* scan in previous (relative) mode in ascending order to find
the last top-edge point */
relPoint.X = leftEdgeStartX; /* initial X coord at Ymin point */
while (1)
{
minIndexRPtr++; /* point to the next vertex */
if ((long) minIndexRPtr == vertexListEnd) /* have we wrapped off the end? */
{ /* yes, wrap back to the start */
minIndexRPtr = points; /* wrap back to the start */
if (minIndexRPtr->Y != minPoint_Y) /* still at top? */
{ /* no, wrap back to the end of the list */
minIndexRPtr = (point *) vertexListEnd;
break;
}
relPoint.X = minIndexRPtr->X; /* initial point is absolute */
}
else
{ /* no , is this vertex still at the top? */
if (minIndexRPtr->Y != 0) break;
relPoint.X += minIndexRPtr->X; /* keep track of the X coord */
}
}
minIndexRPtr--; /* point back to the last vertex at the top */
rightEdgeStartX = relPoint.X;
/* now scan in descending order to find the first top-edge point */
relPoint.X = leftEdgeStartX; /* initial X coord at min point */
while (1)
{
if (minIndexLPtr == points) /* are we at the start of the list? */
{ /* yes, handle in origin mode */
/* is the last point in the list still at the minimum Y? */
if (lastPointY != minPoint_Y) break; /* no if break */
relPoint.X = lastPointX; /* keep track of the X coord */
minIndexLPtr = (point *) (vertexListEnd) - 1 ; /* point to
the previous vertex */
}
else
{ /* no, handle in previous (relative) mode */
/* is the previous vertex still at the top? */
if (minIndexLPtr->Y != 0) break;
relPoint.X -= minIndexLPtr->X; /* keep track of the X coord */
minIndexLPtr--; /* point to the previous vertex */
}
}
leftEdgeStartX = relPoint.X;
}
else
{ /* scan in origin (absolute) mode in ascending order to find
the last top-edge point */
while (1)
{
minIndexRPtr++; /* point to the next vertex */
if ((long) minIndexRPtr == vertexListEnd) /* have we wrapped off the end? */
{ /* yes, wrap back to the start */
minIndexRPtr = points; /* wrap back to the start */
if (minIndexRPtr->Y != minPoint_Y) /* still at top? */
{ /* no, wrap back to the end of the list */
minIndexRPtr = (point *) vertexListEnd;
break;
}
}
else
{ /* no , is this vertex still at the top? */
if (minIndexRPtr->Y != minPoint_Y) break;
}
}
minIndexRPtr--; /* point back to the last vertex at the top */
rightEdgeStartX = minIndexRPtr->X;
/* now scan in descending order to find the first top-edge point */
while (1)
{
if (minIndexLPtr == points) /* are we at the start of the list? */
{ /* yes, is the last point in the list still at the minimum Y? */
minIndexLPtr = (point *) (vertexListEnd) - 1; /* point to
the previous vertex */
if (minIndexLPtr->Y != minPoint_Y)
{
minIndexLPtr = points; /* wrap back to start */
break;
}
}
else
{ /* no, is the previous vertex still at the top? */
minIndexLPtr--; /* point to the previous vertex */
if (minIndexLPtr->Y != minPoint_Y)
{
minIndexLPtr++; /* point back to the last vertex */
break;
}
}
}
leftEdgeStartX = minIndexLPtr->X;
}
/* Figure out which direction through the vertex list from the top
vertex is the left edge and which is the right. At this point,
minIndexRPtr points to the last vertex on the top edge in the
ascending direction through the vertex list, and minIndexLPtr points
to the last vertex on the top edge in the descending direction */
leftEdgeDir = (char)-1; /* assume left edge runs down thru vertex list */
topIsFlat = 0; /* assume that the top isn't flat */
if (mode == coordModePrevious) /* which coord mode? */
{ /* coord mode is previous (relative) */
if (leftEdgeStartX == rightEdgeStartX) /* is top flat? */
{ /* the top isn't flat */
/* point to the downward end of the first line of each of the
two edges down from the top; calculate X and Y lengths from
the top vertex to the end of the first line down each edge;
use those to compare slopes and see which line is leftmost */
/* BobB 5/12/99 - added the following line to get the correct RPtr */
tmpMinIndexPtr = minIndexRPtr;
minIndexRPtr++; /* point to the next vertex */
if ((long) minIndexRPtr == vertexListEnd) /* have we wrapped? */
{ /* yes, wrap to start of the list */
minIndexRPtr = points;
deltaXN = minIndexRPtr->X;
}
else
{ /* no, so calculate the X coord of the first point off the
right end of the top as a delta from the right-end point */
deltaXN = rightEdgeStartX + minIndexRPtr->X;
}
deltaXN -= leftEdgeStartX; /* the first point down off the
top edge incrementing through the list */
deltaYN = minIndexRPtr->Y; /* unless this is the first
point in the list */
if (minIndexRPtr == points) deltaYN -= minPoint_Y;
/* now, calculate deltas to the previous point (decrementing
through list) */
/* BobB 5/12/99 - corrected the following line to get correct RPtr
minIndexRPtr = minIndexLPtr; */ /* save top pointer for later */
minIndexRPtr = tmpMinIndexPtr; /* restore top pointer */
if (minIndexLPtr == points) /* are we at the top of the list? */
{ /* yes */
deltaXP = lastPointX - leftEdgeStartX;
deltaYP = lastPointY - minPoint_Y;
}
else
{
deltaXP = - minIndexLPtr->X;
deltaYP = - minIndexLPtr->Y;
}
deltaXPYN = deltaXP * deltaYN;
deltaXNYP = deltaXN * deltaYP;
if (deltaXNYP < deltaXPYN) leftEdgeDir = 1;
}
else
{ /* the top is flat, so just see which of the ends is leftmost;
if it's the one we've already marked as left, we're all set,
otherwise swap the left and right edges */
topIsFlat = 1;
if (leftEdgeStartX > rightEdgeStartX)
{ /* swap edges */
relPoint.X = leftEdgeStartX;
leftEdgeStartX = rightEdgeStartX;
rightEdgeStartX = relPoint.X;
tmpMinIndexPtr = minIndexLPtr;
minIndexLPtr = minIndexRPtr;
minIndexRPtr = tmpMinIndexPtr;
leftEdgeDir = 1;
}
}
}
else
{ /* coord mode is origin (absolute) */
if (leftEdgeStartX == rightEdgeStartX) /* is top flat? */
{ /* the top isn't flat */
/* point to the downward end of the first line of each of the
two edges down from the top; calculate X and Y lengths from
the top vertex to the end of the first line down each edge;
use those to compare slopes and see which line is leftmost */
/* BobB 5/12/99 - added the following line to get the correct RPtr */
tmpMinIndexPtr = minIndexRPtr;
minIndexRPtr++; /* point to the next vertex */
if ((long) minIndexRPtr == vertexListEnd) minIndexRPtr = points;
deltaXN = minIndexRPtr->X - minIndexLPtr->X;
deltaYN = minIndexRPtr->Y - minIndexLPtr->Y;
minIndexRPtr = minIndexLPtr; /* save top pointer for later */
/* BobB 5/12/99 - corrected the following 6 lines to get correct LPtr
if (minIndexLPtr == points) minIndexLPtr = (point *) vertexListEnd;
minIndexLPtr--; */ /* point to the previous vertex */
/* deltaXP = minIndexLPtr->X - minIndexRPtr->X;
deltaYP = minIndexLPtr->Y - minIndexRPtr->Y;
minIndexLPtr = minIndexRPtr; */ /* restore top pointer */
if (minIndexRPtr == points) minIndexRPtr = (point *) vertexListEnd;
minIndexRPtr--; /* point to the previous vertex */
deltaXP = minIndexRPtr->X - minIndexLPtr->X;
deltaYP = minIndexRPtr->Y - minIndexLPtr->Y;
minIndexRPtr = tmpMinIndexPtr; /* restore top pointer */
deltaXPYN = deltaXP * deltaYN;
deltaXNYP = deltaXN * deltaYP;
if (deltaXNYP < deltaXPYN) leftEdgeDir = 1;
}
else
{ /* the top is flat, so just see which of the ends is leftmost;
if it's the one we've already marked as left, we're all set,
otherwise swap the left and right edges */
topIsFlat = 1;
if (leftEdgeStartX > rightEdgeStartX)
{ /* swap edges */
relPoint.X = leftEdgeStartX;
leftEdgeStartX = rightEdgeStartX;
rightEdgeStartX = relPoint.X;
tmpMinIndexPtr = minIndexLPtr;
minIndexLPtr = minIndexRPtr;
minIndexRPtr = tmpMinIndexPtr;
leftEdgeDir = 1;
}
}
}
/* set the # of scan lines in the polygon, skipping the bottom edge
and also skipping the top vertex if the top isn't flat because in that
case the top vertex has only a right edge component, and set the top
scan line to draw, which is likewise the second line of the polygon
unless the top is flat */
if (rectClipFlag == 0) /* do we do any clipping? */
{ /* no--valid coordinates are guaranteed at a higher level */
polyScans = maxPoint_Y;
}
else
{
polyScans = (int) (clpR.Ymax - lclYAdjust); /* adjust to local coords */
if (polyScans > maxPoint_Y) polyScans = maxPoint_Y;
}
polyScans += (topIsFlat - minPoint_Y);
if (polyScans == 0) return; /* skip if not at least one line */
currentYScan = (int) (minPoint_Y + 1 - topIsFlat + lclYAdjust);
/* scan down the left edge and then the right edge, in bursts of
either the edge size or the max number of rects that will fit in
the buffer */
skipFirstL = topIsFlat ^ 1; /* skip first point only if top isn't flat */
skipFirstR = skipFirstL;
/* first time through, no restart is in progress */
leftRestartStruc.scanEdgeFirstPass = 1;
rightRestartStruc.scanEdgeFirstPass = 1;
do { /* scan loop */
lclBlitRcdPtr->blitCnt = polyScans;
skipFill = 0; /* assume we're not off the top of the clip rect */
if ((rectClipFlag != 0) && (clpR.Ymin > currentYScan))
{ /* clipping required */
lclBlitRcdPtr->blitCnt = clpR.Ymin - currentYScan;
skipFill++; /* mark that we're off the clip rect top */
currentYScan = clpR.Ymin; /* for next time */
}
scanListPtrR = (rect *) (((long) lclScratchBufferPtr) +
sizeof(blitRcd));
scanListPtrP = (point *) (long) scanListPtrR;
scanListPtrPR = scanListPtrP + 1;
if (lclBlitRcdPtr->blitCnt > maxRectCnt)
lclBlitRcdPtr->blitCnt = (short) maxRectCnt;
/* count the lines we'll do in this burst off from remaining total */
polyScans -= (lclBlitRcdPtr->blitCnt + skipFirstL);
/* set the initial pointer for storing scan converted left-edge coords */
/* set the Y coords for all scan lines */
if (skipFill == 0) /* are we off the top? */
{ /* no */
for (i = 0; i < lclBlitRcdPtr->blitCnt; i++)
{
scanListPtrR->Ymin = currentYScan;
currentYScan++;
scanListPtrR->Ymax = currentYScan;
scanListPtrR = scanListPtrR + 1;
}
}
/* scan out as much of the left edge as possible */
ScanBurst(lclBlitRcdPtr->blitCnt, skipFirstL, (short) lclXAdjust,(char) leftEdgeDir,
&leftRestartStruc, &scanListPtrP, minIndexLPtr, &leftEdgeStartX,
points, mode);
skipFirstL = 0; /* don't skip the first point from now on */
/* scan out as much of the right edge as possible */
/* first, set scan list pointer to point to Xmax values */
ScanBurst(lclBlitRcdPtr->blitCnt, skipFirstR,(short) lclXAdjust,(char) -leftEdgeDir,
&rightRestartStruc, &scanListPtrPR, minIndexRPtr, &rightEdgeStartX,
points, mode);
skipFirstR = 0; /* don't skip the first point from now on */
/* skip the fill if all lines in this burst are above the top edge
of the clip rect; else draw the rectangles */
if (skipFill == 0)
lclBlitRcdPtr->blitDmap->prFill(lclBlitRcdPtr);
} while (polyScans > 0);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -