⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xpol6.c

📁 nucleus 文件系统,内核和彩色图形系统,在小系统上非常好用
💻 C
📖 第 1 页 / 共 3 页
字号:
			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 + -