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

📄 lin07.c

📁 nucleus 文件系统,内核和彩色图形系统,在小系统上非常好用
💻 C
📖 第 1 页 / 共 3 页
字号:

	/* l->r, t->b Xmajor  */
		case 2:
			check = lineState.lsErrTerm + lineState.lsErrTermAdjUp;
			if(check > 0x7FFF)
			{
				lineState.lsDYmin++;
				check -= lineState.lsErrTermAdjDown;
			}

			lineState.lsErrTerm = (short) check;
			lineState.lsDXmin++;
			lineState.lsMajorAxisLengthM1--;
			break;

	/* r->l, t->b Xmajor  */
		case 3:
			check = lineState.lsErrTerm + lineState.lsErrTermAdjUp;
			if(check > 0x7FFF)
			{
				lineState.lsDYmin++;
				check -= lineState.lsErrTermAdjDown;
			}

			lineState.lsErrTerm = (short) check;
			lineState.lsDXmin--;
			lineState.lsMajorAxisLengthM1--;
			break;

	/* r->l, b->t Ymojor  */
		case 4:
			check = lineState.lsErrTerm + lineState.lsErrTermAdjUp;
			if(check > 0x7FFF)
			{
				lineState.lsDXmin--;
				check -= lineState.lsErrTermAdjDown;
			}

			lineState.lsErrTerm = (short) check;
			lineState.lsDYmin--;
			lineState.lsMajorAxisLengthM1--;
			break;

	/* l->r, b->t Ymajor  */
		case 5:
			lineState.lsDYmin--;
			check = lineState.lsErrTerm + lineState.lsErrTermAdjUp;
			if(check > 0x7FFF)
			{
				lineState.lsDXmin++;
				check -= lineState.lsErrTermAdjDown;
			}

			lineState.lsErrTerm = (short) check;
			lineState.lsMajorAxisLengthM1--;
			break;

	/* l->r, b->t Xmajor  */
		case 6:
			check = lineState.lsErrTerm + lineState.lsErrTermAdjUp;
			if(check > 0x7FFF)
			{
				lineState.lsDYmin--;
				check -= lineState.lsErrTermAdjDown;
			}

			lineState.lsErrTerm = (short) check;
			lineState.lsDXmin++;
			lineState.lsMajorAxisLengthM1--;
			break;

	/* r->l, b->t Xmajor  */
		case 7:
			check = lineState.lsErrTerm + lineState.lsErrTermAdjUp;
			if(check > 0x7FFF)
			{
				lineState.lsDYmin--;
				check -= lineState.lsErrTermAdjDown;
			}

			lineState.lsErrTerm = (short) check;
			lineState.lsDXmin--;
			lineState.lsMajorAxisLengthM1--;
			break;
		}
	}
	if(lineState.lsSkipStat > 0)
/* BobB 3/10/99 - corrected the following line
		lineState.lsMajorAxisLengthM1 = (short) deltaX; */
		lineState.lsMajorAxisLengthM1--;
	return(0);
}


/*======================================================================
 Routine to scan out as much as possible of a line into a rect list in a
  blitRcd.  Performs all clipping, and saves the state in a lineState
  structure for restarting, if necessary.  Line is fully scanned if the
  lsMajorAxisLengthM1 field is < 0.
 Only generates lsMaxRects-1 as the maximum blitCnt; an additional rect is
  placed at the end of every burst (so there are blitCnt+1 rects in the
  blitList), but isn't counted in blitCnt; this is to allow for proper angle
  correction on the last pixel in dash handling.  */

void _mwLL(void)
{
	rect *rlistPtr;
	short temX,temY,tem;
	long error;

	tem = lineState.lsMajorAxisLengthM1 + 1;
	if(tem >= lineState.lsMaxRects) tem = lineState.lsMaxRects - 1;

	/* Set the # of rects for the filler to drawer after we generate them  */
	lclblitRec->blitCnt = tem;
	/* # of points - 1 for next time  */
	lineState.lsMajorAxisLengthM1 -= tem;
	rlistPtr = (rect *) lclblitRec->blitList;
	/* point to the location at which to store the first pixels rect  */
	switch(lineState.lsLineDir)
	{
/**/case 0: 
		temX = lineState.lsDXmin + 1;
		temY = lineState.lsDYmin;
		error = lineState.lsErrTerm;	
		while(tem-- > 0)
		{
			rlistPtr->Xmax = temX--;
			rlistPtr->Ymin = temY++;
			rlistPtr->Xmin = temX;
			rlistPtr->Ymax = temY;
			rlistPtr++;
			error += lineState.lsErrTermAdjUp;
			if(error < 0)
				temX++;		
			else
				error -= lineState.lsErrTermAdjDown;
		}
		lineState.lsErrTerm = (short) error;
		lineState.lsDYmin = temY;
		rlistPtr->Xmax = temX--;
		rlistPtr->Ymin = temY++;
		rlistPtr->Xmin = temX;
		rlistPtr->Ymax = temY;
		lineState.lsDXmin = temX;
		return;

/**/case 1: 
		temX = lineState.lsDXmin;
		temY = lineState.lsDYmin;
		error = lineState.lsErrTerm;
		while(tem-- >0)
		{
			rlistPtr->Xmin = temX++;
			rlistPtr->Ymin = temY++;
			rlistPtr->Xmax = temX;
			rlistPtr->Ymax = temY;
			rlistPtr++;
			error += lineState.lsErrTermAdjUp;	
			if(error < 0)
				temX--;
			else
				error -= lineState.lsErrTermAdjDown;
		}
		lineState.lsErrTerm = (short) error;
		lineState.lsDXmin = temX;
		lineState.lsDYmin = temY;
		rlistPtr->Xmin = temX++;
		rlistPtr->Ymin = temY++;
		rlistPtr->Xmax = temX;
		rlistPtr->Ymax = temY;
		return;

/**/case 2: 
		temX = lineState.lsDXmin;
		temY = lineState.lsDYmin;
		error = lineState.lsErrTerm;
		while(tem-- > 0)
		{
			rlistPtr->Xmin = temX++;
			rlistPtr->Ymin = temY++;
			rlistPtr->Xmax = temX;
			rlistPtr->Ymax = temY;
			rlistPtr++;
			error += lineState.lsErrTermAdjUp;
			if(error < 0)
				temY--;
			else
				error -= lineState.lsErrTermAdjDown;
		}
		lineState.lsErrTerm = (short) error;
		lineState.lsDXmin = temX;
		lineState.lsDYmin = temY;
		rlistPtr->Xmin = temX++;
		rlistPtr->Ymin = temY++;
		rlistPtr->Xmax = temX;
		rlistPtr->Ymax = temY;


		return;
	
/**/case 3:
		temX = lineState.lsDXmin + 1;
		temY = lineState.lsDYmin;
		error = lineState.lsErrTerm;
		while(tem-- >0)
		{
			rlistPtr->Xmax = temX--;
			rlistPtr->Ymin = temY++;
			rlistPtr->Xmin = temX;
			rlistPtr->Ymax = temY;
			rlistPtr++;
			error += lineState.lsErrTermAdjUp;
			if(error < 0)
				temY--;
			else
				error -= lineState.lsErrTermAdjDown;
		}
		lineState.lsErrTerm = (short) error;
		lineState.lsDYmin = temY;
		rlistPtr->Xmax = temX--;
		rlistPtr->Ymin = temY++;
		rlistPtr->Xmin = temX;
		rlistPtr->Ymax = temY;
		lineState.lsDXmin = temX;
		return;

/**/case 4:
		temX = lineState.lsDXmin + 1;
		temY = lineState.lsDYmin + 1;
		error = lineState.lsErrTerm;
		while(tem-- > 0)
		{
			rlistPtr->Xmax = temX--;
			rlistPtr->Ymax = temY--;
			rlistPtr->Ymin = temY;
			rlistPtr->Xmin = temX;
			rlistPtr++;
			error += lineState.lsErrTermAdjUp;
			if(error < 0)
				temX++;
			else
				error -= lineState.lsErrTermAdjDown;
		}
		lineState.lsErrTerm = (short) error;
		rlistPtr->Ymax = temY--;
		rlistPtr->Xmax = temX--;
		rlistPtr->Xmin = temX;
		rlistPtr->Ymin = temY;
		lineState.lsDXmin = temX;
		lineState.lsDYmin = temY;
		return;
	
/**/case 5:
		temX = lineState.lsDXmin;
		temY = lineState.lsDYmin + 1;
		error = lineState.lsErrTerm;
		while(tem-- > 0)
		{
			rlistPtr->Xmin = temX++;
			rlistPtr->Ymax = temY--;
			rlistPtr->Xmax = temX;
			rlistPtr->Ymin = temY;
			rlistPtr++;
			error += lineState.lsErrTermAdjUp;
			if(error < 0) 
				temX--;
			else
				error -= lineState.lsErrTermAdjDown;
		}
		lineState.lsErrTerm = (short) error;
		lineState.lsDXmin = temX;
		rlistPtr->Xmin = temX++;
		rlistPtr->Ymax = temY--;
		rlistPtr->Xmax = temX;
		rlistPtr->Ymin = temY;
		lineState.lsDYmin = temY;
		return;

	
/**/case 6:
		temX = lineState.lsDXmin;
		temY = lineState.lsDYmin + 1;
		error = lineState.lsErrTerm;
		while(tem-- > 0)
		{
			rlistPtr->Xmin = temX++;
			rlistPtr->Ymax = temY--;
			rlistPtr->Ymin = temY;
			rlistPtr->Xmax = temX;
			rlistPtr++;
			error += lineState.lsErrTermAdjUp;
			if(error < 0)
				temY++;
			else
				error -= lineState.lsErrTermAdjDown;
		}
		lineState.lsErrTerm = (short) error;
		lineState.lsDXmin = temX;
		rlistPtr->Xmin = temX++;
		rlistPtr->Ymax = temY--;
		rlistPtr->Ymin = temY;
		rlistPtr->Xmax = temX;
		lineState.lsDYmin = temY;
		return;

/**/case 7: 
		temX = lineState.lsDXmin + 1;
		temY = lineState.lsDYmin + 1;
		error = lineState.lsErrTerm;
		while(tem-- >0)
		{
			rlistPtr->Xmax = temX--;
			rlistPtr->Ymax = temY--;
			rlistPtr->Xmin = temX;
			rlistPtr->Ymin = temY;
			rlistPtr++;
			error += lineState.lsErrTermAdjUp;
			if(error < 0)
				temY++;
			else
				error -= lineState.lsErrTermAdjDown;
		}
		lineState.lsErrTerm = (short) error;
		rlistPtr->Xmax = temY--;
		rlistPtr->Ymax = temX--;
		rlistPtr->Xmin = temX;
		rlistPtr->Ymin = temY;
		lineState.lsDYmin = temY;
		lineState.lsDXmin = temX;
		return;
	}
	return;
}

/*=================================================================*/
/*** mwLID subroutine for dash thin line drawing  ***/
void mwLID(blitRcd *LINEREC)
{
void SetUpCommon(blitRcd *LINEREC);
	long temcount;
	short temindex;
	byte *temlist;
	rect *rlistPtr;
/* BobB 3/10/99 - added the following variable */
	int lclRectCnt;
	
	workingPnPat = grafPort.pnPat; /* Foreground pattern  */
	workingBkPat = grafPort.bkPat; /* Background pattern  */
	dashFlags = grafPort.pnFlags;  /* dash style and current state  */

	temcount = grafPort.pnDashCnt << 7;
	temindex = grafPort.pnDashNdx;
	dashElements  = grafPort.pnDashRcd[grafPort.pnDash].dashSize;
	dashListStart = (byte *) grafPort.pnDashRcd[grafPort.pnDash].dashList;
	temlist = dashListStart; /* use to move along the dash list  */
/* If dashCount is 0, then dashCount is initialized to the first entry
in the dash list, dashIndex is forced to the index of the first non-
zero-length dash, and the dash state is set to the first non-zero-
length dash's state; that is, the dash sequence is restarted. An
infinite loop will result if all dash lengths are 0!  */

	if(grafPort.pnDashCnt <= 0)
	{/*  Is it a zero count, so reinitialize the dash sequence */
		temcount = 1;
		temindex = -1;
		dashFlags &= ~pnDashState;
		do{
			dashFlags ^= pnDashState;
			temindex++;
			temcount = (*temlist++) << 7;
		}while(temcount == 0);
	}

	dashCount = temcount;
	dashIndex = temindex;
	SetUpCommon(LINEREC);

	/* Check for square pen wide line  */
	if(dashFlags & pnSizeFlg)
	{
		HandleWideSq();
		return;
	}
	/* Check for double dash line  */
	if(dashFlags & pnDashStyle)
	{
		DoubleDash();
		return;
	}

	/* on-off line */
	lineState.lsMaxRects = MAX_RECTS;
/* Main on-off line-drawing loop  */
/* BobB 3/10/99 - corrected the following line for count
	while(rectCnt-- > 0) */
	lclRectCnt = rectCnt;
	while(lclRectCnt-- > 0)
	{
	/* Set up the line state for this line.  */
/* BobB 2/18/99 - corrected lsSkipStat type
		lineState.lsSkipStat = (byte) vListPtr->skipStat; */
		lineState.lsSkipStat = (signed char) vListPtr->skipStat;
		rlistPtr = (rect *) ((long) vListPtr++);
		if(_mwLLSetup(rlistPtr)) continue;
	
		do{
			_mwLL();
			rlistPtr = (rect *) lclblitRec->blitList;
			ProcessDashes(rlistPtr);
/* Call the filler to draw this chunk of the line  */
			lclblitRec->blitDmap->prFill(lclblitRec);
		}while(lineState.lsMajorAxisLengthM1 >= 0);
	}

	grafPort.pnDashNdx = dashIndex;
	thePort->pnDashNdx = dashIndex;
	grafPort.pnDashCnt = (short) dashCount >> 7;
	thePort->pnDashCnt = grafPort.pnDashCnt;
	grafPort.pnFlags   = dashFlags;
	thePort->pnFlags   = dashFlags;
	return;
}

void DoubleDash(void)
{
	rect *rlistPtr;
	int saveBlitCnt;
	int saveDashIndex;
	long saveDashCount;
	int saveDashFlags;
/* BobB 4/23/99 - corrected dashed line rect count */
	int lRectCnt;

	lRectCnt = rectCnt;

	/* Remember where the blitList area  */	
	blitListPtr   = lclblitRec->blitList;
	/* store dash-filtered rects  */
	secondListPtr = blitListPtr + (MAX_RECTS/2)*sizeof(rect);
	/* can only use half area for the blit list, the other
		half is for pre-filtered rects  */
	lineState.lsMaxRects = MAX_RECTS/2;

/* Main double-dash line-drawing loop  */
/* BobB 4/23/99 - corrected dashed line rect count
	while(rectCnt-- > 0) */
	while(lRectCnt-- > 0)
	{
	/* Set up the line state for  this line  */
/* BobB 2/18/99 - corrected lsSkipStat type
		lineState.lsSkipStat = (byte) vListPtr->skipStat; */
		lineState.lsSkipStat = (signed char) vListPtr->skipStat;
		rlistPtr = (rect *) ((long) vListPtr++);
		if(_mwLLSetup(rlistPtr)) continue;

		do{
			lclblitRec->blitList = blitListPtr;
			_mwLL();
		/* go back to where we put dash-filtered rects  */
			lclblitRec->blitList = secondListPtr;
			saveBlitCnt = lclblitRec->blitCnt;
			saveDashIndex = dashIndex;
			saveDashCount = dashCount;
			saveDashFlags = dashFlags;
			rlistPtr = (rect *) blitListPtr;
			ProcessDashes(rlistPtr);
		/* Call the filler to draw the foreground dashes in this 
			chunk of the line  */
			lclblitRec->blitDmap->prFill(lclblitRec);

			lclblitRec->blitCnt = saveBlitCnt;
			dashIndex = saveDashIndex;
			dashCount = saveDashCount;
			dashFlags = saveDashFlags;
			lclblitRec->blitPat = workingBkPat;
			dashFlags ^= pnDashState;
			rlistPtr = (rect *) blitListPtr;
			ProcessDashes(rlistPtr);
		/* Call the filler to draw the background dashes in this
			chunk of the line  */
			lclblitRec->blitDmap->prFill(lclblitRec);

		/* Flip the pen back to normal  */
			dashFlags ^= pnDashState;
			lclblitRec->blitPat = workingPnPat; /* Restore foreground  */
		}while(lineState.lsMajorAxisLengthM1 >= 0);
	}
	return;
}

/* Wide dashed line handler. Assumes square pen  */
void HandleWideSq(void)
{
	int saveBlitCnt;
	int saveDashIndex;
	long saveDashCount;
	int saveDashFlags;
	rect *rlistPtr;
/* BobB 4/23/99 - corrected dashed line rect count */
	int lRectCnt;

	lRectCnt = rectCnt;

	lclblitRec->blitList = lclblitRec->blitList + (MAX_RECTS/2)*sizeof(rect);
	/* use half of buffer size since using other half for mwFC  */
	lineState.lsMaxRects = MAX_RECTS /2;
	/* Setup pen half width  */
	halfHeightUp   = grafPort.pnSize.Y >> 1; /* Round odd up and down  */
	halfHeightDown = (grafPort.pnSize.Y + 1) >> 1;
	halfWidthLeft  = grafPort.pnSize.X >> 1; /* Round odd left and right  */
	halfWidthRight = (grafPort.pnSize.X + 1) >> 1;

	/* It is possible to support capFlat as well by copying from 
	grafPort.pnCap, but since LineTo and especially mwPolyLine

⌨️ 快捷键说明

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