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

📄 xpol7.c

📁 nucleus 文件系统,内核和彩色图形系统,在小系统上非常好用
💻 C
📖 第 1 页 / 共 3 页
字号:
		newAETPtrPtr = AETPtrPtr;
		while ((AETPtr = *newAETPtrPtr) != 0)	/* skip if nothing in AET */
		{
			AETPtr->Count--;	/* decrement the y counter */
			if (AETPtr->Count == 0)	/* check if done with edge */
			{	/* Yes, remove it from the AET. If it's not the edge
				nearest the high water mark, copy the edge nearest the
				high water mark into the hole and relink it; then move
				the high water mark up one edge */
				sameAsLast = 0;
				*newAETPtrPtr = AETPtr->NextEdge;
				tmpAETPtrPtr = newAETPtrPtr;

				/* now, if there's an edge at the high water mark, move
				it into the hole we just made */
				/* point to the lowest address at which an edge could start */
				tmpHighWater = (lineEdgeV *) ((long) (highWater + 2));
				if (AETPtr != tmpHighWater)	/* was the edge we just removed */
				{	/* the one at the high water mark? */
					tmpAETPtr = *AETPtrPtr;	/* no need to check for NULL
						pointer; if there was only one edge in the AET and
						we just removed it, it would have been at the high
						water mark and we'd never get here */
					newAETPtrPtr = AETPtrPtr;
					while (tmpAETPtr != tmpHighWater)
					{
						newAETPtrPtr = &tmpAETPtr->NextEdge;
						tmpAETPtr = *newAETPtrPtr;
					}

					if (tmpAETPtr == (lineEdgeV *) tmpAETPtrPtr)	/* was the */
					{						/* last edge the one we're moving? */
						tmpAETPtrPtr = (lineEdgeV **) AETPtr;	/* remember
													the edge's new location */
					}

					*newAETPtrPtr = AETPtr;	/* relink the edge at its new
											location */
					newAETPtrPtr = (lineEdgeV **) AETPtr;
					*AETPtr = *tmpAETPtr;	/* move the data */
				}

				/* adjust the high water mark for the extra room we just
				made available */
				highWater = (rect *) (((long) highWater) + sizeof(lineEdgeV));
				newAETPtrPtr = tmpAETPtrPtr;
			}
			else
			{	/* count off one scan line for this edge */
				if (AETPtr->WholePixelXMoveV != 0)
				{	/* advance the edge's X coordinate by the minimum
					# of pixels */
					sameAsLast = 0;
					AETPtr->CurrentX += (short) AETPtr->WholePixelXMoveV;
				}

				AETPtr->ErrorTermV += AETPtr->ErrorTermAdjUpV;
				if (AETPtr->ErrorTermV > 0)
				{	/* the error term turned over, so move X one more */
					sameAsLast = 0;
					AETPtr->CurrentX += (short) AETPtr->XDirection;
					AETPtr->ErrorTermV -= AETPtr->ErrorTermAdjDownV;
				}

				newAETPtrPtr = &AETPtr->NextEdge;
			}
		}
		
		XSortAET(AETPtrPtr);	/* X sort the AET */
		numLinesUntilNext--;
		if (numLinesUntilNext == 0)	/* time to add another edge to the AET? */
		{
AddEdges:	/* jump inside this loop the first time */
			numLinesUntilNext = 0x7fff;	/* max value so will always be replaced
				by correct value if there is a next edge to start; otherwise,
				counts down for the remainder of this fill (no more edges
				to start) */
			/* restore the previously saved data for the next GET build */
			lclNpointsparm = saveLclNpointsparm;
			vertexListPtr = saveVertexListPtr;
			buf1Ptr = saveBuf1Ptr;
			addEdgeVector = &AddEdgeToAET;	/* routine called to add each
											edge to the AET */
			if (updateAETVector() == 0)	/* add to the AET all edges that start */
			{		/* at the current scan line, and set new numLinesUntilNext */
				grafErrValue = c_PolyLine +  c_EdgeOflo;	/* there isn't even */
				nuGrafErr(grafErrValue);	/* enough memory to hold the AET */
				return;
			}
		}
		
		if ((AETPtr = *AETPtrPtr) != 0)
		{
			ScanOutAET(AETPtr);	/* do winding rule scan out for this scan line */
		}

		currentY++;	/* continue if we haven't done the bottom line yet */
	} while (currentY <= maxY);

	if (rectCount != 0)	/* do any rects remain? */
	{	/* yes, do the remaining rects */
		lclFillRcd->blitCnt = rectCount;	/* set the count field */
		lclFillRcd->blitDmap->prFill(lclFillRcd);	/* draw the rectangles */
	}
	return;
}


/* Function BuildSquareWidePenPolyLineGET builds a global edge table from
the point list for a square, wide pen. The GET is a linked list,  sorted
first by Y coordinate, then by X coordinate.

Returns 1 for success, 0 for failure (insufficient memory). */



short BuildSquareWidePenPolyLineGET(void)
{
#define PEN_LEFT	0
#define PEN_RIGHT	1
#define PEN_UP		2
#define PEN_DOWN	3
/* For various directions, offset directions to corners of square pen at
which the edges parallel to the ideal line start and end. */
byte StartEndSetTable[8][8] = {
	PEN_LEFT,	PEN_DOWN,	PEN_LEFT,	PEN_UP,		/* Dir0StartEnd */
	PEN_RIGHT,	PEN_UP,		PEN_RIGHT,	PEN_DOWN,
	PEN_LEFT,	PEN_UP,		PEN_LEFT,	PEN_UP,		/* Dir1StartEnd */
	PEN_RIGHT,	PEN_DOWN,	PEN_RIGHT,	PEN_DOWN,
	PEN_LEFT,	PEN_UP,		PEN_RIGHT,	PEN_UP,		/* Dir2StartEnd */
	PEN_RIGHT,	PEN_DOWN,	PEN_LEFT,	PEN_DOWN,
	PEN_RIGHT,	PEN_UP,		PEN_RIGHT,	PEN_UP,		/* Dir3StartEnd */
	PEN_LEFT,	PEN_DOWN,	PEN_LEFT,	PEN_DOWN,
	PEN_RIGHT,	PEN_UP,		PEN_RIGHT,	PEN_DOWN,	/* Dir4StartEnd */
	PEN_LEFT,	PEN_DOWN,	PEN_LEFT,	PEN_UP,
	PEN_RIGHT,	PEN_DOWN,	PEN_RIGHT,	PEN_DOWN,	/* Dir5StartEnd */
	PEN_LEFT,	PEN_UP,		PEN_LEFT,	PEN_UP,
	PEN_RIGHT,	PEN_DOWN,	PEN_LEFT,	PEN_DOWN,	/* Dir6StartEnd */
	PEN_LEFT,	PEN_UP,		PEN_RIGHT,	PEN_UP,
	PEN_LEFT,	PEN_DOWN,	PEN_LEFT,	PEN_DOWN,	/* Dir7StartEnd */
	PEN_RIGHT,	PEN_UP,		PEN_RIGHT,	PEN_UP};
	int xDirection;
	int yDirection;
	int directionDifference;
	point *vrtxListPtr;	/* local copy of vertexListPtr for wrap back */






	rawLastX = vertexListPtr->X;	/* remember this X,Y for next time */
	rawLastY = vertexListPtr->Y;
	vrtxListPtr = vertexListPtr;

	if (globalLevel > 0)	/* already in global? */
	{	/* no, convert to global */
		U2GP(rawLastX, rawLastY, &startX, &startY, 1);
	}
	else
	{
		startX = rawLastX;
		startY = rawLastY;
	}

	firstSegment = 1;	/* mark that this is the first line segment */

	do {
		if(lclNpointsparm == 1)	/* is this the last vertex? */
		{	/* yes, so potentially wrap back to the first point. Also
			remember where the last point of the polyline is, in both
			user and global coords, for advancing the pen location at
			the end. This point is always reached at least once, even
			when polyline drawing fails, and isn't reached until the
			last point */
			if (finalWrap != 1)	/* do we wrap back from the end to the start? */
			{	/* no, so we're done */
				finalRawX = rawLastX;	/* remember where the pen */
				finalRawY = rawLastY;	/* location advances to when */
				finalGblX = startX;		/* we're done */
				finalGblY = startY;
				break;
			}
			/* wrap back to the start of the vertex list */
			/* load the endpoint of this segment and convert it
			to global coords */
			finalRawX = vertexListPtr->X;
			finalRawY = vertexListPtr->Y;
			if (globalLevel > 0)	/* already in global? */
			{	/* no, convert to global */
				U2GP(finalRawX, finalRawY, &finalGblX, &finalGblY, 1);
			}
			else
			{
				finalGblX = finalRawX;
				finalGblY = finalRawY;
			}
		}
		else
		{
			vrtxListPtr++;	/* point to next vertex */
			if (lclModeparm == coordModePrevious)	/* previous mode? */
			{	/* yes, calculate new position as a delta from the
					last X,Y in user coordinates */
				rawLastX += vrtxListPtr->X;
				rawLastY += vrtxListPtr->Y;
			}
			else
			{
				rawLastX = vrtxListPtr->X;
				rawLastY = vrtxListPtr->Y;
			}

			if (globalLevel > 0)	/* already in global? */
			{	/* no, convert to global */
				U2GP(rawLastX, rawLastY, &endX, &endY, 1);
			}
			else
			{
				endX = rawLastX;
				endY = rawLastY;
			}
		}

		xDirection = endX - startX;
		yDirection = endY - startY;
		if (xDirection == 0)
		{	/* vertical direction */
/* BobB 5/19/99 - corrected the following line to continue to next point
			if (yDirection == 0) break; */	/* no movement */
			if (yDirection == 0) 
                continue;	/* no movement */
			if (yDirection < 0) 
                direction = 0;	/* straight up */
			else 
                direction = 4;	/* straight down */
		}
		else
		{
			if (xDirection < 0)
			{	/* moving left */
				if (yDirection == 0) 
                    direction = 6;	/* straight left */
				if (yDirection < 0) 
                    direction = 7;	/* up and to the left */
				else 
                    direction = 5;	/* down and to the left */
			}
			else
			{
				if (yDirection == 0) 
                    direction = 2;	/* straight right */
				if (yDirection < 0) 
                    direction = 1;	/* up and to the right */
				else 
                    direction = 3;	/* down and to the right */
			}
		}

		/* build the two edges that are parallel to the ideal line */
		/*start->end edge start X */
		startOutX = startX + halfWidth[StartEndSetTable[direction][0]];
		/*start->end edge start Y */
		startOutY = startY + halfWidth[StartEndSetTable[direction][1]];
		/*start->end edge end X */
		endInX = endX + halfWidth[StartEndSetTable[direction][2]];
		/*start->end edge end Y */
		endInY = endY + halfWidth[StartEndSetTable[direction][3]];
		/* add start->end edge  and check if enough memory */
		addStartX = startOutX;
		addStartY = startOutY;
		addEndX = endInX;
		addEndY = endInY;
		if (addEdgeVector() != 1) 
            return(0);	/* fail if return */

/* BobB 6/4/99 - corrected the following lines for table values */
		/*end->start edge start X */
		/* startInX = startX + halfWidth[StartEndSetTable[direction][4]]; */
		/*end->start edge start Y */
		/* startInY = startY + halfWidth[StartEndSetTable[direction][5]]; */
		/*end->start edge end X */
		/* endOutX = endX + halfWidth[StartEndSetTable[direction][6]]; */
		/*end->start edge end Y */
		/* endOutY = endY + halfWidth[StartEndSetTable[direction][7]]; */
		/*end->start edge start X */
		startInX = startX + halfWidth[StartEndSetTable[direction][6]];
		/*end->start edge start Y */
		startInY = startY + halfWidth[StartEndSetTable[direction][7]];
		/*end->start edge end X */
		endOutX = endX + halfWidth[StartEndSetTable[direction][4]];
		/*end->start edge end Y */
		endOutY = endY + halfWidth[StartEndSetTable[direction][5]];
		/* add end->start edge  and check if enough memory */
		addStartX = endOutX;
		addStartY = endOutY;
		addEndX = startInX;
		addEndY = startInY;
		if (addEdgeVector() != 1) 
            return(0);	/* fail if return */

		if (firstSegment == 1)	/* is this the first line segment? */
		{	/* yes, just add an edge if necessary to close up the first segment */
			firstSegment = 0;	/* after this, it's not the first line segment */
			/* close up according to direction */
			if ((direction == 0) || (direction == 4)) 
                goto PrepareForNext;
			if (direction > 4)
			{	/* direction 5-7 -- add a right edge */
				addStartX = startX + halfWidthRight;
				addStartY = startY + halfHeightUp;
				addEndX = addStartX;
				addEndY = startY + halfHeightDown;
				if (addEdgeVector() != 1) 
                    return(0);	/* fail if return */
			}
			else
			{	/* direction 1-3 -- add a left edge */
				addStartX = startX + halfWidthLeft;
				addStartY = startY + halfHeightDown;
				addEndX = addStartX;
				addEndY = startY + halfHeightUp;
				if (addEdgeVector() != 1) 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -