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

📄 xpol7.c

📁 nucleus 文件系统,内核和彩色图形系统,在小系统上非常好用
💻 C
📖 第 1 页 / 共 3 页
字号:
/*************************************************************************/
/*                                                                       */
/*         Copyright (c) 1997 - 1999 Accelerated Technology, Inc.        */
/*                                                                       */
/* PROPRIETARY RIGHTS of Accelerated Technology are involved in the      */
/* subject matter of this material.  All manufacturing, reproduction,    */
/* use, and sales rights pertaining to this subject matter are governed  */
/* by the license agreement.  The recipient of this software implicitly  */
/* accepts the terms of the license.                                     */
/*                                                                       */
/*************************************************************************/

/*************************************************************************/
/*                                                                       */
/* FILE NAME                                            VERSION          */
/*                                                                       */
/*      XPOL7.c                                          1.9             */
/*                                                                       */
/* COMPONENT                                                             */
/*                                                                       */
/*      All                                                              */
/*                                                                       */
/* DESCRIPTION                                                           */
/*                                                                       */
/*      This file contains the FindHighestEdge, AddEdgeToAET, __mwSL,    */
/* BuildSquareWidePenPolyLineGET & mwPolyLine functions.                 */
/*                                                                       */
/* AUTHOR                                                                */
/*                                                                       */
/*      Robert G. Burrill, Accelerated Technology, Inc.                  */
/*                                                                       */
/* DATA STRUCTURES                                                       */
/*                                                                       */
/*      None                                                             */
/*                                                                       */
/* FUNCTIONS                                                             */
/*                                                                       */
/*      None                                                             */
/*                                                                       */
/* DEPENDENCIES                                                          */
/*                                                                       */
/*      None                                                             */
/*                                                                       */
/* HISTORY                                                               */
/*                                                                       */
/*         NAME            DATE                    REMARKS               */
/*                                                                       */
/*         BobB           5/19/99     Corrected loop control for wide    */
/*                                     polylines.                        */
/*         BobB           6/4/99      Corrected table indeces            */
/*         MikeM          9/29/99     Corrected edge calculator for wide */
/*                                     polylines.                        */
/*                                                                       */
/*************************************************************************/

#include "meta_wnd.h"
#include "metconst.h"    /* MetaWINDOW Constant & Stucture Definitions */
#include "metports.h"    /* MetaWINDOW Port & Bitmap Definitions */
#include "grafdata.h"
#include "metmacs3.h"
#include "xpol_4.h"
#include "xpol_5.h"


/* Local Functions  */
void XSortAET(lineEdgeV **CurrentEdgePtr);
void mwScanGET(void **GETPtrPtr, blitRcd *fillRcd, int scanRcdSize, int shape,
			   int fillRule, int allEdgesAreLines);
void ScanOutAET(void *AETPtr);




/* Function FindHighestEdge keeps track of the highest and lowest
endpoints encountered, accounting for clipping.

Always returns a 1.*/

short FindHighestEdge(void)
{
	int tmpY;

	if (addStartY == addEndY) return(1);	/* 0-height? */
	if (addStartY > addEndY)
	{	/* exchange endpoint's Y */
		tmpY = addStartY;
		addStartY = addEndY;
		addEndY = tmpY;
	}

	/* trivially clip-reject edges */
	if((addStartY >= clpR.Ymax) || (addEndY <= clpR.Ymin)) return(1);
	if (clpR.Ymin > addStartY) addStartY = clpR.Ymin;
	if (currentY > addStartY) currentY = addStartY;
	if (clpR.Ymax < addEndY) addEndY = clpR.Ymax;

	if (maxY < addEndY) maxY = addEndY;
	return(1);
}


/* Function AddEdgeToAET adds the edge to the AET if it starts at currentY.

Returns 1 if a success and 0 if out of memory. 
*/

short AddEdgeToAET(void)
{
	int tmpDeltaX;
	int tmpDeltaY;
	int tmpXY;
	lineEdgeV *AETPtr;
	lineEdgeV **AETNextEdgePtr;
	lineEdgeV *tmpHighWater;

	if (addStartY == addEndY) return(1);	/* 0-height? */
	if (addStartY < addEndY)	/* which end is higher? */
	{	/* correct order */
		if (addStartY == currentY) goto DoAddEdge;
		/* check if clipped edge will start here */
		if ((addStartY < currentY) && (clpR.Ymin == currentY) &&
			(addEndY > currentY)) goto DoAddEdge;
		/* how far from currentY to this edge? */
		tmpDeltaY = addStartY - currentY;
		/* ignore if edge is above */
		if (tmpDeltaY < 0) return(1);
		/* is this a new closest edge? */
		if (tmpDeltaY < numLinesUntilNext)
			numLinesUntilNext = tmpDeltaY;
		return(1);
	}
	else
	{	/* start is greater than end so check end - start */
		if (addEndY == currentY) goto DoAddEdge;
		/* check if clipped edge will start here */
		if ((addEndY < currentY) && (clpR.Ymin == currentY) &&
			(addStartY > currentY)) goto DoAddEdge;
		/* how far from currentY to this edge? */
		tmpDeltaY = addEndY - currentY;
		/* ignore if edge is above */
		if (tmpDeltaY < 0) return(1);
		/* is this a new closest edge? */
		if (tmpDeltaY < numLinesUntilNext)
			numLinesUntilNext = tmpDeltaY;
		return(1);
	}

DoAddEdge:
	/* add the edge */
	/* new high water mark plus room for one rect */
	tmpHighWater = ((lineEdgeV *) ((long) (highWater + 1))) - 1;
	/* is there currently room for this edge? */
	if ((long) tmpHighWater < (long) rectPtr)
	{	/* no, clear the rects and try again */
		if (rectCount == 0) return(0);	/* no room */
		lclFillRcd->blitCnt = rectCount;	/* set the count field */
		lclFillRcd->blitDmap->prFill(lclFillRcd);	/* draw the rectangles */

		rectCount = 0;	/* reset the # of rects in the rect list to 0 */
		rectPtr = rectBase;	/* the next rect goes at the start of the rect list */
		sameAsLast = 0;	/* mark that this line can't be treated as the same
						as the last line, because the last line's rectangles
						aren't around any more */
		if ((long) tmpHighWater < (long) rectPtr) return(0);	/* still no room? */
	}

	/* yes, point to the new high water mark (last address at which
	there's room for two more rects) */
	highWater = ((rect *) ((long) tmpHighWater)) - 1;
	tmpHighWater = (lineEdgeV *) ((long) (highWater + 2));

	sameAsLast = 0;	/* mark that this line isn't the same as the preceding
					line (because we are about to add an edge) */
	if (addStartY < addEndY)	/* make sure the edge runs top->bottom */
	{	/* yes */
		tmpHighWater->TopToBottom = 1;
	}
	else
	{	/* no, swap endpoints */
		tmpHighWater->TopToBottom = -1;
		tmpXY = addStartX;
		addStartX = addEndX;
		addEndX = tmpXY;
		tmpXY = addStartY;
		addStartY = addEndY;
		addEndY = tmpXY;
	}

	tmpHighWater->CurrentX = addStartX;
	tmpHighWater->StartY = addStartY;
	tmpDeltaY = addEndY - addStartY;
	tmpHighWater->Count = tmpDeltaY;
	tmpHighWater->ErrorTermAdjDownV = tmpDeltaY;
	tmpDeltaX = addEndX - addStartX;

	if (tmpDeltaX >= 0)	/* check X direction */
	{	/* left->right */
		tmpHighWater->XDirection = 1;	/* direction in which X moves */
		tmpHighWater->ErrorTermV = -1;	/* initial error term */
	}
	else
	{	/* right->left */
		tmpDeltaX = -tmpDeltaX;	/* abs(tmpDeltaX) */
		tmpHighWater->XDirection = -1;
		tmpHighWater->ErrorTermV = -tmpDeltaY;
	}

	if (tmpDeltaY >= tmpDeltaX)	/* X major or Y major? */
	{	/* Y major */
		tmpHighWater->WholePixelXMoveV = 0;
		tmpHighWater->ErrorTermAdjUpV = tmpDeltaX;
	}
	else
	{	/* X major */
		tmpHighWater->ErrorTermAdjUpV = tmpDeltaX % tmpDeltaY;
		if (tmpHighWater->XDirection == 1)
		{
			tmpHighWater->WholePixelXMoveV = tmpDeltaX / tmpDeltaY;
		}
		else
		{
			tmpHighWater->WholePixelXMoveV = - tmpDeltaX / tmpDeltaY;
		}
	}

	if (tmpHighWater->StartY < clpR.Ymin)	/* does this edge start above top clip? */
	{	/* yes, jump it ahead */
		tmpHighWater->Count -= (clpR.Ymin - tmpHighWater->StartY);	/* clip count */
		tmpHighWater->StartY = clpR.Ymin;	/* new start Y (at top clip) */

		/* adjust error term for # of times we would have adjusted it in
		advancing that many points */
		tmpHighWater->ErrorTermV += (tmpHighWater->Count * 
			tmpHighWater->ErrorTermAdjUpV);
		if (tmpHighWater->ErrorTermV >= 0)	/* check if it turned over */
		{	/* yes it did so correct it */
			if (tmpHighWater->XDirection == 1)	/* which direction? */
			{	/* left->right */
				tmpHighWater->CurrentX += ((tmpHighWater->ErrorTermV / 
					tmpHighWater->ErrorTermAdjDownV) + 1);
			}
			else
			{	/* right to left */
				tmpHighWater->CurrentX -= ((tmpHighWater->ErrorTermV / 
					tmpHighWater->ErrorTermAdjDownV) + 1);
			}

			tmpHighWater->ErrorTermV = ((tmpHighWater->ErrorTermV % 
				tmpHighWater->ErrorTermAdjDownV) -
				tmpHighWater->ErrorTermAdjDownV);
		}

		tmpHighWater->CurrentX += (short) (tmpDeltaX * tmpHighWater->WholePixelXMoveV);
	}
	/* finally, link the new edge in so that the edge list is still sorted
	by X coordinate */
	AETNextEdgePtr = AETPtrPtr;
	while ((AETPtr = *AETNextEdgePtr) != 0)
	{
		if (AETPtr->CurrentX >= tmpHighWater->CurrentX) break;
		AETNextEdgePtr = &AETPtr->NextEdge;
	}

	/* link in the edge before the next edge we just reached */
	tmpHighWater->NextEdge = AETPtr;
	*AETNextEdgePtr = tmpHighWater;

	return(1);
}


/* Function __mwSL scans out an edge list when there's too little memory
for the GET. */

void __mwSL(void)
{
	short grafErrValue;
	point *saveVertexListPtr;
	int saveLclNpointsparm;
	byte *saveBuf1Ptr;
	lineEdgeV *AETPtr;
	lineEdgeV **tmpAETPtrPtr;
	lineEdgeV **newAETPtrPtr;
	lineEdgeV *tmpHighWater;

	currentY = 0x7fff;	/* point to bottom possible line; this can never
							be the starting line for an active edge */
	maxY = 0x8000;	/* top possible line */

	/* save the following for later use since the GET is built twice */
	saveLclNpointsparm = lclNpointsparm;
	saveVertexListPtr = vertexListPtr;
	saveBuf1Ptr = buf1Ptr;

	addEdgeVector = &FindHighestEdge;	/* routine called to check each edge
									for the highest endpoint in the polyline */
	updateAETVector();	/* scan for the highest endpoint */
	if (currentY > maxY) return;	/* skip if there are no edges to do */

	AETPtrPtr = ptrToGETPtr;	/* point to AETPtr */
	/* now set up the fill record according to the settings in the current port */
	lclFillRcd = (blitRcd *) (((long) AETPtrPtr) + SIZEOFF);
	*lclFillRcd = grafBlit;	/* Init local blitRcd from grafBlit */
	lclFillRcd->blitList = (long) (lclFillRcd + 1);

	/* calculate the last address at which a rect can start in the blitRcd
	without being the last rect that can fit in the blitRcd */
	highWater = (rect *) (((long) AETPtrPtr) + bufCntr - 2 * sizeof(rect));

	rectCount = 0;	/* no rects yet */
	rectBase = (rect *) lclFillRcd->blitList;	/* point to the first rect location */
	rectPtr = rectBase;

	*AETPtrPtr = 0;	/* AETPtr = NULL */
	sameAsLast = 0;	/* mark that the first line can't be the same as the
					preceding line */
	goto AddEdges;	/* add the first edges and go */

	do {
		/* Advance each edge in the AET by one scan line. Remove edges that
		have been fully scanned compressing the AET so that as much room as
		possible is always available for rects in the blitRcd. (Used only
		for low-memory case.) */

⌨️ 快捷键说明

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